Johns release
authorK. Richard Pixley <rich@cygnus>
Thu, 28 Mar 1991 16:28:29 +0000 (16:28 +0000)
committerK. Richard Pixley <rich@cygnus>
Thu, 28 Mar 1991 16:28:29 +0000 (16:28 +0000)
246 files changed:
gdb/.gdbinit [new file with mode: 0644]
gdb/Convex.notes [new file with mode: 0644]
gdb/Makefile.dist [new file with mode: 0755]
gdb/Makefile.srcdir [new file with mode: 0755]
gdb/Projects [new file with mode: 0644]
gdb/TODO [new file with mode: 0644]
gdb/WHATS.NEW [new file with mode: 0755]
gdb/alldeps.mak [new file with mode: 0644]
gdb/alloca.c [new file with mode: 0644]
gdb/altos-xdep.c [new file with mode: 0644]
gdb/am29k-opcode.h [new file with mode: 0644]
gdb/am29k-pinsn.c [new file with mode: 0644]
gdb/am29k-tdep.c [new file with mode: 0644]
gdb/ansidecl.h [new file with mode: 0755]
gdb/arm-convert.s [new file with mode: 0644]
gdb/arm-pinsn.c [new file with mode: 0644]
gdb/arm-xdep.c [new file with mode: 0644]
gdb/command.c [new file with mode: 0644]
gdb/config.gdb [new file with mode: 0755]
gdb/config.status [new file with mode: 0755]
gdb/config/3b1.mh [new file with mode: 0644]
gdb/config/3b1.mt [new file with mode: 0644]
gdb/config/altos.mh [new file with mode: 0644]
gdb/config/altos.mt [new file with mode: 0644]
gdb/config/altosgas.mh [new file with mode: 0644]
gdb/config/altosgas.mt [new file with mode: 0644]
gdb/config/am29k [new file with mode: 0755]
gdb/config/arm.mh [new file with mode: 0644]
gdb/config/arm.mt [new file with mode: 0644]
gdb/config/bigmips.mh [new file with mode: 0644]
gdb/config/bigmips.mt [new file with mode: 0644]
gdb/config/convex.mh [new file with mode: 0644]
gdb/config/convex.mt [new file with mode: 0644]
gdb/config/hp300bsd.mh [new file with mode: 0644]
gdb/config/hp300bsd.mt [new file with mode: 0644]
gdb/config/hp300hpux.mh [new file with mode: 0644]
gdb/config/hp300hpux.mt [new file with mode: 0644]
gdb/config/i386v-g.mh [new file with mode: 0644]
gdb/config/i386v-g.mt [new file with mode: 0644]
gdb/config/i386v.mh [new file with mode: 0644]
gdb/config/i386v.mt [new file with mode: 0644]
gdb/config/i386v32-g.mh [new file with mode: 0644]
gdb/config/i386v32-g.mt [new file with mode: 0644]
gdb/config/i386v32.mh [new file with mode: 0644]
gdb/config/i386v32.mt [new file with mode: 0644]
gdb/config/i960.mt [new file with mode: 0644]
gdb/config/isi.mh [new file with mode: 0644]
gdb/config/isi.mt [new file with mode: 0644]
gdb/config/littlemips.mh [new file with mode: 0644]
gdb/config/littlemips.mt [new file with mode: 0644]
gdb/config/m88k.mh [new file with mode: 0644]
gdb/config/m88k.mt [new file with mode: 0644]
gdb/config/merlin.mh [new file with mode: 0644]
gdb/config/merlin.mt [new file with mode: 0644]
gdb/config/mh-vax [new file with mode: 0755]
gdb/config/news.mh [new file with mode: 0644]
gdb/config/news.mt [new file with mode: 0644]
gdb/config/news1000.mh [new file with mode: 0644]
gdb/config/news1000.mt [new file with mode: 0644]
gdb/config/nindy960.mt [new file with mode: 0644]
gdb/config/none.mh [new file with mode: 0644]
gdb/config/none.mt [new file with mode: 0644]
gdb/config/np1.mh [new file with mode: 0644]
gdb/config/np1.mt [new file with mode: 0644]
gdb/config/pn.mh [new file with mode: 0644]
gdb/config/pn.mt [new file with mode: 0644]
gdb/config/pyramid.mh [new file with mode: 0644]
gdb/config/pyramid.mt [new file with mode: 0644]
gdb/config/sun2os3.mh [new file with mode: 0644]
gdb/config/sun2os3.mt [new file with mode: 0644]
gdb/config/sun2os4.mh [new file with mode: 0644]
gdb/config/sun2os4.mt [new file with mode: 0644]
gdb/config/sun3.mh [new file with mode: 0644]
gdb/config/sun3.mt [new file with mode: 0644]
gdb/config/sun386.mh [new file with mode: 0644]
gdb/config/sun386.mt [new file with mode: 0644]
gdb/config/sun3os3.mh [new file with mode: 0644]
gdb/config/sun3os3.mt [new file with mode: 0644]
gdb/config/sun3os4.mh [new file with mode: 0644]
gdb/config/sun3os4.mt [new file with mode: 0644]
gdb/config/sun4.mh [new file with mode: 0644]
gdb/config/sun4.mt [new file with mode: 0644]
gdb/config/sun4os3.mh [new file with mode: 0644]
gdb/config/sun4os3.mt [new file with mode: 0644]
gdb/config/sun4os4.mh [new file with mode: 0644]
gdb/config/sun4os4.mt [new file with mode: 0644]
gdb/config/symmetry.mh [new file with mode: 0644]
gdb/config/symmetry.mt [new file with mode: 0644]
gdb/config/umax.mh [new file with mode: 0644]
gdb/config/umax.mt [new file with mode: 0644]
gdb/config/vax.mt [new file with mode: 0644]
gdb/config/vxworks68.mt [new file with mode: 0644]
gdb/config/vxworks960.mt [new file with mode: 0644]
gdb/convex-opcode.h [new file with mode: 0755]
gdb/convex-pinsn.c [new file with mode: 0644]
gdb/convex-tdep.c [new file with mode: 0644]
gdb/convex-xdep.c [new file with mode: 0644]
gdb/core.c [new file with mode: 0644]
gdb/coredep.c [new file with mode: 0644]
gdb/cplus-dem.c [new file with mode: 0644]
gdb/createtags [new file with mode: 0755]
gdb/depend [new file with mode: 0755]
gdb/expread.tab.c [new file with mode: 0755]
gdb/expread.y [new file with mode: 0755]
gdb/getpagesize.h [new file with mode: 0755]
gdb/gmalloc.c [new file with mode: 0755]
gdb/gmalloc.h [new file with mode: 0755]
gdb/gould-pinsn.c [new file with mode: 0644]
gdb/gould-xdep.c [new file with mode: 0644]
gdb/hp300hpux-xdep.c [new file with mode: 0755]
gdb/i386-pinsn.c [new file with mode: 0644]
gdb/i386-xdep.c [new file with mode: 0644]
gdb/i960-pinsn.c [new file with mode: 0644]
gdb/i960-tdep.c [new file with mode: 0644]
gdb/ieee-float.c [new file with mode: 0644]
gdb/ieee-float.h [new file with mode: 0644]
gdb/kdb-start.c [new file with mode: 0644]
gdb/m68k-opcode.h [new file with mode: 0755]
gdb/m68k-pinsn.c [new file with mode: 0644]
gdb/mcheck.c [new file with mode: 0755]
gdb/mips-opcode.h [new file with mode: 0755]
gdb/mips-pinsn.c [new file with mode: 0644]
gdb/mips-xdep.c [new file with mode: 0644]
gdb/munch [new file with mode: 0755]
gdb/news-xdep.c [new file with mode: 0644]
gdb/nindy-tdep.c [new file with mode: 0644]
gdb/np1-opcode.h [new file with mode: 0755]
gdb/ns32k-opcode.h [new file with mode: 0644]
gdb/ns32k-pinsn.c [new file with mode: 0644]
gdb/obstack.c [new file with mode: 0755]
gdb/obstack.h [new file with mode: 0755]
gdb/param-no-tm.h [new file with mode: 0755]
gdb/param.h [new file with mode: 0755]
gdb/pn-opcode.h [new file with mode: 0755]
gdb/pyr-opcode.h [new file with mode: 0755]
gdb/pyr-pinsn.c [new file with mode: 0644]
gdb/pyr-tdep.c [new file with mode: 0644]
gdb/pyr-xdep.c [new file with mode: 0644]
gdb/regex.c [new file with mode: 0644]
gdb/regex.h [new file with mode: 0644]
gdb/remote-eb.c [new file with mode: 0644]
gdb/remote-multi.shar [new file with mode: 0755]
gdb/remote-nindy.c [new file with mode: 0644]
gdb/remote-vx.c [new file with mode: 0644]
gdb/saber.suppress [new file with mode: 0644]
gdb/signals.h [new file with mode: 0644]
gdb/signame.c [new file with mode: 0755]
gdb/signame.h [new file with mode: 0755]
gdb/sparc-opcode.h [new file with mode: 0755]
gdb/sparc-pinsn.c [new file with mode: 0644]
gdb/sparc-xdep.c [new file with mode: 0644]
gdb/stab.def [new file with mode: 0755]
gdb/standalone.c [new file with mode: 0644]
gdb/stddef.h [new file with mode: 0755]
gdb/stdlib.h [new file with mode: 0755]
gdb/stuff.c [new file with mode: 0644]
gdb/sun3-xdep.c [new file with mode: 0644]
gdb/sun386-xdep.c [new file with mode: 0644]
gdb/symmetry-tdep.c [new file with mode: 0755]
gdb/symmetry-xdep.c [new file with mode: 0755]
gdb/tdesc.c [new file with mode: 0755]
gdb/tdesc.h [new file with mode: 0755]
gdb/tm-29k.h [new file with mode: 0644]
gdb/tm-3b1.h [new file with mode: 0644]
gdb/tm-68k.h [new file with mode: 0644]
gdb/tm-altos.h [new file with mode: 0644]
gdb/tm-altosgas.h [new file with mode: 0644]
gdb/tm-arm.h [new file with mode: 0644]
gdb/tm-bigmips.h [new file with mode: 0644]
gdb/tm-convex.h [new file with mode: 0644]
gdb/tm-hp300bsd.h [new file with mode: 0644]
gdb/tm-hp300hpux.h [new file with mode: 0644]
gdb/tm-i386v-g.h [new file with mode: 0644]
gdb/tm-i386v.h [new file with mode: 0644]
gdb/tm-i960.h [new file with mode: 0644]
gdb/tm-isi.h [new file with mode: 0644]
gdb/tm-m88k.h [new file with mode: 0644]
gdb/tm-merlin.h [new file with mode: 0644]
gdb/tm-mips.h [new file with mode: 0644]
gdb/tm-news.h [new file with mode: 0644]
gdb/tm-nindy960.h [new file with mode: 0644]
gdb/tm-np1.h [new file with mode: 0644]
gdb/tm-pn.h [new file with mode: 0644]
gdb/tm-pyr.h [new file with mode: 0644]
gdb/tm-sparc.h [new file with mode: 0644]
gdb/tm-sun2.h [new file with mode: 0644]
gdb/tm-sun2os4.h [new file with mode: 0644]
gdb/tm-sun3.h [new file with mode: 0644]
gdb/tm-sun386.h [new file with mode: 0644]
gdb/tm-sun3os4.h [new file with mode: 0644]
gdb/tm-sun4os4.h [new file with mode: 0644]
gdb/tm-sunos.h [new file with mode: 0644]
gdb/tm-symmetry.h [new file with mode: 0644]
gdb/tm-umax.h [new file with mode: 0644]
gdb/tm-vax.h [new file with mode: 0644]
gdb/tm-vxworks68.h [new file with mode: 0755]
gdb/tm-vxworks960.h [new file with mode: 0755]
gdb/umax-xdep.c [new file with mode: 0644]
gdb/values.c [new file with mode: 0644]
gdb/vax-opcode.h [new file with mode: 0755]
gdb/vax-pinsn.c [new file with mode: 0644]
gdb/vx-share/dbgRpcLib.h [new file with mode: 0644]
gdb/vx-share/ptrace.h [new file with mode: 0644]
gdb/vx-share/reg.h [new file with mode: 0644]
gdb/vx-share/vxTypes.h [new file with mode: 0644]
gdb/vx-share/vxWorks.h [new file with mode: 0644]
gdb/vx-share/wait.h [new file with mode: 0644]
gdb/vx-share/xdr_ld.c [new file with mode: 0644]
gdb/vx-share/xdr_ld.h [new file with mode: 0644]
gdb/vx-share/xdr_ptrace.c [new file with mode: 0644]
gdb/vx-share/xdr_ptrace.h [new file with mode: 0644]
gdb/vx-share/xdr_rdb.c [new file with mode: 0644]
gdb/vx-share/xdr_rdb.h [new file with mode: 0644]
gdb/vx-share/xdr_regs.c [new file with mode: 0644]
gdb/vx-share/xdr_regs.h [new file with mode: 0644]
gdb/xm-3b1.h [new file with mode: 0644]
gdb/xm-altos.h [new file with mode: 0644]
gdb/xm-arm.h [new file with mode: 0644]
gdb/xm-bigmips.h [new file with mode: 0644]
gdb/xm-convex.h [new file with mode: 0644]
gdb/xm-hp300bsd.h [new file with mode: 0644]
gdb/xm-hp300hpux.h [new file with mode: 0644]
gdb/xm-i386v.h [new file with mode: 0644]
gdb/xm-i386v32.h [new file with mode: 0644]
gdb/xm-isi.h [new file with mode: 0644]
gdb/xm-m88k.h [new file with mode: 0644]
gdb/xm-merlin.h [new file with mode: 0644]
gdb/xm-mips.h [new file with mode: 0644]
gdb/xm-news.h [new file with mode: 0644]
gdb/xm-news1000.h [new file with mode: 0644]
gdb/xm-np1.h [new file with mode: 0644]
gdb/xm-pn.h [new file with mode: 0644]
gdb/xm-pyr.h [new file with mode: 0644]
gdb/xm-sparc.h [new file with mode: 0644]
gdb/xm-sun2.h [new file with mode: 0644]
gdb/xm-sun3.h [new file with mode: 0644]
gdb/xm-sun386.h [new file with mode: 0644]
gdb/xm-sun3os4.h [new file with mode: 0644]
gdb/xm-sun4os4.h [new file with mode: 0644]
gdb/xm-symmetry.h [new file with mode: 0644]
gdb/xm-umax.h [new file with mode: 0644]
gdb/xm-vax.h [new file with mode: 0644]
include/a.out.hp.h [new file with mode: 0755]
readline/ChangeLog [new file with mode: 0644]
readline/history.texinfo [new file with mode: 0755]
readline/readline.texinfo [new file with mode: 0755]

diff --git a/gdb/.gdbinit b/gdb/.gdbinit
new file mode 100644 (file)
index 0000000..bcacd5d
--- /dev/null
@@ -0,0 +1,15 @@
+echo Setting up the environment for debugging gdb.\n
+
+b fatal
+
+b info_command
+commands
+       silent
+       return
+end
+
+define rr
+    run
+end
+
+set prompt (top-gdb)
diff --git a/gdb/Convex.notes b/gdb/Convex.notes
new file mode 100644 (file)
index 0000000..28d336b
--- /dev/null
@@ -0,0 +1,163 @@
+
+@node Convex,,, Top
+@appendix Convex-specific info
+@cindex Convex notes
+
+Scalar registers are 64 bits long, which is a pain since
+left half of an S register frequently contains noise.
+Therefore there are two ways to obtain the value of an S register.
+
+@table @kbd
+@item $s0
+returns the low half of the register as an int
+
+@item $S0
+returns the whole register as a long long
+@end table
+
+You can print the value in floating point by using @samp{p/f $s0} or @samp{p/f $S0}
+to print a single or double precision value.
+
+@cindex vector registers
+Vector registers are handled similarly, with @samp{$V0} denoting the whole
+64-bit register and @kbd{$v0} denoting the 32-bit low half; @samp{p/f $v0}
+or @samp{p/f $V0} can be used to examine the register in floating point.
+The length of the vector registers is taken from @samp{$vl}.  
+
+Individual elements of a vector register are denoted in the obvious way;
+@samp{print $v3[9]} prints the tenth element of register @kbd{v3}, and
+@samp{set $v3[9] = 1234} alters it.
+
+@kbd{$vl} and @kbd{$vs} are int, and @kbd{$vm} is an int vector.
+Elements of @kbd{$vm} can't be assigned to.
+
+@cindex communication registers
+@kindex info comm-registers
+Communication registers have names @kbd{$C0 .. $C63}, with @kbd{$c0 .. $c63}
+denoting the low-order halves.  @samp{info comm-registers} will print them
+all out, and tell which are locked.  (A communication register is
+locked when a value is sent to it, and unlocked when the value is
+received.)  Communication registers are, of course, global to all
+threads, so it does not matter what the currently selected thread is.
+@samp{info comm-reg @var{name}} prints just that one communication
+register; @samp{name} may also be a communication register number
+@samp{nn} or @samp{0xnn}.
+@samp{info comm-reg @var{address}} prints the contents of the resource
+structure at that address.
+
+@kindex info psw
+The command @samp{info psw} prints the processor status word @kbd{$ps}
+bit by bit.
+
+@kindex set base
+GDB normally prints all integers in base 10, but the leading
+@kbd{0x80000000} of pointers is intolerable in decimal, so the default
+output radix has been changed to try to print addresses appropriately.
+The @samp{set base} command can be used to change this.
+
+@table @code
+@item set base 10
+Integer values always print in decimal.
+
+@item set base 16
+Integer values always print in hex.
+
+@item set base
+Go back to the initial state, which prints integer values in hex if they
+look like pointers (specifically, if they start with 0x8 or 0xf in the
+stack), otherwise in decimal.
+@end table
+
+@kindex set pipeline
+When an exception such as a bus error or overflow happens, usually the PC
+is several instructions ahead by the time the exception is detected.
+The @samp{set pipe} command will disable this.
+
+@table @code
+@item set pipeline off
+Forces serial execution of instructions; no vector chaining and no 
+scalar instruction overlap.  With this, exceptions are detected with 
+the PC pointing to the instruction after the one in error.
+
+@item set pipeline on
+Returns to normal, fast, execution.  This is the default.
+@end table
+
+@cindex parallel
+In a parallel program, multiple threads may be executing, each
+with its own registers, stack, and local memory.  When one of them
+hits a breakpoint, that thread is selected.  Other threads do
+not run while the thread is in the breakpoint.
+
+@kindex 1cont
+The selected thread can be single-stepped, given signals, and so
+on.  Any other threads remain stopped.  When a @samp{cont} command is given,
+all threads are resumed.  To resume just the selected thread, use
+the command @samp{1cont}.
+
+@kindex thread
+The @samp{thread} command will show the active threads and the
+instruction they are about to execute.  The selected thread is marked
+with an asterisk.  The command @samp{thread @var{n}} will select thread @var{n},
+shifting the debugger's attention to it for single-stepping,
+registers, local memory, and so on.
+
+@kindex info threads
+The @samp{info threads} command will show what threads, if any, have
+invisibly hit breakpoints or signals and are waiting to be noticed.
+
+@kindex set parallel
+The @samp{set parallel} command controls how many threads can be active.
+
+@table @code
+@item set parallel off
+One thread.  Requests by the program that other threads join in
+(spawn and pfork instructions) do not cause other threads to start up.
+This does the same thing as the @samp{limit concurrency 1} command.
+
+@item set parallel fixed
+All CPUs are assigned to your program whenever it runs.  When it
+executes a pfork or spawn instruction, it begins parallel execution
+immediately.  This does the same thing as the @samp{mpa -f} command.
+
+@item set parallel on
+One or more threads.  Spawn and pfork cause CPUs to join in when and if
+they are free.  This is the default.  It is very good for system
+throughput, but not very good for finding bugs in parallel code.  If you
+suspect a bug in parallel code, you probably want @samp{set parallel fixed.}
+@end table
+
+@subsection Limitations
+
+WARNING: Convex GDB evaluates expressions in long long, because S
+registers are 64 bits long.  However, GDB expression semantics are not
+exactly C semantics.  This is a bug, strictly speaking, but it's not one I
+know how to fix.  If @samp{x} is a program variable of type int, then it
+is also type int to GDB, but @samp{x + 1} is long long, as is @samp{x + y}
+or any other expression requiring computation.  So is the expression
+@samp{1}, or any other constant.  You only really have to watch out for
+calls.  The innocuous expression @samp{list_node (0x80001234)} has an
+argument of type long long.  You must explicitly cast it to int.
+
+It is not possible to continue after an uncaught fatal signal by using
+@samp{signal 0}, @samp{return}, @samp{jump}, or anything else.  The difficulty is with
+Unix, not GDB.
+
+I have made no big effort to make such things as single-stepping a
+@kbd{join} instruction do something reasonable.  If the program seems to
+hang when doing this, type @kbd{ctrl-c} and @samp{cont}, or use
+@samp{thread} to shift to a live thread.  Single-stepping a @kbd{spawn}
+instruction apparently causes new threads to be born with their T bit set;
+this is not handled gracefully.  When a thread has hit a breakpoint, other
+threads may have invisibly hit the breakpoint in the background; if you
+clear the breakpoint gdb will be surprised when threads seem to continue
+to stop at it.  All of these situations produce spurious signal 5 traps;
+if this happens, just type @samp{cont}.  If it becomes a nuisance, use
+@samp{handle 5 nostop}.  (It will ask if you are sure.  You are.)
+
+There is no way in GDB to store a float in a register, as with
+@kbd{set $s0 = 3.1416}.  The identifier @kbd{$s0} denotes an integer,
+and like any C expression which assigns to an integer variable, the
+right-hand side is casted to type int.  If you should need to do
+something like this, you can assign the value to @kbd{@{float@} ($sp-4)}
+and then do @kbd{set $s0 = $sp[-4]}.  Same deal with @kbd{set $v0[69] = 6.9}.
diff --git a/gdb/Makefile.dist b/gdb/Makefile.dist
new file mode 100755 (executable)
index 0000000..7b4e3ce
--- /dev/null
@@ -0,0 +1,506 @@
+##Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Place to install binaries. 
+bindir=/usr/local/bin
+
+# System V: If you compile gdb with a compiler which uses the coff
+# encapsulation feature (this is a function of the compiler used, NOT
+# of the m-?.h file selected by config.gdb), you must make sure that
+# the GNU nm is the one that is used by munch.
+
+# If you are compiling with GCC, make sure that either 1) You use the
+# -traditional flag, or 2) You have the fixed include files where GCC
+# can reach them.  Otherwise the ioctl calls in inflow.c and readline.c 
+# will be incorrectly compiled.  The "fixincludes" script in the gcc
+# distribution will fix your include files up.
+#CC=cc
+#CC=gcc -traditional
+GCC=gcc
+
+VPATH=$(srcdir)
+
+# It is also possible that you will need to add -I/usr/include/sys to the
+# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which 
+# is where it should be according to Posix).
+
+YACC=bison -y
+# YACC=yacc
+SHELL=/bin/sh
+MAKE=make
+
+# Set this up with gcc if you have gnu ld and the loader will print out
+# line numbers for undefinded refs.
+#CC-LD=gcc -static
+CC-LD=${CC}
+
+# define this to be "gmalloc.o" if you want to use the gnu malloc routine
+# (useful for debugging memory allocation problems in gdb).  To use your
+# system malloc, uncomment the following two lines.
+#GNU_MALLOC =
+#MALLOC_CFLAGS = -DNO_MALLOC_CHECK
+GNU_MALLOC = gmalloc.o mcheck.o
+MALLOC_CFLAGS =
+
+# Where is the "include" directory?  Traditionally ../include or ./include
+INCLUDE_DIR =  ${srcdir}/../include
+INCLUDE_DEP = $$(INCLUDE_DIR)
+
+# Where is the BFD library?  Traditionally ../bfd or ./bfd
+BFD_DIR =  ${srcdir}/../bfd
+BFD_DEP = $$(BFD_DIR)
+
+# All the includes used for CFLAGS and for lint.
+# -I. for config files.
+# -I${srcdir} for <obstack.h>, possibly regex.h also.
+INCLUDE_CFLAGS = -I. -I${srcdir} -I$(INCLUDE_DIR) -I${srcdir}/vx-share
+
+# {X,T}M_CFLAGS, if defined, has system-dependent CFLAGS.
+# CFLAGS for both GDB and readline.
+GLOBAL_CFLAGS = -g ${TM_CFLAGS} ${XM_CFLAGS}
+#PROFILE_CFLAGS = -pg
+
+CFLAGS = ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} ${MALLOC_CFLAGS} ${INCLUDE_CFLAGS}
+# None of the things in CFLAGS will do any harm, and on some systems
+#  (e.g. SunOS4) it is important to use the M_CFLAGS.
+LDFLAGS = $(CFLAGS)
+
+# define this to be "obstack.o" if you don't have the obstack library installed
+# so that the dependencies work right.  
+OBSTACK = obstack.o
+
+# Requires GNU getopt_long features.
+GETOPT = getopt.o getopt1.o
+# Where is the getopt directory?  Traditionally ../getopt or ./getopt
+GETOPT_DIR =  ${srcdir}/../getopt
+GETOPT_DEP = $$(GETOPT_DIR)
+
+# Flags that describe where you can find the termcap library.
+# You may need to make other arrangements for USG.
+TERMCAP = -ltermcap
+
+# You must define REGEX and REGEX1 on USG machines.
+# If your sysyem is missing alloca(), or, more likely, it's there but
+# it doesn't work, define ALLOCA & ALLOCA1
+
+# {X,T}M_CLIBS, if defined, has system-dependent libs
+# For example, -lPW for System V to get alloca().
+# FIXME STOPGAP FOR BFD LIBRARY: BFD stuff
+CLIBS = ${TERMCAP} $(XM_CLIBS) ${TM_CLIBS} ${BFD_DIR}/libbfd.a
+CDEPS = ${XM_CDEPS} ${TM_CDEPS} ${BFD_DIR}/libbfd.a
+
+ADD_FILES = ${OBSTACK} ${REGEX} ${ALLOCA} ${GNU_MALLOC} ${GETOPT}
+ADD_DEPS = ${OBSTACK} ${REGEX1} ${ALLOCA1} ${GNU_MALLOC} ${GETOPT}
+
+VERSION = 3.94.2
+DIST=gdb-$(VERSION)
+
+LINT=/usr/5bin/lint
+LINTFLAGS=
+
+# Source files in the main directory.
+# Files which are included via a tconfig/* or xconfig/* file 
+# should *not* be specified here; they're in "ALLDEPFILES".
+SFILES_MAINDIR = \
+        blockframe.c breakpoint.c command.c core.c \
+        environ.c eval.c expprint.c findvar.c infcmd.c inflow.c infrun.c \
+        main.c printcmd.c \
+        remote.c source.c stack.c symmisc.c symtab.c symfile.c \
+        utils.c valarith.c valops.c valprint.c values.c expread.y \
+        signame.c cplus-dem.c mem-break.c target.c inftarg.c \
+        dbxread.c coffread.c \
+        ieee-float.c 
+
+# Source files in subdirectories (which will be handled separately by
+#  'make gdb.tar.Z').
+# Files which are included via a tconfig/* or xconfig/* file 
+# should *not* be specified here; they're in "ALLDEPFILES".
+SFILES_SUBDIR = \
+        ${srcdir}/vx-share/dbgRpcLib.h \
+        ${srcdir}/vx-share/ptrace.h \
+        ${srcdir}/vx-share/reg.h \
+        ${srcdir}/vx-share/vxTypes.h \
+        ${srcdir}/vx-share/vxWorks.h \
+        ${srcdir}/vx-share/wait.h \
+        ${srcdir}/vx-share/xdr_ld.h \
+        ${srcdir}/vx-share/xdr_ptrace.h \
+        ${srcdir}/vx-share/xdr_rdb.h \
+        ${srcdir}/vx-share/xdr_regs.h \
+        ${srcdir}/nindy-share/Makefile \
+        ${srcdir}/nindy-share/VERSION \
+        ${srcdir}/nindy-share/b.out.h \
+        ${srcdir}/nindy-share/block_io.h \
+        ${srcdir}/nindy-share/coff.h \
+        ${srcdir}/nindy-share/demux.h \
+        ${srcdir}/nindy-share/env.h \
+        ${srcdir}/nindy-share/stop.h \
+        ${srcdir}/nindy-share/ttycntl.h
+
+# All source files that go into linking GDB, except config-specified files.
+SFILES = $(SFILES_MAINDIR) $(SFILES_SUBDIR)
+
+# All source files that lint should look at
+LINTFILES = $(SFILES) expread.tab.c init.c
+
+# Any additional files specified on these lines should also be added to
+# the OTHERS = definition below, so they go in the tar files.
+SFILES_STAND = $(SFILES) standalone.c
+SFILES_KGDB  = $(SFILES) stuff.c kdb-start.c
+
+# Header files that are not named in tconfig/* or xconfig/* go here.
+HFILES=        breakpoint.h command.h defs.h environ.h \
+       expression.h frame.h gdbcmd.h gdbcore.h \
+       getpagesize.h ieee-float.h inferior.h param-no-tm.h param.h \
+       signals.h signame.h symfile.h symtab.h \
+       target.h tdesc.h terminal.h tm-68k.h tm-i960.h tm-sunos.h \
+       value.h
+
+OPCODES = pn-opcode.h np1-opcode.h sparc-opcode.h vax-opcode.h m68k-opcode.h \
+         ns32k-opcode.h convex-opcode.h pyr-opcode.h mips-opcode.h \
+         am29k-opcode.h
+
+REMOTE_EXAMPLES = remote-sa.m68k.shar remote-multi.shar
+
+MALLOCSRC = gmalloc.c mcheck.c ansidecl.h stdlib.h gmalloc.h stddef.h
+GETOPTSRC = $(GETOPT_DIR)/getopt.c $(GETOPT_DIR)/getopt1.c
+
+POSSLIBS_MAINDIR = obstack.h obstack.c regex.c regex.h alloca.c \
+       $(MALLOCSRC)
+POSSLIBS = $(POSSLIBS_MAINDIR) $(GETOPTSRC)
+
+TESTS = testbpt.c testfun.c testrec.c testreg.c testregs.c
+
+# tdesc-lib cannot be named simply tdesc, because if if it were GNU make
+# would try to make it from tdesc.c.
+# tdesc-lib removed from the list due to Motorola copyrights...gnu@cygnus.com
+OTHERS = Makefile.dist depend alldeps.mak Makefile.srcdir \
+        createtags munch config.gdb config.status \
+        ChangeLog ChangeLog-3.x \
+        README TODO TAGS WHATS.NEW \
+        gdb.texinfo gdb-int.texinfo gdbrc.tex threecol.tex \
+       .gdbinit COPYING expread.tab.c stab.def \
+        copying.c Projects Convex.notes copying.awk \
+        saber.suppress standalone.c stuff.c kdb-start.c \
+        hp-include # tests
+
+DEPFILES= ${TDEPFILES} ${XDEPFILES}
+
+SOURCES=$(SFILES) $(ALLDEPFILES)
+TAGFILES = $(SOURCES) ${HFILES} ${OPCODES} ${ALLPARAM} ${POSSLIBS} 
+TAGFILES_MAINDIR = $(SFILES_MAINDIR) $(ALLDEPFILES_MAINDIR) \
+             ${HFILES} ${OPCODES} ${ALLPARAM} ${POSSLIBS_MAINDIR} 
+TARFILES = ${TAGFILES_MAINDIR} ${OTHERS} ${REMOTE_EXAMPLES}
+
+OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \
+    values.o eval.o valops.o valarith.o valprint.o printcmd.o \
+    symtab.o symfile.o symmisc.o infcmd.o infrun.o remote.o \
+    command.o utils.o expread.o expprint.o environ.o version.o \
+    copying.o $(DEPFILES) signame.o cplus-dem.o mem-break.o target.o \
+    inftarg.o ieee-float.o \
+    dbxread.o coffread.o # mipsread.o
+
+RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES)
+
+TSOBS = core.o inflow.o
+
+NTSOBS = standalone.o
+
+TSSTART = /lib/crt0.o
+
+NTSSTART = kdb-start.o
+
+RL_LIB = readline/libreadline.a
+RL_LIB_DEP = $(RL_LIB)
+
+# Prevent Sun make from putting in the machine type.  Setting
+# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1.
+.c.o:
+       ${CC} -c ${CFLAGS} $<
+
+all: gdb
+
+install: gdb
+       cp gdb $(bindir)/gdb.new
+       mv $(bindir)/gdb.new $(bindir)/gdb
+       $(M_INSTALL)
+
+init.c: $(srcdir)/munch $(MUNCH_DEFINE) $(OBS) $(TSOBS)
+       $(srcdir)/munch ${MUNCH_DEFINE} $(OBS) $(TSOBS) > init.c
+
+gdb: $(OBS) $(TSOBS) ${ADD_DEPS} ${RL_LIB_DEP} ${CDEPS} init.o
+       ${CC-LD} $(LDFLAGS) -o gdb init.o $(OBS) $(TSOBS) $(ADD_FILES) \
+       ${RL_LIB} $(CLIBS)
+
+saber_gdb: $(SFILES) $(GETOPTSRC) $(DEPFILES) copying.c obstack.c version.c
+       #setopt load_flags $(CFLAGS) -I$(BFD_DIR)
+       #load ./init.c $(SFILES)
+       #unload ${srcdir}/expread.y
+       #load ${srcdir}/expread.tab.c readline/libreadline.a
+       #load copying.c version.c
+       #load obstack.c $(GETOPTSRC)
+       #load `echo " "$(DEPFILES) | sed -e 's/\.o/.c/g' -e 's, , ../,g'`
+       #load ${BFD_DIR}/libbfd.a -ltermcap 
+       ##void mcheck(a) void (*a)(); { }
+
+
+
+# This is useful when debugging GDB, because some Unix's don't let you run GDB
+# on itself without copying the executable.  So "make gdb1" will make
+# gdb and put a copy in gdb1, and you can run it with "gdb gdb1".
+# Removing gdb1 before the copy is the right thing if gdb1 is open
+# in another process.
+gdb1: gdb
+       rm -f gdb1
+       cp gdb gdb1
+
+# This is a remote stub which runs under unix and starts up an
+# inferior process.  This is at least useful for debugging GDB's
+# remote support.
+rapp: $(RAPP_OBS)
+       rm -f rapp_init.c
+       ${srcdir}/munch ${RAPP_OBS} > rapp_init.c
+       ${CC-LD} $(LDFLAGS) -o $@ rapp_init.c $(RAPP_OBS)
+       
+Makefiles= Makefile.srcdir $(M_MAKEFILE) \
+       ${srcdir}/alldeps.mak ${srcdir}/Makefile.dist
+
+MAKE_MAKEFILE= echo "M_MAKEFILE=$(M_MAKEFILE)" | \
+       cat - ${Makefiles} ${srcdir}/depend >Makefile
+
+Makefile: $(Makefiles)
+       $(MAKE_MAKEFILE)
+
+alldeps.mak: ${srcdir}/tconfig ${srcdir}/xconfig
+       rm -f alldeps.mak alldeps.tmp allparam.tmp allconfig.tmp
+       for i in `ls -d ${srcdir}/tconfig/*[0-9A-Za-z] \
+          ${srcdir}/xconfig/*[0-9A-Za-z] | grep -v RCS` ; do \
+         echo $$i >>allconfig.tmp; \
+         awk <$$i ' \
+           $$1 == "TDEPFILES=" || $$1 == "XDEPFILES=" { \
+             for (i = 2; i <= NF; i++) \
+               print $$i >> "alldeps.tmp" ; \
+            } \
+           $$1 == "TM_FILE=" || $$1 == "XM_FILE=" { \
+             print $$2 >> "allparam.tmp" }' ; \
+       done
+       sort <alldeps.tmp | uniq | \
+         sed -e 's/arm-convert.o/arm-convert.s/' \
+             -e 's!^Onindy.o!nindy-share/Onindy.c!' \
+             -e 's!^nindy.o!nindy-share/nindy.c!' \
+             -e 's!ttybreak.o!nindy-share/ttybreak.c!' \
+             -e 's!ttyflush.o!nindy-share/ttyflush.c!' \
+             -e 's!xdr_ld.o!vx-share/xdr_ld.c!' \
+             -e 's!xdr_ptrace.o!vx-share/xdr_ptrace.c!' \
+             -e 's!xdr_rdb.o!vx-share/xdr_rdb.c!' \
+             -e 's!xdr_regs.o!vx-share/xdr_regs.c!' \
+             -e 's/\.o/.c/' \
+           >alldeps2.tmp
+       echo 'ALLDEPFILES = $$(ALLDEPFILES_MAINDIR) $$(ALLDEPFILES_SUBDIR)' \
+           >>alldeps.mak;
+       grep -v / alldeps2.tmp | \
+         awk 'BEGIN {printf "ALLDEPFILES_MAINDIR="} \
+           NR == 0 {printf $$0;} \
+           NR != 0 {printf "\\\n" $$0} \
+           END {printf "\n\n"}' >>alldeps.mak;
+       grep / alldeps2.tmp | \
+         awk 'BEGIN {printf "ALLDEPFILES_SUBDIR="} \
+           NR == 0 {printf $$0;} \
+           NR != 0 {printf "\\\n" $$0} \
+           END {printf "\n\n"}' >>alldeps.mak;
+       sort <allparam.tmp | uniq | awk 'BEGIN {printf "ALLPARAM="} \
+           NR == 0 {printf $$0;} \
+           NR != 0 {printf "\\\n" $$0} \
+           END {printf "\n\n"}' >>alldeps.mak;
+       sort <allconfig.tmp | uniq | awk 'BEGIN {printf "ALLCONFIG="} \
+           NR == 0 {printf $$0;} \
+           NR != 0 {printf "\\\n" $$0} \
+           END {printf "\n\n"}' >>alldeps.mak;
+       rm -f alldeps.tmp alldeps2.tmp allparam.tmp allconfig.tmp
+
+# The sed script makes everything which depends on {x,t}m.h depend on
+# config.status as well, in case someone reconfigures gdb out from
+# under an already compiled gdb.
+depend: $(SOURCES) Makefile.dist
+       @echo Ignore errors about non-existent system-supplied include files
+       @echo for systems other than the one you are using.
+       @echo "If xm.h and tm.h don't exist, the error messages saying so"
+       @echo can safely be ignored.
+       @echo Also ignore parse errors in valops.c, and any errors in
+       @echo arm-convert.s.
+       -$(GCC) -MM $(CFLAGS) -I$(BFD_DIR) \
+           `ls $(SOURCES) | sort -u` >depend.tmp
+       <depend.tmp sed -e 's/ [xt]m.h/& config.status/g'  \
+         -e 's; vx-share/; $${srcdir}/vx-share/;g'  \
+         -e 's; nindy-share/; $${srcdir}/nindy-share/;g'  \
+         -e 's; $(INCLUDE_DIR)/; $(INCLUDE_DEP)/;g'  \
+         -e 's; [a-z0-9./]*bfd/; $(BFD_DEP)/;g'  \
+         -e 's; [a-z0-9./]*getopt/; $(GETOPT_DEP)/;g'  \
+         -e 's; \./; $${srcdir}/;g'  \
+         >depend
+       $(MAKE_MAKEFILE)
+       rm depend.tmp
+
+config.status:
+       @echo "You must configure gdb.  Look at the README file for details."
+       @false
+
+# These are not generated by "make depend" because they only are there
+# for some machines.
+tm-isi.h tm-sun3.h tm-news.h tm-hp300bsd.h tm-altos.h : tm-68k.h
+tm-hp300hpux.h tm-sun2.h tm-3b1.h : tm-68k.h
+xm-news1000.h : xm-news.h
+xm-i386-sv32.h : xm-i386.h
+tm-i386gas.h: tm-i386.h
+xm-sun4os4.h : xm-sparc.h
+tm-sun4os4.h : tm-sparc.h
+
+kdb : $(NTSSTART) $(OBS) $(NTSOBS) ${ADD_DEPS} ${RL_LIB_DEP}
+       rm -f init.c
+       $(srcdir)/munch ${MUNCH_DEFINE} $(OBS) $(NTSOBS) > init.c
+       $(CC) $(LDFLAGS) -c init.c $(CLIBS) 
+       ld -o kdb $(NTSSTART) $(OBS) $(NTSOBS) init.o $(ADD_FILES) \
+       ${RL_LIB} -lc $(CLIBS)
+
+# Put the proper machine-specific files first.
+# createtags will edit the .o in DEPFILES into .c
+TAGS: ${TAGFILES}
+       $(srcdir)/createtags $(TM_FILE) ${XM_FILE} $(DEPFILES) ${TAGFILES}
+tags: TAGS
+
+# FIXME: Get alldeps.mak up to date, config.gdb none, THEN make gdb.tar.Z!
+gdb.tar.Z: ${TARFILES}
+       rm -f gdb.tar; rm -rf $(DIST)
+       cd readline ; make readline.tar
+       mkdir $(DIST)
+       cd $(DIST) ; for i in ${TARFILES} ; do ln -s ../$$i . ; done
+       mkdir $(DIST)/readline
+       cd $(DIST)/readline ; tar xf ../../readline/readline.tar
+       mkdir $(DIST)/xconfig ${DIST}/tconfig
+       cd $(DIST)/tconfig ; \
+         for i in $(ALLCONFIG) ; do ln -s ../../$$i ../$$i ; done
+       mkdir $(DIST)/vx-share $(DIST)/nindy-share
+       cd $(DIST)/tconfig ; \
+         for i in $(SFILES_SUBDIR) $(ALLDEPFILES_SUBDIR); \
+           do ln -s ../../$$i ../$$i ; done
+       tar chf - $(DIST) | compress >gdb.tar.Z
+       rm -rf $(DIST)
+
+clean:
+       rm -f ${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES}
+       rm -f init.c init.o version.c
+       rm -f gdb core gdb.tar gdb.tar.Z make.log
+       rm -f gdb[0-9]
+       cd readline ; make clean
+
+distclean: clean expread.tab.c TAGS
+       rm -f tm.h xm.h config.status
+       rm -f y.output yacc.acts yacc.tmp
+       rm -f ${TESTS} Makefile
+
+realclean: clean
+       rm -f expread.tab.c TAGS
+       rm -f tm.h xm.h config.status
+       rm -f Makefile
+
+gdb.dvi : gdb.texinfo
+       tex gdb.texinfo
+       texindex gdb.??
+       tex gdb.texinfo
+
+# Make copying.c from COPYING
+copying.c : COPYING copying.awk
+       awk -f copying.awk < COPYING > copying.c
+
+version.c : Makefile.dist
+       echo 'char *version = "$(VERSION)";' >version.c
+
+${srcdir}/expread.tab.c : $(srcdir)/expread.y
+       @echo 'Expect 4 shift/reduce conflict.'
+       ${YACC} $(srcdir)/expread.y
+       mv y.tab.c ${srcdir}/expread.tab.c
+
+expread.o : ${srcdir}/expread.tab.c defs.h param.h symtab.h \
+            frame.h expression.h
+       $(CC) -c ${CFLAGS} `echo ${srcdir}/expread.tab.c | sed 's,^\./,,'`
+       mv expread.tab.o expread.o
+
+# dbxread, coffread, mipsread have dependencies on BFD header files.
+dbxread.o: ${srcdir}/dbxread.c
+       ${CC} -c ${CFLAGS} -I$(BFD_DIR) ${srcdir}/dbxread.c
+
+coffread.o: ${srcdir}/coffread.c
+       ${CC} -c ${CFLAGS} -I$(BFD_DIR) ${srcdir}/coffread.c
+
+mipsread.o: ${srcdir}/mipsread.c
+       ${CC} -c ${CFLAGS} -I$(BFD_DIR) ${srcdir}/mipsread.c
+
+# Drag in the files that are in another directory.
+
+getopt1.o: $(GETOPT_DIR)/getopt1.c
+       ${CC} -c ${CFLAGS} $(GETOPT_DIR)/getopt1.c
+
+getopt.o: $(GETOPT_DIR)/getopt.c
+       ${CC} -c ${CFLAGS} $(GETOPT_DIR)/getopt.c
+
+xdr_ld.o: ${srcdir}/vx-share/xdr_ld.c
+       ${CC} -c ${CFLAGS} ${srcdir}/vx-share/xdr_ld.c
+
+xdr_ptrace.o: ${srcdir}/vx-share/xdr_ptrace.c
+       ${CC} -c ${CFLAGS} ${srcdir}/vx-share/xdr_ptrace.c
+
+xdr_rdb.o: ${srcdir}/vx-share/xdr_rdb.c
+       ${CC} -c ${CFLAGS} ${srcdir}/vx-share/xdr_rdb.c
+
+xdr_regs.o: ${srcdir}/vx-share/xdr_regs.c
+       ${CC} -c ${CFLAGS} ${srcdir}/vx-share/xdr_regs.c
+
+nindy.o: ${srcdir}/nindy-share/nindy.c
+       ${CC} -c ${CFLAGS} ${srcdir}/nindy-share/nindy.c
+
+Onindy.o: ${srcdir}/nindy-share/Onindy.c
+       ${CC} -c ${CFLAGS} ${srcdir}/nindy-share/Onindy.c
+
+ttybreak.o: ${srcdir}/nindy-share/ttybreak.c
+       ${CC} -c ${CFLAGS} ${srcdir}/nindy-share/ttybreak.c
+
+ttyflush.o: ${srcdir}/nindy-share/ttyflush.c
+       ${CC} -c ${CFLAGS} ${srcdir}/nindy-share/ttyflush.c
+
+tdesc-lib/libdc.o : force_update
+       cd tdesc-lib ; ${MAKE} "SYSV_DEFINE=${SYSV_DEFINE}"
+
+# In LOCAL_INCLUDES, -I${srcdir} is right if srcdir is an absolute path,
+# and -I../${srcdir} is right if it is relative (e.g. ".."), so search both.
+readline/libreadline.a : force_update
+       cd readline ; ${MAKE} "SYSV=${SYSV_DEFINE}"\
+               "VPATH=${srcdir}/readline:../${srcdir}/readline"\
+               "LOCAL_INCLUDES=-I../ -I${srcdir}/ -I../${srcdir}/"\
+               "DEBUG_FLAGS=${GLOBAL_CFLAGS}" "CC=${CC}" libreadline.a
+
+lint: $(LINTFILES)
+       $(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES)
+
+gdb.cxref: $(SFILES)
+       cxref -I. $(SFILES) >gdb.cxref
+
+force_update :
+
+# When used with GDB, the demangler should never look for leading underscores
+# because GDB strips them off during symbol read-in.  Thus -Dnounderscore.
+cplus-dem.o : cplus-dem.c
+       ${CC} -c -Dnounderscore `echo ${srcdir}/cplus-dem.c | sed 's,^\./,,'`
diff --git a/gdb/Makefile.srcdir b/gdb/Makefile.srcdir
new file mode 100755 (executable)
index 0000000..b5fb6b3
--- /dev/null
@@ -0,0 +1 @@
+srcdir=.
diff --git a/gdb/Projects b/gdb/Projects
new file mode 100644 (file)
index 0000000..b30d268
--- /dev/null
@@ -0,0 +1,97 @@
+
+        Suggested projects for aspiring or current GDB hackers
+        ======================================================
+
+    (You should probably chat with bug-gdb@cygnus.com to make sure that
+  no one else is doing the project you chose).
+
+Rewrite proceed, wait_for_inferior, and normal_stop to clean them up.
+Suggestions: 
+
+       1) Make each test in wait_for_inferior a seperate subroutine
+          call.
+       2) Combine wait_for_inferior and normal_stop to clean up
+          communication via global variables.
+       3) See if you can find some way to clean up the global
+          variables that are used; possibly group them by data flow
+          and information content?
+
+Work out some kind of way to allow running the inferior to be done as
+a sub-execution of, eg. breakpoint command lists.  Currently running
+the inferior interupts any command list execution.  This would require
+some rewriting of wait_for_inferior & friends, and hence should
+probably be done in concert with the above.
+
+Add function arguments to gdb user defined functions.
+
+Add convenience variables that refer to exec file, symbol file,
+selected frame source file, selected frame function, selected frame
+line number, etc.
+
+Add a "suspend" subcommand of the "continue" command to suspend gdb
+while continuing  execution of the subprocess.  Useful when you are
+debugging servers and you want to dodge out and initiate a connection
+to a server running under gdb.
+
+Work out and implement a reasonably general mechanism for multi-threaded
+processies.  There are parts of one implemented in convex-dep.c, if
+you want an example.
+
+Add stab information to allow reasonable debugging of inline functions
+(possibly they should show up on a stack backtrace?  With a note
+indicating that they weren't "real"?).
+
+Implement support for specifying arbitrary locations of stack frames
+(in practice, this usually requires specification of both the top and
+bottom of the stack frame (fp and sp), since you *must* retrieve the
+pc that was saved in the innermost frame).
+
+Modify the naked "until" command to step until past the current source
+line, rather than past the current pc value.  This is tricky simply
+because the low level routines have no way of specifying a multi-line
+step range, and there is no way of saying "don't print stuff when we
+stop" from above (otherwise could just call step many times).
+
+Modify the handling of symbols grouped through BINCL/EINCL stabs to
+allocate a partial symtab for each BINCL/EINCL grouping.  This will
+seriously decrease the size of inter-psymtab dependencies and hence
+lessen the amount that needs to be read in when a new source file is
+accessed. 
+
+Do an "x/i $pc" after each stepi or nexti.  
+
+Modify all of the disassemblers to use printf_filtered to get correct
+more filtering.
+
+Modify gdb to work correctly with Pascal.
+
+Rewrite macros that handle frame chaining and frameless functions.
+They should be able to tell the difference between start, main, and a
+frameless function called from main.
+
+Work out what information would need to be included in an executable
+by the compiler to allow gdb to debug functions which do not have a
+frame pointer.  Modify gdb and gcc to do this.
+
+When `attached' to a program (via either OS support or remote
+debugging), gdb should arrange to catch signals which the terminal
+might send, as it is unlikely that the program will be able to notice
+them.  SIGINT and SIGTSTP are obvious examples.
+
+Enhance the gdb manual with extra examples where needed.
+
+Arrange for list_command not to use decode_line_1 and thus not require
+symbols to be read in simply to read a source file.
+
+Allow patching of executables, a la "adb -w".
+
+Improve the target interface so that targets can be stacked; e.g. an
+exec file and a core file (memory references that the core file can't
+satisfy are directed to the exec file); those two plus a child process.
+The child doesn't let any refs through, but when the child terminates,
+you are back to debugging the core file -- you might even want to swap
+back and forth between the two, or between two core files.
+
+# Local Variables:
+# mode: text
+# End:
diff --git a/gdb/TODO b/gdb/TODO
new file mode 100644 (file)
index 0000000..93dce62
--- /dev/null
+++ b/gdb/TODO
@@ -0,0 +1,325 @@
+
+       gdb bug list
+       John Gilmore, gnu@cygnus.com
+
+This bug list is probably not up to date or accurate, but it reflects
+some known bugs in gdb, if you are into bug-hunting.
+
+
+Update the TODO list with all the lists of gdb bugs lying around on paper.
+
+"share" command should not need to be manually run.  It should be run
+as soon as possible, automatically, both on "run" and on core files.
+
+It should be possible to use symbols from shared libraries before we know
+exactly where the libraries will be loaded.  E.g. "b perror" before running
+the program.  This could maybe be done as an extension of the "breakpoint
+re-evaluation" after new symbols are loaded.
+
+Make single_step() insert and remove breakpoints in one operation.
+
+Speed up single stepping by avoiding extraneous ptrace calls.
+
+Speed up single stepping by not inserting and removing breakpoints
+each time the inferior starts and stops.
+
+Speed up watchpoints by not single-stepping them, but do something
+faster like single-line execution.
+
+Update gdb.texinfo to include doc on the directory structure and 
+the various tricks of building gdb.
+
+Do a tutorial in gdb.texinfo on how to do simple things in gdb.
+E.g. how to set a breakpoint that just prints something and continues.
+How to break on aborts.  Etc.
+
+Do a "new features" section for release 4.
+
+Provide "voodoo" debugging of core files.  This creates a zombie
+process as a child of the debugger, and loads it up with the data,
+stack, and regs of the core file.  This allows you to call functions
+in the executable, to manipulate the data in the core file.
+
+GDB reopens the source file on every line, as you "next" through it.
+
+Referencing the vtbl member of a struct doesn't work.  It prints OK
+if you print the struct, but it gets 0 if you try to deref it.
+
+Persistent command history: A feature where you could save off a list
+of the commands you did, so you can edit it into something that will bring
+the target to the same place every time you source it.  Sun wants it.
+This would also be useful for automated fast watchpointing; if you go
+past the place where it watchpoints, you just start it over again and
+do it more carefully.
+
+Deal with the Sun ptrace bug that loses the registers if the stack is
+paged out.
+
+Finish the C++ exception handling stub routines.  Lint points them out
+as unused statics functions.
+
+"i source" only shows you info about files that it can read.  When it
+can't read a file and complains, you can't see any info about it, like
+where it was compiled.  Perhaps "i source" should take an argument
+like that of "list".
+
+See if coredep.c's fetch_core_registers can be used on more machines.
+E.g. MIPS (mips-xdep.c).
+
+coredep.c is completely broken.  Needs work just to compile, it uses
+"u" and doesn't declare it, etc.
+
+unpack_double() does not handle IEEE float on the target unless the host
+is also IEEE.  Death on a vax.
+
+Test cross-debugging Unix-to-Unix.
+
+Check the RAPP remote protocol.  What is it?  It's in Makefile.dist
+and one ChangeLog entry.
+
+Set up interface between GDB and INFO so that you can hop into interactive
+INFO and back out again.  When running under Emacs, should use Emacs
+info, else fork the info program.  Installation of GDB should install
+its texinfo files into the info tree automagically, including the readline
+texinfo files..
+
+Improve backtrace output to avoid line wraps.  Prettify it.
+
+"help address" ought to find the "help set addressprint" entry.
+
+Remove the VTBL internal guts from printouts of C++ structs, unless
+vtblprint is set.
+
+Remove "at 0xnnnn" from the "b foo" response, if !addressprint and if
+it matches the source line indicated.
+
+The prompt at end of screen should accept space as well as CR.
+
+"List" should put you into a pseudo-"more" where you can hit space 
+to get more, forever to eof.
+
+Check STORE_RETURN_VALUE on all architectures.  Check near it in tm-sparc.h
+for other bogosities.
+
+Check for storage leaks in GDB, I'm sure there are a lot!
+
+vtblprint of a vtbl should demangle the names it's printing.
+
+Backtrace should point out what the currently selected frame is, in its
+display, perhaps showing ">3 foo (bar, ...)" rather than "#3 foo (bar, ...)".
+
+"i program" should work for core files, and display more info, like what
+actually caused it to die.
+
+Hitting ^Z to an inferior doesn't work right, it takes several continues
+to make it actually go.
+
+"i fun" doesn't show misc function vector symbols.
+
+"x/10i" should shorten the long name, if any, on subsequent lines.
+
+Check through the code for FIXME comments and fix them.  dbxread.c,
+blockframe.c, and plenty more.
+
+"next" over a function that longjumps, never stops until next time you happen
+to get to that spot by accident.  E.g. "n" over execute_command which has
+an error.
+
+Watchpoints seem not entirely reliable.
+
+"set zeroprint off", don't bother printing members of structs which are entirely
+zero.  Useful for those big structs with few useful members.
+
+GDB does four ioctl's for every command, probably switching terminal modes
+to/from inferior or for readline or something.
+
+terminal_ours versus terminal_inferior: cache state.  Switch should be a noop
+if the state is the same, too.
+
+ptype $i6 = void??!
+
+Clean up invalid_float handling so gdb doesn't coredump when it tries to
+access a NaN.  While this might work on SPARC, other machines are not
+configured right.
+
+"b value_at ; commands ; continue ; end" stops EVERY OTHER TIME!
+Then once you enter a command, it does the command, runs two more
+times, and then stops again!  Bizarre...  (This behaviour has been
+modified, but it is not yet 100% predictable when e.g. the commands
+call functions in the child, and while there, the child is interrupted
+with a signal, or hits a breakpoint.)
+
+Symbol completion with TAB does not unmangle names!
+
+help completion, help history should work.
+
+Symbol completion doesn't handle e.g. W::f.  (symtab.c,
+make_symbol_completion_list).
+
+AMD version: ^C should do ^Ak to stop ebmon.
+
+Check that we can handle stack trace through varargs AND alloca in same
+function, on 29K.
+
+wait_for_inferior loops forever if wait() gives it an error.
+
+"i frame" arg formatting sucks.  Should wrap lines.
+"bt" arg formatting needs the same treatment .
+
+"i frame" shows wrong "arglist at" location, doesn't show where the args
+should be found, only their actual values.
+
+Symbolic display of addrs, (& disassembly prefixes), don't show static
+fns, e.g. enable_command in gdb.
+
+'ptype yylval' ==> "union YYSTYPE { ..... }".  However, it is not a
+union YYSTYPE, but is simply a YYSTYPE, which is a typedef for an
+unnamed union.
+
+"show all" should work.
+
+There should be a way for "set" commands to validate the new setting
+before it takes effect.
+
+The "display" command should become the "always" command, e.g.
+       "always print XXX"
+       "always p/xxx XXX"
+       "always echo foo"
+       "always call XXX"
+       "always x/i $pc", etc.
+
+A mess of floating point opcodes are missing from sparc-opcode.h.
+Also, a little program should test the table for bits that are
+overspecified or underspecified.  E.g. if the must-be-ones bits
+and the must-be-zeroes bits leave some fields unexamined, and the format
+string leaves them unprinted, then point this out.  If multiple
+non-alias patterns match, point this out too.  Finally, there should
+be a sparc-optest.s file that tries each pattern out.  This file
+should end up coming back the same (modulo transformation comments) 
+if fed to "gas" then the .o is fed to gdb for disassembly.
+
+Merge the xxx-opcode.h files with gas again...
+
+Eliminate all the core_file_command's in all the xdep files.
+Eliminate separate declarations of registers[] everywhere.
+
+"ena d" is ambiguous, why?  "ena delete" seems to think it is a command!
+
+Line numbers are off in some spots.  In proceed() at 1st "oneproc = 1",
+it seems to run that statement, but it doesn't actually.
+
+Perhaps the tdep and xdep files, and the tm and xm files, into a config
+subdirectory.  If not, at least straighten out their names so that
+they all start with the machine name.
+
+inferior_status should include stop_print_frame.  It won't need to be
+reset in wait_for_inferior after bpstat_stop_status call, then.
+
+i line VAR produces "Line number not known for symbol ``var''.".  I
+thought we were stashing that info now!
+
+Make sure we can handle executables with no symbol info, e.g. /bin/csh.
+
+We should be able to write to executables that aren't running.
+
+We should be able to write to random files at hex offsets like adb.
+
+Tiemann:  It is very painful to look at fp registers that hold
+double precision values.  GDB is happy to show them to you as single
+precision, but you cannot look at them as doubles.  Perhaps casting
+should be changed to make this work; or maybe a new "set" option that
+sets the default fp precision to single, double, or quad.  This is not
+urgent, but would be nice to get into GDB 4.0.
+
+Make "target xxx" command interruptible.
+
+Handle add_file with separate text, data, and bss addresses.  Maybe
+handle separate addresses for each segment in the object file?
+
+Handle free_named_symtab to cope with multiply-loaded object files
+in a dynamic linking environment.  Should remember the last copy loaded,
+but not get too snowed if it finds references to the older copy.
+
+Implement have_memory, have_stack, have_registers, have_execution.
+Memory:  core, exec, child, vxworks even without child.
+stack:   core, child, vxworks with child
+registers:  core, child, vxworks with child
+execution:  child, vxworks with child.
+
+The original BFD core dump reading routine would itself coredump when fed
+a garbage file as a core file.  Does the current one?
+
+Breakpoints should not be inserted and deleted all the time.  Only the
+one(s) there should be removed when we have to step over one.  Support
+breakpoints that don't have to be removed to step over them.
+
+Stop reading stop_registers!
+
+Generalize and Standardize the RPC interface to a target program,
+improve it beyond the "ptrace" interface, and see if it can become a standard
+for remote debugging.  Is WRS interested in donating their target-end
+code?
+
+Remove all references to:
+       text_offset
+       data_offset
+       text_data_start
+       text_end
+       exec_data_offset
+       ...
+now that we have BFD.  All remaining are in machine dependent files.
+
+When quitting with a running program, if a core file was previously
+examined, you get "Couldn't read float regs from core file"...if 
+indeed it can't.  generic_mourn_inferior...
+
+...
+
+Check signal argument to remote proceed's and error if set.
+
+Handle floating point registers in core files under BFD.  Currently
+they are punted.
+
+Sort help and info output.
+
+Re-organize help categories into things that tend to fit on a screen
+and hang together.
+
+When trying to print source lines but you can't find the file,
+print the file name and line number, and leave it selected anyway
+so "i source" will show it.
+
+renote-nindy.c handles interrupts poorly; it error()s out of badly
+chosen places, e.g. leaving current_frame zero, which causes core dumps
+on the next command.
+
+Add in commands like ADB's for searching for patterns, etc.  We should
+be able to examine and patch raw unsymboled binaries as well in gdb as
+we can in adb.  (E.g. increase the timeout in /bin/login without source).
+
+Those xdep files that call register_addr without defining it are
+probably simply broken.  When reconfiguring this part of gdb, I could
+only make guesses about how to redo some of those files, and I
+probably guessed wrong, or left them "for later" when I have a
+machine that can attempt to build them.
+
+Use the complain() mechanism for handling all the error() calls in dbxread.c,
+and in similar situations in coffread.c and mipsread.c.
+
+When doing "step" or "next", if a few lines of source are skipped between
+the previous line and the current one, print those lines, not just the
+last line of a multiline statement.
+
+When searching for C++ superclasses in value_cast in valops.c, we must
+not search the "fields", only the "superclasses".  There might be a
+struct with a field name that matches the superclass name.  This can
+happen when the struct was defined before the superclass (before the
+name became a typedef).
+
+For "float point[15];":
+ptype &point[4]   ==> Attempt to take address of non-lvalue.
+p     &point[4]   ==> Dereferences point[4] rather than giving you point+4.
+
+Fix symbol reading in the presence of interrupts.  It currently leaves a
+cleanup to blow away the entire symbol table when a QUIT occurs.
+
diff --git a/gdb/WHATS.NEW b/gdb/WHATS.NEW
new file mode 100755 (executable)
index 0000000..97b0415
--- /dev/null
@@ -0,0 +1,223 @@
+               GDB 4.0 -- what has changed since 3.5?
+
+ *  New Facilities
+
+Gdb now paginates its output, with a ``more''-like interface.  You can
+set the screen width and screen height with new ``set'' commands; they
+default to your terminal settings.  Wide output is wrapped at good
+places to make the output more readable.
+
+Gdb now reads its input via the ``readline'' interface.  This provides
+inline editing of commands, using familiar Emacs or VI commands (like
+``tcsh'' or the korn shell); history substitutions a la the C shell;
+and storage and recall of your command history across debugging
+sessions.  The default is Emacs mode; to switch temporarily to vi mode,
+use control-meta-J or ESC control-j.  You can switch permanently to vi
+mode by putting the line ``set editing-mode vi'' in the file .inputrc
+in your home directory.   For full details, see the description in
+readline/inc-readline.texinfo and readline/inc-history.texinfo.
+
+Gdb now supports cross-debugging from a host machine of one type to a
+target machine of another type.  Communication with the target system
+is over serial lines.  The ``target'' command handles connecting to the
+remote system; the ``load'' command will download a program into the
+remote system.  It also supports debugging of realtime processes
+running under VxWorks, using SunRPC Remote Procedure Calls over TCP/IP
+to talk to a debugger stub on the target system.
+
+New CPUs supported include the AMD 29000 and Intel 960.
+
+GDB now reads object files and symbol tables via a ``binary file'' 
+library, which allows a single copy of GDB to debug programs of multiple
+object file types such as a.out and coff.
+
+There is now a GDB reference card in "gdbrc.tex".
+
+
+ *  Control-Variable user interface simplified
+
+All variables that control the operation of the debugger can be set
+by the ``set'' command, and displayed by the ``show'' command.
+
+For example, ``set prompt new-gdb=>'' will change your prompt to new-gdb=>.
+``Show prompt'' produces the response:
+Gdb's prompt is new-gdb=>.
+
+What follows are the NEW set commands.  The command ``help set'' will
+print a complete list of old and new set commands.  ``help set FOO''
+will give a longer description of the variable FOO.
+
+caution on/off:  Enables warning questions for operations that are
+                hard to recover from, e.g. rerunning the program while
+                it is already running.  Default is ON.
+
+editing on/off:  Enables EMACS style command line editing 
+                 of input.  Previous lines can be recalled with 
+                control-P, the current line can be edited with control-B,
+                you can search for commands with control-R, etc.
+                Default is ON.
+
+history filename NAME:  NAME is where the gdb command history 
+                       will be stored.  The default is .gdb_history,
+                       or the value of the environment variable
+                       GDBHISTFILE.
+
+history size N:  The size, in commands, of the command history.  The 
+                default is 256, or the value of the environment variable
+                HISTSIZE.
+
+history write on/off: If this value is set to ON, the history file will
+                     be saved after exiting gdb.  If set to OFF, the 
+                     file will not be saved.  The default is OFF.
+
+history expansion on/off: If this value is set to ON, then csh-like 
+                         history expansion will be performed  on 
+                         command line input.  The default is OFF.
+
+radix N:  Sets the default radix for input and output.  It can be set
+         to 8, 10, or 16.  Note that the argument to "radix" is interpreted
+         in the current radix, so "set radix 10" is always a no-op.
+
+screen-height N: This integer value is the number of lines on a page. Default
+                 is 24, the current `stty rows'' setting, or the ``li#''
+                setting from the termcap entry matching the environment
+                variable TERM.
+
+screen-width N:  This integer value is the number of characters on a line.
+                Default is 80, the current `stty cols'' setting, or the ``co#''
+                setting from the termcap entry matching the environment
+                variable TERM.
+
+Note: ``set screensize'' is obsolete. Use ``set screen-height'' and
+``set screen-width'' instead.
+
+addressprint on/off:  Print memory addresses in various command displays,
+                     such as stack traces and structure values.  Gdb looks
+                     more ``symbolic'' if you turn this off; it looks more
+                     ``machine level'' with it on.  Default is ON.
+
+arrayprint on/off:  Prettyprint arrays.  New convenient format!  Default 
+                    is OFF.
+
+demangle on/off:   Print C++ symbols in "source" form if on, "raw" form if off.
+
+asm-demangle on/off:  Same, for assembler level printouts like instructions.
+
+vtblprint on/off:  Prettyprint C++ virtual function tables.  Default is OFF.
+
+
+ *  Support for Epoch Environment.
+
+The epoch environment is a version of Emacs v18 with windowing.  One
+new command, ``inspect'', is identical to ``print'', except that if you
+are running in the epoch environment, the value is printed in its own
+window.
+
+
+ *  Support for Shared Libraries
+
+GDB can now debug programs and core files that use SunOS shared libraries.
+Symbols from a shared library cannot be referenced
+before the shared library has been linked with the program (this
+happens after you type ``run'' and before the function main() is entered).
+At any time after this linking (including when examining core files
+from dynamically linked programs), gdb reads the symbols from each
+shared library when you type the ``sharedlibrary'' command.
+It can be abbreviated ``share''.
+
+sharedlibrary REGEXP:  Load shared object library symbols for files 
+                       matching a unix regular expression.  No argument
+                      indicates to load symbols for all shared libraries.
+
+info sharedlibrary:  Status of loaded shared libraries.
+
+
+ *  Watchpoints
+
+A watchpoint stops execution of a program whenever the value of an
+expression changes.  Checking for this slows down execution
+tremendously whenever you are in the scope of the expression, but is
+quite useful for catching tough ``bit-spreader'' or pointer misuse
+problems.  Some machines such as the 386 have hardware for doing this
+more quickly, and future versions of gdb will use this hardware.
+
+watch EXP:  Set a watchpoint (breakpoint) for an expression.
+
+info watchpoints:  Information about your watchpoints.
+
+delete N:   Deletes watchpoint number N (same as breakpoints).
+disable N:  Temporarily turns off watchpoint number N (same as breakpoints).
+enable N:   Re-enables watchpoint number N (same as breakpoints).
+
+
+ *  C++ multiple inheritance
+
+When used with a GCC version 2 compiler, GDB supports multiple inheritance
+for C++ programs.
+
+ *  C++ exception handling
+
+Gdb now supports limited C++ exception handling.  Besides the existing
+ability to breakpoint on an exception handler, gdb can breakpoint on
+the raising of an exception (before the stack is peeled back to the
+handler's context).
+
+catch FOO:  If there is a FOO exception handler in the dynamic scope,
+           set a breakpoint to catch exceptions which may be raised there.
+           Multiple exceptions (``catch foo bar baz'') may be caught.
+
+info catch:  Lists all exceptions which may be caught in the
+             current stack frame.
+
+
+ *  Minor command changes
+
+The command ``call func (arg, arg, ...)'' now acts like the print
+command, except it does not print or save a value if the function's result
+is void.  This is similar to dbx usage.
+
+The ``up'' and ``down'' commands now always print the frame they end up
+at; ``up-silently'' and `down-silently'' can be used in scripts to change
+frames without printing.
+
+ *  New directory command
+
+'dir' now adds directories to the FRONT of the source search path.
+The path starts off empty.  Source files that contain debug information
+about the directory in which they were compiled can be found even
+with an empty path; GCC includes this information.  If GDB can't find
+your source file in the current directory, type "dir .".
+
+ *  Features removed in this release
+
+``info types'' has been removed, since it printed builtin types in a
+confusing fashion, and did not do useful things with typedefs.  ``ptype''
+or ``whatis'' are more useful commands for dealing with types..
+
+
+ * Configuring GDB for compilation
+
+For normal use, type ``config.gdb host''.  Hosts now handled are:
+
+3b1 altos altosgas arm bigmips convex hp300bsd hp300hpux i386v i386v-g 
+i386v32 i386v32-g isi littlemips m88k merlin news news1000 none np1 pn
+pyramid sun2os3 sun2os4 sun386 sun3os3 sun3os4 sun4os3 sun4os4 symmetry
+umax vax
+
+Type config.gdb +host to get a full description of each host.
+
+You can now build gdb conveniently for several architectures from the
+same sources.  If config.gdb is run from a subdirectory, it configures
+the Makefile to use source files from '..'.  Each subdirectory can be
+indpendently configured.  An explicit source file directory can also
+be specified with the +srcdir=xxx option.  Due to obscure search rules
+in the C preprocessor, if you have previously built gdb in the main 
+directory, run 'make cleanconfig' in the top level directory before
+building it in a subdirectory.
+
+GDB now handles cross debugging.  If you are remotely debugging between 
+two different machines, type ``config.gdb host target''.
+Host is the machine where gdb will run; target is the machine
+where the program that you are debugging will run.
+
+Type config.gdb +target to get a full description of each target.
diff --git a/gdb/alldeps.mak b/gdb/alldeps.mak
new file mode 100644 (file)
index 0000000..73e6cb8
--- /dev/null
@@ -0,0 +1,196 @@
+ALLDEPFILES = $(ALLDEPFILES_MAINDIR) $(ALLDEPFILES_SUBDIR)
+ALLDEPFILES_MAINDIR=\
+altos-xdep.c\
+am29k-pinsn.c\
+am29k-tdep.c\
+arm-convert.s\
+arm-pinsn.c\
+arm-tdep.c\
+arm-xdep.c\
+convex-pinsn.c\
+convex-tdep.c\
+convex-xdep.c\
+coredep.c\
+exec.c\
+gould-pinsn.c\
+gould-xdep.c\
+hp300hpux-xdep.c\
+i386-pinsn.c\
+i386-tdep.c\
+i386-xdep.c\
+i960-pinsn.c\
+i960-tdep.c\
+infptrace.c\
+m68k-pinsn.c\
+m68k-tdep.c\
+mips-pinsn.c\
+mips-tdep.c\
+mips-xdep.c\
+mipsread.c\
+news-xdep.c\
+nindy-tdep.c\
+ns32k-pinsn.c\
+pyr-pinsn.c\
+pyr-tdep.c\
+pyr-xdep.c\
+remote-eb.c\
+remote-nindy.c\
+remote-vx.c\
+solib.c\
+sparc-pinsn.c\
+sparc-tdep.c\
+sparc-xdep.c\
+sun3-xdep.c\
+sun386-xdep.c\
+symmetry-tdep.c\
+symmetry-xdep.c\
+tdesc.c\
+umax-xdep.c\
+vax-pinsn.c
+
+ALLDEPFILES_SUBDIR=\
+nindy-share/Onindy.c\
+nindy-share/nindy.c\
+nindy-share/ttybreak.c\
+nindy-share/ttyflush.c\
+vx-share/xdr_ld.c\
+vx-share/xdr_ptrace.c\
+vx-share/xdr_rdb.c\
+vx-share/xdr_regs.c
+
+ALLPARAM=\
+tm-29k.h\
+tm-3b1.h\
+tm-88k.h\
+tm-altos.h\
+tm-altosgas.h\
+tm-arm.h\
+tm-bigmips.h\
+tm-convex.h\
+tm-hp300bsd.h\
+tm-hp300hpux.h\
+tm-i386v-g.h\
+tm-i386v.h\
+tm-isi.h\
+tm-merlin.h\
+tm-mips.h\
+tm-news.h\
+tm-nindy960.h\
+tm-np1.h\
+tm-pn.h\
+tm-pyr.h\
+tm-sparc.h\
+tm-sun2.h\
+tm-sun2os4.h\
+tm-sun3.h\
+tm-sun386.h\
+tm-sun3os4.h\
+tm-sun4os4.h\
+tm-symmetry.h\
+tm-umax.h\
+tm-vax.h\
+tm-vxworks68.h\
+tm-vxworks960.h\
+xm-3b1.h\
+xm-88k.h\
+xm-altos.h\
+xm-arm.h\
+xm-bigmips.h\
+xm-convex.h\
+xm-hp300bsd.h\
+xm-hp300hpux.h\
+xm-i386v.h\
+xm-i386v32.h\
+xm-isi.h\
+xm-merlin.h\
+xm-mips.h\
+xm-news.h\
+xm-news1000.h\
+xm-np1.h\
+xm-pn.h\
+xm-pyr.h\
+xm-sparc.h\
+xm-sun2.h\
+xm-sun3.h\
+xm-sun386.h\
+xm-sun3os4.h\
+xm-sun4os4.h\
+xm-symmetry.h\
+xm-umax.h\
+xm-vax.h
+
+ALLCONFIG=\
+./tconfig/3b1\
+./tconfig/altos\
+./tconfig/altosgas\
+./tconfig/am29k\
+./tconfig/arm\
+./tconfig/bigmips\
+./tconfig/convex\
+./tconfig/hp300bsd\
+./tconfig/hp300hpux\
+./tconfig/i386v\
+./tconfig/i386v-g\
+./tconfig/i386v32\
+./tconfig/i386v32-g\
+./tconfig/i960\
+./tconfig/isi\
+./tconfig/littlemips\
+./tconfig/m88k\
+./tconfig/merlin\
+./tconfig/news\
+./tconfig/news1000\
+./tconfig/nindy960\
+./tconfig/none\
+./tconfig/np1\
+./tconfig/pn\
+./tconfig/pyramid\
+./tconfig/sun2os3\
+./tconfig/sun2os4\
+./tconfig/sun3\
+./tconfig/sun386\
+./tconfig/sun3os3\
+./tconfig/sun3os4\
+./tconfig/sun4\
+./tconfig/sun4os3\
+./tconfig/sun4os4\
+./tconfig/symmetry\
+./tconfig/umax\
+./tconfig/vax\
+./tconfig/vxworks68\
+./tconfig/vxworks960\
+./xconfig/3b1\
+./xconfig/altos\
+./xconfig/altosgas\
+./xconfig/arm\
+./xconfig/bigmips\
+./xconfig/convex\
+./xconfig/hp300bsd\
+./xconfig/hp300hpux\
+./xconfig/i386v\
+./xconfig/i386v-g\
+./xconfig/i386v32\
+./xconfig/i386v32-g\
+./xconfig/isi\
+./xconfig/littlemips\
+./xconfig/m88k\
+./xconfig/merlin\
+./xconfig/news\
+./xconfig/news1000\
+./xconfig/none\
+./xconfig/np1\
+./xconfig/pn\
+./xconfig/pyramid\
+./xconfig/sun2os3\
+./xconfig/sun2os4\
+./xconfig/sun3\
+./xconfig/sun386\
+./xconfig/sun3os3\
+./xconfig/sun3os4\
+./xconfig/sun4\
+./xconfig/sun4os3\
+./xconfig/sun4os4\
+./xconfig/symmetry\
+./xconfig/umax\
+./xconfig/vax
+
diff --git a/gdb/alloca.c b/gdb/alloca.c
new file mode 100644 (file)
index 0000000..d5de3de
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+       alloca -- (mostly) portable public-domain implementation -- D A Gwyn
+
+       last edit:      86/05/30        rms
+          include config.h, since on VMS it renames some symbols.
+          Use xmalloc instead of malloc.
+
+       This implementation of the PWB library alloca() function,
+       which is used to allocate space off the run-time stack so
+       that it is automatically reclaimed upon procedure exit, 
+       was inspired by discussions with J. Q. Johnson of Cornell.
+
+       It should work under any C implementation that uses an
+       actual procedure stack (as opposed to a linked list of
+       frames).  There are some preprocessor constants that can
+       be defined when compiling for your specific system, for
+       improved efficiency; however, the defaults should be okay.
+
+       The general concept of this implementation is to keep
+       track of all alloca()-allocated blocks, and reclaim any
+       that are found to be deeper in the stack than the current
+       invocation.  This heuristic does not reclaim storage as
+       soon as it becomes invalid, but it will do so eventually.
+
+       As a special case, alloca(0) reclaims storage without
+       allocating any.  It is a good idea to use alloca(0) in
+       your main control loop, etc. to force garbage collection.
+*/
+#ifndef lint
+static char    SCCSid[] = "@(#)alloca.c        1.1";   /* for the "what" utility */
+#endif
+
+#ifdef emacs
+#include "config.h"
+#ifdef static
+/* actually, only want this if static is defined as ""
+   -- this is for usg, in which emacs must undefine static
+   in order to make unexec workable
+   */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif static
+#endif emacs
+
+#ifdef __STDC__
+typedef void   *pointer;               /* generic pointer type */
+#else
+typedef char   *pointer;               /* generic pointer type */
+#endif
+
+#define        NULL    0                       /* null pointer constant */
+
+extern void    free();
+extern pointer xmalloc();
+
+/*
+       Define STACK_DIRECTION if you know the direction of stack
+       growth for your system; otherwise it will be automatically
+       deduced at run-time.
+
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown
+*/
+
+#ifndef STACK_DIRECTION
+#define        STACK_DIRECTION 0               /* direction unknown */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define        STACK_DIR       STACK_DIRECTION /* known at compile-time */
+
+#else  /* STACK_DIRECTION == 0; need run-time code */
+
+static int     stack_dir;              /* 1 or -1 once known */
+#define        STACK_DIR       stack_dir
+
+static void
+find_stack_direction (/* void */)
+{
+  static char  *addr = NULL;   /* address of first
+                                  `dummy', once known */
+  auto char    dummy;          /* to get stack address */
+
+  if (addr == NULL)
+    {                          /* initial entry */
+      addr = &dummy;
+
+      find_stack_direction (); /* recurse once */
+    }
+  else                         /* second entry */
+    if (&dummy > addr)
+      stack_dir = 1;           /* stack grew upward */
+    else
+      stack_dir = -1;          /* stack grew downward */
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/*
+       An "alloca header" is used to:
+       (a) chain together all alloca()ed blocks;
+       (b) keep track of stack depth.
+
+       It is very important that sizeof(header) agree with malloc()
+       alignment chunk size.  The following default should work okay.
+*/
+
+#ifndef        ALIGN_SIZE
+#define        ALIGN_SIZE      sizeof(double)
+#endif
+
+typedef union hdr
+{
+  char align[ALIGN_SIZE];      /* to force sizeof(header) */
+  struct
+    {
+      union hdr *next;         /* for chaining headers */
+      char *deep;              /* for stack depth measure */
+    } h;
+} header;
+
+/*
+       alloca( size ) returns a pointer to at least `size' bytes of
+       storage which will be automatically reclaimed upon exit from
+       the procedure that called alloca().  Originally, this space
+       was supposed to be taken from the current stack frame of the
+       caller, but that method cannot be made to work for some
+       implementations of C, for example under Gould's UTX/32.
+*/
+
+static header *last_alloca_header = NULL; /* -> last alloca header */
+
+pointer
+alloca (size)                  /* returns pointer to storage */
+     unsigned  size;           /* # bytes to allocate */
+{
+  auto char    probe;          /* probes stack depth: */
+  register char        *depth = &probe;
+
+#if STACK_DIRECTION == 0
+  if (STACK_DIR == 0)          /* unknown growth direction */
+    find_stack_direction ();
+#endif
+
+                               /* Reclaim garbage, defined as all alloca()ed storage that
+                                  was allocated from deeper in the stack than currently. */
+
+  {
+    register header    *hp;    /* traverses linked list */
+
+    for (hp = last_alloca_header; hp != NULL;)
+      if (STACK_DIR > 0 && hp->h.deep > depth
+         || STACK_DIR < 0 && hp->h.deep < depth)
+       {
+         register header       *np = hp->h.next;
+
+         free ((pointer) hp);  /* collect garbage */
+
+         hp = np;              /* -> next header */
+       }
+      else
+       break;                  /* rest are not deeper */
+
+    last_alloca_header = hp;   /* -> last valid storage */
+  }
+
+  if (size == 0)
+    return NULL;               /* no allocation required */
+
+  /* Allocate combined header + user data storage. */
+
+  {
+    register pointer   new = xmalloc (sizeof (header) + size);
+    /* address of header */
+
+    ((header *)new)->h.next = last_alloca_header;
+    ((header *)new)->h.deep = depth;
+
+    last_alloca_header = (header *)new;
+
+    /* User storage begins just after header. */
+
+    return (pointer)((char *)new + sizeof(header));
+  }
+}
+
diff --git a/gdb/altos-xdep.c b/gdb/altos-xdep.c
new file mode 100644 (file)
index 0000000..1949c8d
--- /dev/null
@@ -0,0 +1,166 @@
+/* Low level interface to ptrace, for GDB when running under m68k SVR2 Unix
+   on Altos 3068.  Report bugs to Jyrki Kuoppala <jkp@cs.hut.fi>
+   Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#ifdef USG
+#include <sys/page.h>
+#ifdef ALTOS
+#include <sys/net.h>
+#include <errno.h>
+#endif
+#endif
+
+#include "gdbcore.h"
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <sys/stat.h>
+\f
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct user u;
+
+       unsigned int reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name ("Not a core file: reading upage");
+       if (val != sizeof u)
+         error ("Not a core file: could only read %d bytes", val);
+       data_start = exec_data_start;
+
+#if !defined (NBPG)
+#define NBPG NBPP
+#endif
+#if !defined (UPAGES)
+#define UPAGES USIZE
+#endif
+
+       data_end = data_start + NBPG * u.u_dsize;
+       stack_start = stack_end - NBPG * u.u_ssize;
+       data_offset = NBPG * UPAGES + exec_data_start % NBPG /* Not sure about this //jkp */;
+       stack_offset = NBPG * (UPAGES + u.u_dsize);
+
+       /* Some machines put an absolute address in here and some put
+          the offset in the upage of the regs.  */
+       reg_offset = (int) u.u_state;
+       if (reg_offset > NBPG * UPAGES)
+         reg_offset -= KERNEL_U_ADDR;
+
+       bcopy (&u.u_exdata, &core_aouthdr, sizeof (AOUTHDR));
+       printf ("Core file is from \"%s\".\n", u.u_comm);
+
+       /* I don't know where to find this info.
+          So, for now, mark it as not available.  */
+       N_SET_MAGIC (core_aouthdr, 0);
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < NUM_REGS; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             val = lseek (corechan, register_addr (regno, reg_offset), 0);
+             if (val < 0
+                 || (val = myread (corechan, buf, sizeof buf)) < 0)
+               {
+                 char * buffer = (char *) alloca (strlen (reg_names[regno])
+                                                  + 30);
+                 strcpy (buffer, "Reading register ");
+                 strcat (buffer, reg_names[regno]);
+                                                  
+                 perror_with_name (buffer);
+               }
+
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
diff --git a/gdb/am29k-opcode.h b/gdb/am29k-opcode.h
new file mode 100644 (file)
index 0000000..96aff40
--- /dev/null
@@ -0,0 +1,271 @@
+/* Table of opcodes for the AMD 29000
+   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+struct am29k_opcode {
+  /* Name of the instruction.  */
+  char *name;
+
+  /* Opcode (i.e. most significant byte of the word).  */
+  unsigned char opcode;
+
+  /* A string of characters which describe the operands.
+     Valid characters are:
+     ,        Itself.  The character appears in the assembly code.
+     a        RA.  The register number is in bits 8-15 of the instruction.
+     b        RB.  The register number is in bits 0-7 of the instruction.
+     c        RC.  The register number is in bits 16-23 of the instruction.
+     i        An immediate operand is in bits 0-7 of the instruction.
+     x        Bits 0-7 and 16-23 of the instruction are bits 0-7 and 8-15
+              (respectively) of the immediate operand.
+     h        Same as x but the instruction contains bits 16-31 of the
+              immediate operand.
+     X        Same as x but bits 16-31 of the signed immediate operand
+              are set to 1 (thus the operand is always negative).
+     P,A      Bits 0-7 and 16-23 of the instruction are bits 2-9 and 10-17
+              (respectively) of the immediate operand.
+             P=PC-relative, sign-extended to 32 bits.
+             A=Absolute, zero-extended to 32 bits.
+     e        CE bit (bit 23) for a load/store instruction.
+     n        Control field (bits 16-22) for a load/store instruction.
+     v        Immediate operand in bits 16-23 of the instruction.
+              (used for trap numbers).
+     s        SA.  Special-purpose register number in bits 8-15
+              of the instruction.
+     u        UI--bit 7 of the instruction.
+     r        RND--bits 4-6 of the instruction.
+     d        FD--bits 2-3 of the instruction.
+     f        FS--bits 0-1 of the instruction.  */
+  char *args;
+};
+
+static struct am29k_opcode am29k_opcodes[] =
+{
+
+{ "add", 0x14, "c,a,b" },
+{ "add", 0x15, "c,a,i" },
+{ "addc", 0x1c, "c,a,b" },
+{ "addc", 0x1d, "c,a,i" },
+{ "addcs", 0x18, "c,a,b" },
+{ "addcs", 0x19, "c,a,i" },
+{ "addcu", 0x1a, "c,a,b" },
+{ "addcu", 0x1b, "c,a,i" },
+{ "adds", 0x10, "c,a,b" },
+{ "adds", 0x11, "c,a,i" },
+{ "addu", 0x12, "c,a,b" },
+{ "addu", 0x13, "c,a,i" },
+{ "and", 0x90, "c,a,b" },
+{ "and", 0x91, "c,a,i" },
+{ "andn", 0x9c, "c,a,b" },
+{ "andn", 0x9d, "c,a,i" },
+{ "aseq", 0x70, "v,a,b" },
+{ "aseq", 0x71, "v,a,i" },
+{ "asge", 0x5c, "v,a,b" },
+{ "asge", 0x5d, "v,a,i" },
+{ "asgeu", 0x5e, "v,a,b" },
+{ "asgeu", 0x5f, "v,a,i" },
+{ "asgt", 0x58, "v,a,b" },
+{ "asgt", 0x59, "v,a,i" },
+{ "asgtu", 0x5a, "v,a,b" },
+{ "asgtu", 0x5b, "v,a,i" },
+{ "asle", 0x54, "v,a,b" },
+{ "asle", 0x55, "v,a,i" },
+{ "asleu", 0x56, "v,a,b" },
+{ "asleu", 0x57, "v,a,i" },
+{ "aslt", 0x50, "v,a,b" },
+{ "aslt", 0x51, "v,a,i" },
+{ "asltu", 0x52, "v,a,b" },
+{ "asltu", 0x53, "v,a,i" },
+{ "asneq", 0x72, "v,a,b" },
+{ "asneq", 0x73, "v,a,i" },
+{ "call", 0xa8, "a,P" },
+{ "call", 0xa9, "a,A" },
+{ "calli", 0xc8, "a,b" },
+{ "class", 0xe6, "c,a,f" },
+{ "clz", 0x08, "c,b" },
+{ "clz", 0x09, "c,i" },
+{ "const", 0x03, "a,x" },
+{ "consth", 0x02, "a,h" },
+{ "consthz", 0x05, "a,h" },
+{ "constn", 0x01, "a,X" },
+{ "convert", 0xe4, "c,a,u,r,d,f" },
+{ "cpbyte", 0x2e, "c,a,b" },
+{ "cpbyte", 0x2f, "c,a,i" },
+{ "cpeq", 0x60, "c,a,b" },
+{ "cpeq", 0x61, "c,a,i" },
+{ "cpge", 0x4c, "c,a,b" },
+{ "cpge", 0x4d, "c,a,i" },
+{ "cpgeu", 0x4e, "c,a,b" },
+{ "cpgeu", 0x4f, "c,a,i" },
+{ "cpgt", 0x48, "c,a,b" },
+{ "cpgt", 0x49, "c,a,i" },
+{ "cpgtu", 0x4a, "c,a,b" },
+{ "cpgtu", 0x4b, "c,a,i" },
+{ "cple", 0x44, "c,a,b" },
+{ "cple", 0x45, "c,a,i" },
+{ "cpleu", 0x46, "c,a,b" },
+{ "cpleu", 0x47, "c,a,i" },
+{ "cplt", 0x40, "c,a,b" },
+{ "cplt", 0x41, "c,a,i" },
+{ "cpltu", 0x42, "c,a,b" },
+{ "cpltu", 0x43, "c,a,i" },
+{ "cpneq", 0x62, "c,a,b" },
+{ "cpneq", 0x63, "c,a,i" },
+{ "dadd", 0xf1, "c,a,b" },
+{ "ddiv", 0xf7, "c,a,b" },
+{ "deq", 0xeb, "c,a,b" },
+{ "dge", 0xef, "c,a,b" },
+{ "dgt", 0xed, "c,a,b" },
+{ "div", 0x6a, "c,a,b" },
+{ "div", 0x6b, "c,a,i" },
+{ "div0", 0x68, "c,b" },
+{ "div0", 0x69, "c,i" },
+{ "divide", 0xe1, "c,a,b" },
+{ "dividu", 0xe3, "c,a,b" },
+{ "divl", 0x6c, "c,a,b" },
+{ "divl", 0x6d, "c,a,i" },
+{ "divrem", 0x6e, "c,a,b" },
+{ "divrem", 0x6f, "c,a,i" },
+{ "dmac", 0xd9, "F,C,a,b" },
+{ "dmsm", 0xdb, "c,a,b" },
+{ "dmul", 0xf5, "c,a,b" },
+{ "dsub", 0xf3, "c,a,b" },
+{ "emulate", 0xd7, "v,a,b" },
+{ "exbyte", 0x0a, "c,a,b" },
+{ "exbyte", 0x0b, "c,a,i" },
+{ "exhw", 0x7c, "c,a,b" },
+{ "exhw", 0x7d, "c,a,i" },
+{ "exhws", 0x7e, "c,a" },
+{ "extract", 0x7a, "c,a,b" },
+{ "extract", 0x7b, "c,a,i" },
+{ "fadd", 0xf0, "c,a,b" },
+{ "fdiv", 0xf6, "c,a,b" },
+{ "fdmul", 0xf9, "c,a,b" },
+{ "feq", 0xea, "c,a,b" },
+{ "fge", 0xee, "c,a,b" },
+{ "fgt", 0xec, "c,a,b" },
+{ "fmac", 0xd8, "F,C,a,b" },
+{ "fmsm", 0xda, "c,a,b" },
+{ "fmul", 0xf4, "c,a,b" },
+{ "fsub", 0xf2, "c,a,b" },
+{ "halt", 0x89, "" },
+{ "inbyte", 0x0c, "c,a,b" },
+{ "inbyte", 0x0d, "c,a,i" },
+{ "inhw", 0x78, "c,a,b" },
+{ "inhw", 0x79, "c,a,i" },
+{ "inv", 0x9f, "" },
+{ "iret", 0x88, "" },
+{ "iretinv", 0x8c, "" },
+{ "jmp", 0xa0, "P" },
+{ "jmp", 0xa1, "A" },
+{ "jmpf", 0xa4, "a,P" },
+{ "jmpf", 0xa5, "a,A" },
+{ "jmpfdec", 0xb4, "a,P" },
+{ "jmpfdec", 0xb5, "a,A" },
+{ "jmpfi", 0xc4, "a,b" },
+{ "jmpi", 0xc0, "b" },
+{ "jmpt", 0xac, "a,P" },
+{ "jmpt", 0xad, "a,A" },
+{ "jmpti", 0xcc, "a,b" },
+{ "load", 0x16, "e,n,a,b" },
+{ "load", 0x17, "e,n,a,i" },
+{ "loadl", 0x06, "e,n,a,b" },
+{ "loadl", 0x07, "e,n,a,i" },
+{ "loadm", 0x36, "e,n,a,b" },
+{ "loadm", 0x37, "e,n,a,i" },
+{ "loadset", 0x26, "e,n,a,b" },
+{ "loadset", 0x27, "e,n,a,i" },
+{ "mfacc", 0xe9, "c,d,f" },
+{ "mfsr", 0xc6, "c,s" },
+{ "mftlb", 0xb6, "c,a" },
+{ "mtacc", 0xe8, "c,d,f" },
+{ "mtsr", 0xce, "s,b" },
+{ "mtsrim", 0x04, "s,x" },
+{ "mttlb", 0xbe, "a,b" },
+{ "mul", 0x64, "c,a,b" },
+{ "mul", 0x65, "c,a,i" },
+{ "mull", 0x66, "c,a,b" },
+{ "mull", 0x67, "c,a,i" },
+{ "multiplu", 0xe2, "c,a,b" },
+{ "multiply", 0xe0, "c,a,b" },
+{ "multm", 0xde, "c,a,b" },
+{ "multmu", 0xdf, "c,a,b" },
+{ "mulu", 0x74, "c,a,b" },
+{ "mulu", 0x75, "c,a,i" },
+{ "nand", 0x9a, "c,a,b" },
+{ "nand", 0x9b, "c,a,i" },
+{ "nor", 0x98, "c,a,b" },
+{ "nor", 0x99, "c,a,i" },
+{ "or", 0x92, "c,a,b" },
+{ "or", 0x93, "c,a,i" },
+{ "orn", 0xaa, "c,a,b" },
+{ "orn", 0xab, "c,a,i" },
+
+/* The description of "setip" in Chapter 8 ("instruction set") of the user's
+   manual claims that these are absolute register numbers.  But section
+   7.2.1 explains that they are not.  The latter is correct, so print
+   these normally ("lr0", "lr5", etc.).  */
+{ "setip", 0x9e, "c,a,b" },
+
+{ "sll", 0x80, "c,a,b" },
+{ "sll", 0x81, "c,a,i" },
+{ "sqrt", 0xe5, "c,a,f" },
+{ "sra", 0x86, "c,a,b" },
+{ "sra", 0x87, "c,a,i" },
+{ "srl", 0x82, "c,a,b" },
+{ "srl", 0x83, "c,a,i" },
+{ "store", 0x1e, "e,n,a,b" },
+{ "store", 0x1f, "e,n,a,i" },
+{ "storel", 0x0e, "e,n,a,b" },
+{ "storel", 0x0f, "e,n,a,i" },
+{ "storem", 0x3e, "e,n,a,b" },
+{ "storem", 0x3f, "e,n,a,i" },
+{ "sub", 0x24, "c,a,b" },
+{ "sub", 0x25, "c,a,i" },
+{ "subc", 0x2c, "c,a,b" },
+{ "subc", 0x2d, "c,a,i" },
+{ "subcs", 0x28, "c,a,b" },
+{ "subcs", 0x29, "c,a,i" },
+{ "subcu", 0x2a, "c,a,b" },
+{ "subcu", 0x2b, "c,a,i" },
+{ "subr", 0x34, "c,a,b" },
+{ "subr", 0x35, "c,a,i" },
+{ "subrc", 0x3c, "c,a,b" },
+{ "subrc", 0x3d, "c,a,i" },
+{ "subrcs", 0x38, "c,a,b" },
+{ "subrcs", 0x39, "c,a,i" },
+{ "subrcu", 0x3a, "c,a,b" },
+{ "subrcu", 0x3b, "c,a,i" },
+{ "subrs", 0x30, "c,a,b" },
+{ "subrs", 0x31, "c,a,i" },
+{ "subru", 0x32, "c,a,b" },
+{ "subru", 0x33, "c,a,i" },
+{ "subs", 0x20, "c,a,b" },
+{ "subs", 0x21, "c,a,i" },
+{ "subu", 0x22, "c,a,b" },
+{ "subu", 0x23, "c,a,i" },
+{ "xnor", 0x96, "c,a,b" },
+{ "xnor", 0x97, "c,a,i" },
+{ "xor", 0x94, "c,a,b" },
+{ "xor", 0x95, "c,a,i" }
+
+};
+
+#define NUM_OPCODES ((sizeof am29k_opcodes) / (sizeof am29k_opcodes[0]))
+
diff --git a/gdb/am29k-pinsn.c b/gdb/am29k-pinsn.c
new file mode 100644 (file)
index 0000000..c933629
--- /dev/null
@@ -0,0 +1,296 @@
+/* Instruction printing code for the AMD 29000
+   Copyright (C) 1990 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "target.h"
+#include "am29k-opcode.h"
+
+/* Print a symbolic representation of a general-purpose
+   register number NUM on STREAM.
+   NUM is a number as found in the instruction, not as found in
+   debugging symbols; it must be in the range 0-255.  */
+static void
+print_general (num, stream)
+     int num;
+     FILE *stream;
+{
+  if (num < 128)
+    fprintf_filtered (stream, "gr%d", num);
+  else
+    fprintf_filtered (stream, "lr%d", num - 128);
+}
+
+/* Like print_general but a special-purpose register.
+   
+   The mnemonics used by the AMD assembler are not quite the same
+   as the ones in the User's Manual.  We use the ones that the
+   assembler uses.  */
+static void
+print_special (num, stream)
+     int num;
+     FILE *stream;
+{
+  /* Register names of registers 0-SPEC0_NUM-1.  */
+  static char *spec0_names[] = {
+    "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
+    "pc0", "pc1", "pc2", "mmu", "lru"
+    };
+#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
+
+  /* Register names of registers 128-128+SPEC128_NUM-1.  */
+  static char *spec128_names[] = {
+    "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
+    };
+#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
+
+  /* Register names of registers 160-160+SPEC160_NUM-1.  */
+  static char *spec160_names[] = {
+    "fpe", "inte", "fps", "sr163", "exop"
+    };
+#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
+
+  if (num < SPEC0_NUM)
+    fprintf_filtered (stream, spec0_names[num]);
+  else if (num >= 128 && num < 128 + SPEC128_NUM)
+    fprintf_filtered (stream, spec128_names[num-128]);
+  else if (num >= 160 && num < 160 + SPEC160_NUM)
+    fprintf_filtered (stream, spec160_names[num-160]);
+  else
+    fprintf_filtered (stream, "sr%d", num);
+}
+
+/* Is an instruction with OPCODE a delayed branch?  */
+static int
+is_delayed_branch (opcode)
+     int opcode;
+{
+  return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
+         || opcode == 0xa4 || opcode == 0xa5
+         || opcode == 0xb4 || opcode == 0xb5
+         || opcode == 0xc4 || opcode == 0xc0
+         || opcode == 0xac || opcode == 0xad
+         || opcode == 0xcc);
+}
+
+/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}.
+   Note that the amd can be set up as either
+   big or little-endian (the tm file says which) and we can't assume
+   the host machine is the same.  */
+static void
+find_bytes (insn, insn0, insn8, insn16, insn24)
+     char *insn;
+     unsigned char *insn0;
+     unsigned char *insn8;
+     unsigned char *insn16;
+     unsigned char *insn24;
+{
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+  *insn24 = insn[0];
+  *insn16 = insn[1];
+  *insn8  = insn[2];
+  *insn0  = insn[3];
+#else /* Little-endian.  */
+  *insn24 = insn[3];
+  *insn16 = insn[2];
+  *insn8 = insn[1];
+  *insn0 = insn[0];
+#endif /* Little-endian.  */
+}
+
+/* Print one instruction from MEMADDR on STREAM.
+   Return the size of the instruction (always 4 on am29k).  */
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  /* The raw instruction.  */
+  char insn[4];
+
+  /* The four bytes of the instruction.  */
+  unsigned char insn24, insn16, insn8, insn0;
+
+  struct am29k_opcode *opcode;
+
+  read_memory (memaddr, &insn[0], 4);
+
+  find_bytes (insn, &insn0, &insn8, &insn16, &insn24);
+
+  /* The opcode is always in insn24.  */
+  for (opcode = &am29k_opcodes[0];
+       opcode < &am29k_opcodes[NUM_OPCODES];
+       ++opcode)
+    {
+      if (insn24 == opcode->opcode)
+       {
+         char *s;
+         
+         fprintf_filtered (stream, "%s ", opcode->name);
+         for (s = opcode->args; *s != '\0'; ++s)
+           {
+             switch (*s)
+               {
+               case 'a':
+                 print_general (insn8, stream);
+                 break;
+                 
+               case 'b':
+                 print_general (insn0, stream);
+                 break;
+
+               case 'c':
+                 print_general (insn16, stream);
+                 break;
+
+               case 'i':
+                 fprintf_filtered (stream, "%d", insn0);
+                 break;
+
+               case 'x':
+                 fprintf_filtered (stream, "%d", (insn16 << 8) + insn0);
+                 break;
+
+               case 'h':
+                 fprintf_filtered (stream, "0x%x",
+                                   (insn16 << 24) + (insn0 << 16));
+                 break;
+
+               case 'X':
+                 fprintf_filtered (stream, "%d",
+                                   ((insn16 << 8) + insn0) | 0xffff0000);
+                 break;
+
+               case 'P':
+                 /* This output looks just like absolute addressing, but
+                    maybe that's OK (it's what the GDB 68k and EBMON
+                    29k disassemblers do).  */
+                 /* All the shifting is to sign-extend it.  p*/
+                 print_address
+                   (memaddr +
+                    (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
+                    stream);
+                 break;
+
+               case 'A':
+                 print_address ((insn16 << 10) + (insn0 << 2), stream);
+                 break;
+
+               case 'e':
+                 fprintf_filtered (stream, "%d", insn16 >> 7);
+                 break;
+
+               case 'n':
+                 fprintf_filtered (stream, "0x%x", insn16 & 0x7f);
+                 break;
+
+               case 'v':
+                 fprintf_filtered (stream, "%#x", insn16);
+                 break;
+
+               case 's':
+                 print_special (insn8, stream);
+                 break;
+
+               case 'u':
+                 fprintf_filtered (stream, "%d", insn0 >> 7);
+                 break;
+
+               case 'r':
+                 fprintf_filtered (stream, "%d", (insn0 >> 4) & 7);
+                 break;
+
+               case 'd':
+                 fprintf_filtered (stream, "%d", (insn0 >> 2) & 3);
+                 break;
+
+               case 'f':
+                 fprintf_filtered (stream, "%d", insn0 & 3);
+                 break;
+
+               case 'F':
+                 fprintf_filtered (stream, "%d", (insn0 >> 18) & 15);
+                 break;
+
+               case 'C':
+                 fprintf_filtered (stream, "%d", (insn0 >> 16) & 3);
+                 break;
+
+               default:
+                 fprintf_filtered (stream, "%c", *s);
+               }
+           }
+
+         /* Now we look for a const,consth pair of instructions,
+            in which case we try to print the symbolic address.  */
+         if (insn24 == 2)  /* consth */
+           {
+             int errcode;
+             char prev_insn[4];
+             unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
+             
+             errcode = target_read_memory (memaddr - 4,
+                                           &prev_insn[0],
+                                           4);
+             if (errcode == 0)
+               {
+                 /* If it is a delayed branch, we need to look at the
+                    instruction before the delayed brach to handle
+                    things like
+                    
+                    const _foo
+                    call _printf
+                    consth _foo
+                    */
+                 find_bytes (prev_insn, &prev_insn0, &prev_insn8,
+                             &prev_insn16, &prev_insn24);
+                 if (is_delayed_branch (prev_insn24))
+                   {
+                     errcode = target_read_memory
+                       (memaddr - 8, &prev_insn[0], 4);
+                     find_bytes (prev_insn, &prev_insn0, &prev_insn8,
+                                 &prev_insn16, &prev_insn24);
+                   }
+               }
+                 
+             /* If there was a problem reading memory, then assume
+                the previous instruction was not const.  */
+             if (errcode == 0)
+               {
+                 /* Is it const to the same register?  */
+                 if (prev_insn24 == 3
+                     && prev_insn8 == insn8)
+                   {
+                     fprintf_filtered (stream, "\t; ");
+                     print_address (((insn16 << 24) + (insn0 << 16)
+                                     + (prev_insn16 << 8) + (prev_insn0)),
+                                    stream);
+                   }
+               }
+           }
+
+         return 4;
+       }
+    }
+  fprintf_filtered (stream, ".word %#8x",
+                   (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
+  return 4;
+}
diff --git a/gdb/am29k-tdep.c b/gdb/am29k-tdep.c
new file mode 100644 (file)
index 0000000..e58847b
--- /dev/null
@@ -0,0 +1,695 @@
+/* Target-machine dependent code for the AMD 29000
+   Copyright (C) 1990 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include <stdio.h>
+#include "frame.h"
+#include "value.h"
+#include "param.h"
+#include "symtab.h"
+#include "inferior.h"
+
+/* Structure to hold cached info about function prologues.  */
+struct prologue_info
+{
+  CORE_ADDR pc;                        /* First addr after fn prologue */
+  unsigned rsize, msize;       /* register stack frame size, mem stack ditto */
+  unsigned mfp_used : 1;       /* memory frame pointer used */
+  unsigned rsize_valid : 1;    /* Validity bits for the above */
+  unsigned msize_valid : 1;
+  unsigned mfp_valid : 1;
+};
+
+/* Examine the prologue of a function which starts at PC.  Return
+   the first addess past the prologue.  If MSIZE is non-NULL, then
+   set *MSIZE to the memory stack frame size.  If RSIZE is non-NULL,
+   then set *RSIZE to the register stack frame size (not including
+   incoming arguments and the return address & frame pointer stored
+   with them).  If no prologue is found, *RSIZE is set to zero.
+   If no prologue is found, or a prologue which doesn't involve
+   allocating a memory stack frame, then set *MSIZE to zero.
+
+   Note that both msize and rsize are in bytes.  This is not consistent
+   with the _User's Manual_ with respect to rsize, but it is much more
+   convenient.
+
+   If MFP_USED is non-NULL, *MFP_USED is set to nonzero if a memory
+   frame pointer is being used.  */
+CORE_ADDR
+examine_prologue (pc, rsize, msize, mfp_used)
+     CORE_ADDR pc;
+     unsigned *msize;
+     unsigned *rsize;
+     int *mfp_used;
+{
+  long insn;
+  CORE_ADDR p = pc;
+  int misc_index = find_pc_misc_function (pc);
+  struct prologue_info *mi = 0;
+
+  if (misc_index >= 0)
+    mi = (struct prologue_info *)misc_function_vector[misc_index].misc_info;
+
+  if (mi != 0)
+    {
+      int valid = 1;
+      if (rsize != NULL)
+       {
+         *rsize = mi->rsize;
+         valid &= mi->rsize_valid;
+       }
+      if (msize != NULL)
+       {
+         *msize = mi->msize;
+         valid &= mi->msize_valid;
+       }
+      if (mfp_used != NULL)
+       {
+         *mfp_used = mi->mfp_used;
+         valid &= mi->mfp_valid;
+       }
+      if (valid)
+       return mi->pc;
+    }
+
+  if (rsize != NULL)
+    *rsize = 0;
+  if (msize != NULL)
+    *msize = 0;
+  if (mfp_used != NULL)
+    *mfp_used = 0;
+  
+  /* Prologue must start with subtracting a constant from gr1.
+     Normally this is sub gr1,gr1,<rsize * 4>.  */
+  insn = read_memory_integer (p, 4);
+  if ((insn & 0xffffff00) != 0x25010100)
+    {
+      /* If the frame is large, instead of a single instruction it
+        might be a pair of instructions:
+        const <reg>, <rsize * 4>
+        sub gr1,gr1,<reg>
+        */
+      int reg;
+      /* Possible value for rsize.  */
+      unsigned int rsize0;
+      
+      if ((insn & 0xff000000) != 0x03000000)
+       {
+         p = pc;
+         goto done;
+       }
+      reg = (insn >> 8) & 0xff;
+      rsize0 = (((insn >> 8) & 0xff00) | (insn & 0xff));
+      p += 4;
+      insn = read_memory_integer (p, 4);
+      if ((insn & 0xffffff00) != 0x24010100
+         || (insn & 0xff) != reg)
+       {
+         p = pc;
+         goto done;
+       }
+      if (rsize != NULL)
+       *rsize = rsize0;
+    }
+  else
+    {
+      if (rsize != NULL)
+       *rsize = (insn & 0xff);
+    }
+  p += 4;
+
+  /* Next instruction must be asgeu V_SPILL,gr1,rab.  */
+  insn = read_memory_integer (p, 4);
+  if (insn != 0x5e40017e)
+    {
+      p = pc;
+      goto done;
+    }
+  p += 4;
+
+  /* Next instruction usually sets the frame pointer (lr1) by adding
+     <size * 4> from gr1.  However, this can (and high C does) be
+     deferred until anytime before the first function call.  So it is
+     OK if we don't see anything which sets lr1.  */
+  /* Normally this is just add lr1,gr1,<size * 4>.  */
+  insn = read_memory_integer (p, 4);
+  if ((insn & 0xffffff00) == 0x15810100)
+    p += 4;
+  else
+    {
+      /* However, for large frames it can be
+        const <reg>, <size *4>
+        add lr1,gr1,<reg>
+        */
+      int reg;
+      CORE_ADDR q;
+
+      if ((insn & 0xff000000) == 0x03000000)
+       {
+         reg = (insn >> 8) & 0xff;
+         q = p + 4;
+         insn = read_memory_integer (q, 4);
+         if ((insn & 0xffffff00) == 0x14810100
+             && (insn & 0xff) == reg)
+           p = q;
+       }
+    }
+
+  /* Next comes "add lr{<rsize-1>},msp,0", but only if a memory
+     frame pointer is in use.  We just check for add lr<anything>,msp,0;
+     we don't check this rsize against the first instruction, and
+     we don't check that the trace-back tag indicates a memory frame pointer
+     is in use.  
+
+     The recommended instruction is actually "sll lr<whatever>,msp,0". 
+     We check for that, too.  Originally Jim Kingdon's code seemed
+     to be looking for a "sub" instruction here, but the mask was set
+     up to lose all the time. */
+  insn = read_memory_integer (p, 4);
+  if (((insn & 0xff80ffff) == 0x15807d00)      /* add */
+   || ((insn & 0xff80ffff) == 0x81807d00) )    /* sll */
+    {
+      p += 4;
+      if (mfp_used != NULL)
+       *mfp_used = 1;
+    }
+
+  /* Next comes a subtraction from msp to allocate a memory frame,
+     but only if a memory frame is
+     being used.  We don't check msize against the trace-back tag.
+
+     Normally this is just
+     sub msp,msp,<msize>
+     */
+  insn = read_memory_integer (p, 4);
+  if ((insn & 0xffffff00) == 0x257d7d00)
+    {
+      p += 4;
+      if (msize != NULL)
+       *msize = insn & 0xff;
+    }
+  else
+    {
+      /* For large frames, instead of a single instruction it might
+        be
+
+        const <reg>, <msize>
+        consth <reg>, <msize>     ; optional
+        sub msp,msp,<reg>
+        */
+      int reg;
+      unsigned msize0;
+      CORE_ADDR q = p;
+
+      if ((insn & 0xff000000) == 0x03000000)
+       {
+         reg = (insn >> 8) & 0xff;
+         msize0 = ((insn >> 8) & 0xff00) | (insn & 0xff);
+         q += 4;
+         insn = read_memory_integer (q, 4);
+         /* Check for consth.  */
+         if ((insn & 0xff000000) == 0x02000000
+             && (insn & 0x0000ff00) == reg)
+           {
+             msize0 |= (insn << 8) & 0xff000000;
+             msize0 |= (insn << 16) & 0x00ff0000;
+             q += 4;
+             insn = read_memory_integer (q, 4);
+           }
+         /* Check for sub msp,msp,<reg>.  */
+         if ((insn & 0xffffff00) == 0x247d7d00
+             && (insn & 0xff) == reg)
+           {
+             p = q + 4;
+             if (msize != NULL)
+               *msize = msize0;
+           }
+       }
+    }
+
+ done:
+  if (misc_index >= 0)
+    {
+      if (mi == 0)
+       {
+         /* Add a new cache entry.  */
+         mi = (struct prologue_info *)xmalloc (sizeof (struct prologue_info));
+         misc_function_vector[misc_index].misc_info = (char *)mi;
+         mi->rsize_valid = 0;
+         mi->msize_valid = 0;
+         mi->mfp_valid = 0;
+       }
+      /* else, cache entry exists, but info is incomplete.  */
+      mi->pc = p;
+      if (rsize != NULL)
+       {
+         mi->rsize = *rsize;
+         mi->rsize_valid = 1;
+       }
+      if (msize != NULL)
+       {
+         mi->msize = *msize;
+         mi->msize_valid = 1;
+       }
+      if (mfp_used != NULL)
+       {
+         mi->mfp_used = *mfp_used;
+         mi->mfp_valid = 1;
+       }
+    }
+  return p;
+}
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+CORE_ADDR
+skip_prologue (pc)
+     CORE_ADDR pc;
+{
+  return examine_prologue (pc, (unsigned *)NULL, (unsigned *)NULL,
+                          (int *)NULL);
+}
+
+/* Initialize the frame.  In addition to setting "extra" frame info,
+   we also set ->frame because we use it in a nonstandard way, and ->pc
+   because we need to know it to get the other stuff.  See the diagram
+   of stacks and the frame cache in tm-29k.h for more detail.  */
+static void
+init_frame_info (innermost_frame, fci)
+     int innermost_frame;
+     struct frame_info *fci;
+{
+  CORE_ADDR p;
+  long insn;
+  unsigned rsize;
+  unsigned msize;
+  int mfp_used;
+  struct symbol *func;
+
+  p = fci->pc;
+
+  if (innermost_frame)
+    fci->frame = read_register (GR1_REGNUM);
+  else
+    fci->frame = fci->next_frame + fci->next->rsize;
+  
+#if CALL_DUMMY_LOCATION == ON_STACK
+  This wont work;
+#else
+  if (PC_IN_CALL_DUMMY (p, 0, 0))
+#endif
+    {
+      fci->rsize = DUMMY_FRAME_RSIZE;
+      /* This doesn't matter since we never try to get locals or args
+        from a dummy frame.  */
+      fci->msize = 0;
+      /* Dummy frames always use a memory frame pointer.  */
+      fci->saved_msp = 
+       read_register_stack_integer (fci->frame + DUMMY_FRAME_RSIZE - 4, 4);
+      return;
+    }
+    
+  func = find_pc_function (p);
+  if (func != NULL)
+    p = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+  else
+    {
+      /* Search backward to find the trace-back tag.  However,
+        do not trace back beyond the start of the text segment
+        (just as a sanity check to avoid going into never-never land).  */
+      while (p >= text_start
+            && ((insn = read_memory_integer (p, 4)) & 0xff000000) != 0)
+       p -= 4;
+      
+      if (p < text_start)
+       {
+         /* Couldn't find the trace-back tag.
+            Something strange is going on.  */
+         fci->saved_msp = 0;
+         fci->rsize = 0;
+         fci->msize = 0;
+         return;
+       }
+      else
+       /* Advance to the first word of the function, i.e. the word
+          after the trace-back tag.  */
+       p += 4;
+    }
+  /* We've found the start of the function.  Since High C interchanges
+     the meanings of bits 23 and 22 (as of Jul 90), and we
+     need to look at the prologue anyway to figure out
+     what rsize is, ignore the contents of the trace-back tag.  */
+  examine_prologue (p, &rsize, &msize, &mfp_used);
+  fci->rsize = rsize;
+  fci->msize = msize;
+  if (innermost_frame)
+    {
+      fci->saved_msp = read_register (MSP_REGNUM) + msize;
+    }
+  else
+    {
+      if (mfp_used)
+       fci->saved_msp =
+         read_register_stack_integer (fci->frame + rsize - 1, 4);
+      else
+       fci->saved_msp = fci->next->saved_msp + msize;
+    }
+}
+
+void
+init_extra_frame_info (fci)
+     struct frame_info *fci;
+{
+  if (fci->next == 0)
+    /* Assume innermost frame.  May produce strange results for "info frame"
+       but there isn't any way to tell the difference.  */
+    init_frame_info (1, fci);
+  else
+    /* We're in get_prev_frame_info.
+       Take care of everything in init_frame_pc.  */
+    ;
+}
+
+void
+init_frame_pc (fromleaf, fci)
+     int fromleaf;
+     struct frame_info *fci;
+{
+  fci->pc = (fromleaf ? SAVED_PC_AFTER_CALL (fci->next) :
+            fci->next ? FRAME_SAVED_PC (fci->next) : read_pc ());
+  init_frame_info (0, fci);
+}
+\f
+/* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their
+   offsets being relative to the memory stack pointer (high C) or
+   saved_msp (gcc).  */
+
+CORE_ADDR
+frame_locals_address (fi)
+     struct frame_info *fi;
+{
+  struct block *b = block_for_pc (fi->pc);
+  /* If compiled without -g, assume GCC.  */
+  if (b == NULL || BLOCK_GCC_COMPILED (b))
+    return fi->saved_msp;
+  else
+    return fi->saved_msp - fi->msize;
+}
+\f
+/* Routines for reading the register stack.  The caller gets to treat
+   the register stack as a uniform stack in memory, from address $gr1
+   straight through $rfb and beyond.  */
+
+/* Analogous to read_memory except the length is understood to be 4.
+   Also, myaddr can be NULL (meaning don't bother to read), and
+   if actual_mem_addr is non-NULL, store there the address that it
+   was fetched from (or if from a register the offset within
+   registers).  Set *LVAL to lval_memory or lval_register, depending
+   on where it came from.  */
+void
+read_register_stack (memaddr, myaddr, actual_mem_addr, lval)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     CORE_ADDR *actual_mem_addr;
+     enum lval_type *lval;
+{
+  long rfb = read_register (RFB_REGNUM);
+  long rsp = read_register (RSP_REGNUM);
+  if (memaddr < rfb)
+    {
+      /* It's in a register.  */
+      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
+      if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)
+       error ("Attempt to read register stack out of range.");
+      if (myaddr != NULL)
+       read_register_gen (regnum, myaddr);
+      if (lval != NULL)
+       *lval = lval_register;
+      if (actual_mem_addr != NULL)
+       *actual_mem_addr = REGISTER_BYTE (regnum);
+    }
+  else
+    {
+      /* It's in the memory portion of the register stack.  */
+      if (myaddr != NULL)
+       read_memory (memaddr, myaddr, 4);
+      if (lval != NULL)
+       *lval = lval_memory;
+      if (actual_mem_addr != NULL)
+       *actual_mem_addr == memaddr;
+    }
+}
+
+/* Analogous to read_memory_integer
+   except the length is understood to be 4.  */
+long
+read_register_stack_integer (memaddr, len)
+     CORE_ADDR memaddr;
+     int len;
+{
+  long buf;
+  read_register_stack (memaddr, &buf, NULL, NULL);
+  SWAP_TARGET_AND_HOST (&buf, 4);
+  return buf;
+}
+
+/* Copy 4 bytes from GDB memory at MYADDR into inferior memory
+   at MEMADDR and put the actual address written into in
+   *ACTUAL_MEM_ADDR.  */
+static void
+write_register_stack (memaddr, myaddr, actual_mem_addr)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     CORE_ADDR *actual_mem_addr;
+{
+  long rfb = read_register (RFB_REGNUM);
+  long rsp = read_register (RSP_REGNUM);
+  if (memaddr < rfb)
+    {
+      /* It's in a register.  */
+      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
+      if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)
+       error ("Attempt to read register stack out of range.");
+      if (myaddr != NULL)
+       write_register (regnum, *(long *)myaddr);
+      if (actual_mem_addr != NULL)
+       *actual_mem_addr = NULL;
+    }
+  else
+    {
+      /* It's in the memory portion of the register stack.  */
+      if (myaddr != NULL)
+       write_memory (memaddr, myaddr, 4);
+      if (actual_mem_addr != NULL)
+       *actual_mem_addr == memaddr;
+    }
+}
+\f
+/* Find register number REGNUM relative to FRAME and put its
+   (raw) contents in *RAW_BUFFER.  Set *OPTIMIZED if the variable
+   was optimized out (and thus can't be fetched).  If the variable
+   was fetched from memory, set *ADDRP to where it was fetched from,
+   otherwise it was fetched from a register.
+
+   The argument RAW_BUFFER must point to aligned memory.  */
+void
+get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp)
+     char *raw_buffer;
+     int *optimized;
+     CORE_ADDR *addrp;
+     FRAME frame;
+     int regnum;
+     enum lval_type *lvalp;
+{
+  struct frame_info *fi = get_frame_info (frame);
+  CORE_ADDR addr;
+  enum lval_type lval;
+
+  /* Once something has a register number, it doesn't get optimized out.  */
+  if (optimized != NULL)
+    *optimized = 0;
+  if (regnum == RSP_REGNUM)
+    {
+      if (raw_buffer != NULL)
+       *(CORE_ADDR *)raw_buffer = fi->frame;
+      if (lvalp != NULL)
+       *lvalp = not_lval;
+      return;
+    }
+  else if (regnum == PC_REGNUM)
+    {
+      if (raw_buffer != NULL)
+       *(CORE_ADDR *)raw_buffer = fi->pc;
+
+      /* Not sure we have to do this.  */
+      if (lvalp != NULL)
+       *lvalp = not_lval;
+
+      return;
+    }
+  else if (regnum == MSP_REGNUM)
+    {
+      if (raw_buffer != NULL)
+       {
+         if (fi->next != NULL)
+           *(CORE_ADDR *)raw_buffer = fi->next->saved_msp;
+         else
+           *(CORE_ADDR *)raw_buffer = read_register (MSP_REGNUM);
+       }
+      /* The value may have been computed, not fetched.  */
+      if (lvalp != NULL)
+       *lvalp = not_lval;
+      return;
+    }
+  else if (regnum < LR0_REGNUM || regnum >= LR0_REGNUM + 128)
+    {
+      /* These registers are not saved over procedure calls,
+        so just print out the current values.  */
+      if (raw_buffer != NULL)
+       *(CORE_ADDR *)raw_buffer = read_register (regnum);
+      if (lvalp != NULL)
+       *lvalp = lval_register;
+      if (addrp != NULL)
+       *addrp = REGISTER_BYTE (regnum);
+      return;
+    }
+      
+  addr = fi->frame + (regnum - LR0_REGNUM) * 4;
+  if (raw_buffer != NULL)
+    read_register_stack (addr, raw_buffer, &addr, &lval);
+  if (lvalp != NULL)
+    *lvalp = lval;
+  if (addrp != NULL)
+    *addrp = addr;
+}
+\f
+/* Discard from the stack the innermost frame,
+   restoring all saved registers.  */
+
+void
+pop_frame ()
+{
+  FRAME frame = get_current_frame ();                                        
+  struct frame_info *fi = get_frame_info (frame);                            
+  CORE_ADDR rfb = read_register (RFB_REGNUM);                                
+  CORE_ADDR gr1 = fi->frame + fi->rsize;
+  CORE_ADDR lr1;                                                             
+  CORE_ADDR ret_addr;
+  int i;
+
+  /* If popping a dummy frame, need to restore registers.  */
+  if (PC_IN_CALL_DUMMY (read_register (PC_REGNUM),
+                       read_register (SP_REGNUM),
+                       FRAME_FP (fi)))
+    {
+      for (i = 0; i < DUMMY_SAVE_SR128; ++i)
+       write_register
+         (SR_REGNUM (i + 128),
+          read_register (LR0_REGNUM + DUMMY_ARG / 4 + i));
+      for (i = 0; i < DUMMY_SAVE_GR96; ++i)
+       write_register
+         (GR96_REGNUM + i,
+          read_register (LR0_REGNUM + DUMMY_ARG / 4 + DUMMY_SAVE_SR128 + i));
+    }
+
+  /* Restore the memory stack pointer.  */
+  write_register (MSP_REGNUM, fi->saved_msp);                                
+  /* Restore the register stack pointer.  */                                 
+  write_register (GR1_REGNUM, gr1);
+  /* Check whether we need to fill registers.  */                            
+  lr1 = read_register (LR0_REGNUM + 1);                                      
+  if (lr1 > rfb)                                                             
+    {                                                                        
+      /* Fill.  */                                                           
+      int num_bytes = lr1 - rfb;
+      int i;                                                                 
+      long word;                                                             
+      write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes);  
+      write_register (RFB_REGNUM, lr1);                                      
+      for (i = 0; i < num_bytes; i += 4)                                     
+        {
+         /* Note: word is in host byte order.  */
+          word = read_memory_integer (rfb + i, 4);
+          write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word);                                          
+        }                                                                    
+    }
+  ret_addr = read_register (LR0_REGNUM);
+  write_register (PC_REGNUM, ret_addr);
+  write_register (NPC_REGNUM, ret_addr + 4);
+  flush_cached_frames ();                                                    
+  set_current_frame (create_new_frame (0, read_pc()));               
+}
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+void 
+push_dummy_frame ()
+{
+  long w;
+  CORE_ADDR rab, gr1;
+  CORE_ADDR msp = read_register (MSP_REGNUM);
+  int i;
+  
+  /* Save the PC.  */
+  write_register (LR0_REGNUM, read_register (PC_REGNUM));
+
+  /* Allocate the new frame.  */
+  gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE;
+  write_register (GR1_REGNUM, gr1);
+
+  rab = read_register (RAB_REGNUM);
+  if (gr1 < rab)
+    {
+      /* We need to spill registers.  */
+      int num_bytes = rab - gr1;
+      CORE_ADDR rfb = read_register (RFB_REGNUM);
+      int i;
+      long word;
+
+      write_register (RFB_REGNUM, rfb - num_bytes);
+      write_register (RAB_REGNUM, gr1);
+      for (i = 0; i < num_bytes; i += 4)
+       {
+         /* Note:  word is in target byte order.  */
+         read_register_gen (LR0_REGNUM + i / 4, &word, 4);
+         write_memory (rfb - num_bytes + i, &word, 4);
+       }
+    }
+
+  /* There are no arguments in to the dummy frame, so we don't need
+     more than rsize plus the return address and lr1.  */
+  write_register (LR0_REGNUM + 1, gr1 + DUMMY_FRAME_RSIZE + 2 * 4);
+
+  /* Set the memory frame pointer.  */
+  write_register (LR0_REGNUM + DUMMY_FRAME_RSIZE / 4 - 1, msp);
+
+  /* Allocate arg_slop.  */
+  write_register (MSP_REGNUM, msp - 16 * 4);
+
+  /* Save registers.  */
+  for (i = 0; i < DUMMY_SAVE_SR128; ++i)
+    write_register (LR0_REGNUM + DUMMY_ARG / 4 + i,
+                   read_register (SR_REGNUM (i + 128)));
+  for (i = 0; i < DUMMY_SAVE_GR96; ++i)
+    write_register (LR0_REGNUM + DUMMY_ARG / 4 + DUMMY_SAVE_SR128 + i,
+                   read_register (GR96_REGNUM + i));
+}
diff --git a/gdb/ansidecl.h b/gdb/ansidecl.h
new file mode 100755 (executable)
index 0000000..9e8f390
--- /dev/null
@@ -0,0 +1,93 @@
+/* Copyright (C) 1989 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the GNU C Library; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+       Macros
+               PTR             - Generic pointer type
+               LONG_DOUBLE     - `long double' type
+               CONST           - `const' keyword
+               VOLATILE        - `volatile' keyword
+               SIGNED          - `signed' keyword
+               PTRCONST        - Generic const pointer (void *const)
+
+       EXFUN(name, prototype)          - declare external function NAME
+                                         with prototype PROTOTYPE
+       DEFUN(name, arglist, args)      - define function NAME with
+                                         args ARGLIST of types in ARGS
+       DEFUN_VOID(name)                - define function NAME with no args
+       AND                             - argument separator for ARGS
+       NOARGS                          - null arglist
+       DOTS                            - `...' in args
+
+    For example:
+       extern int EXFUN(printf, (CONST char *format DOTS));
+       int DEFUN(fprintf, (stream, format),
+                 FILE *stream AND CONST char *format DOTS) { ... }
+       void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef        _ANSIDECL_H
+
+#define        _ANSIDECL_H     1
+
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+
+#ifdef __STDC__
+
+#define        PTR             void *
+#define        PTRCONST        void *CONST
+#define        LONG_DOUBLE     long double
+
+#define        AND             ,
+#define        NOARGS          void
+#define        CONST           const
+#define        VOLATILE        volatile
+#define        SIGNED          signed
+#define        DOTS            , ...
+
+#define        EXFUN(name, proto)              name proto
+#define        DEFUN(name, arglist, args)      name(args)
+#define        DEFUN_VOID(name)                name(NOARGS)
+
+#else  /* Not ANSI C.  */
+
+#define        PTR             char *
+#define        PTRCONST        PTR
+#define        LONG_DOUBLE     double
+
+#define        AND             ;
+#define        NOARGS
+#define        CONST
+#define        VOLATILE
+#define        SIGNED
+#define        DOTS
+
+#define        EXFUN(name, proto)              name()
+#define        DEFUN(name, arglist, args)      name arglist args;
+#define        DEFUN_VOID(name)                name()
+
+#endif /* ANSI C.  */
+
+
+#endif /* ansidecl.h   */
diff --git a/gdb/arm-convert.s b/gdb/arm-convert.s
new file mode 100644 (file)
index 0000000..416132b
--- /dev/null
@@ -0,0 +1,16 @@
+       .text
+       .global _convert_from_extended
+
+_convert_from_extended:
+
+       ldfe    f0,[a1]
+       stfd    f0,[a2]
+       movs    pc,lr
+
+       .global _convert_to_extended
+
+_convert_to_extended:
+
+       ldfd    f0,[a1]
+       stfe    f0,[a2]
+       movs    pc,lr
diff --git a/gdb/arm-pinsn.c b/gdb/arm-pinsn.c
new file mode 100644 (file)
index 0000000..2da8fdc
--- /dev/null
@@ -0,0 +1,271 @@
+/* Print ARM instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "arm-opcode.h"
+
+extern char *reg_names[];
+
+static char *shift_names[] = {
+    "lsl", "lsr", "asr", "ror",
+};
+
+static char *cond_names[] = {
+       "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
+       "hi", "ls", "ge", "lt", "gt", "le", "", "nv"
+};
+
+static char float_precision[] = "sdep";
+static char float_rounding[] = " pmz";
+static float float_immed[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0.5, 10.0 };
+
+static void print_ldr_str_offset();
+static void print_ldc_stc_offset();
+static long immediate_value();
+\f
+/* Print the ARM instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+    unsigned long ins;
+    register struct opcode *op;
+    register char *p;
+    register int i, c;
+    int s, e, val;
+
+    ins = read_memory_integer(memaddr, 4);
+    for (i = 0, op = opcodes; i < N_OPCODES; i++, op++)
+       if ((ins & op->mask) == op->value) break;
+    assert(i != N_OPCODES);
+    
+    for (p = op->assembler; *p;) {
+       c = *p++;
+       if (c == '%') {
+           s = e = 0;
+           while (isdigit(*p))
+               s = s*10 + (*p++ - '0');
+           if (*p == '-') {
+               p++;
+               while (isdigit(*p))
+                   e = e*10 + (*p++ - '0');
+           } else
+               e = s;
+           assert(s >= 0 && s <= 31 && e >= 0 && e <= 31);
+           val = (ins >> s) & ((1 << (e + 1 - s)) - 1);
+           switch (*p++) {
+           case '%' :
+               putc('%', stream);
+               break;
+           case 'd' :
+               fprintf(stream, "%d", val);
+               break;
+           case 'x' :
+               fprintf(stream, "%x", val);
+               break;
+           case 'r' :
+               assert(val >= 0 && val <= 15);
+               fprintf(stream, "%s", reg_names[val]);
+               break;
+           case 'c' :
+               fprintf(stream, "%s", cond_names[ins >> 28]);
+               break;
+           case '\'' :
+               assert(*p);
+               c = *p++;
+               if (val)
+                   putc(c, stream);
+               break;
+           case '`' :
+               assert(*p);
+               c = *p++;
+               if (!val)
+                   putc(c, stream);
+               break;
+           case '?' :
+               assert(*p);
+               c = *p++;
+               assert(*p);
+               if (val)
+                   p++;
+               else
+                   c = *p++;
+               putc(c, stream);
+               break;
+           case 'p' :
+               if (((ins >> 12) & 0xf) == 0xf)
+                   putc('p', stream);
+               break;
+           case 'o' :
+               if (ins & (1<<25)) {
+                   int immed = immediate_value(ins & 0xfff);
+                   fprintf (stream, "#%d (0x%x)", immed, immed);
+               } else {
+                   int operand2 = ins & 0xfff;
+                   /* in operand2 :
+                      bits 0-3 are the base register
+                      bits 5-6 are the shift (0=lsl, 1=lsr, 2=asr, 3=ror)
+                      if bit 4 is zero then bits 7-11 are an immediate shift count
+                      else bit 7 must be zero and bits 8-11 are the register
+                      to be used as a shift count.
+                      Note: no shift at all is encoded as "reg lsl #0" */
+                   fprintf (stream, "%s", reg_names[operand2 & 0xf]);
+                   if (operand2 & 0xff0) {
+                       /* ror #0 is really rrx (rotate right extend) */
+                       if ((operand2 & 0xff0) == 0x060)
+                           fprintf (stream, ", rrx");
+                       else {
+                           fprintf (stream, ", %s ",
+                                    shift_names[(operand2 >> 5) & 3]);
+                           if (operand2 & (1<<4)) /* register shift */
+                               fprintf (stream, "%s",
+                                        reg_names[operand2 >> 8]);
+                           else        /* immediate shift */
+                               fprintf (stream, "#%d",
+                                        operand2 >> 7);
+                       }
+                   }
+               }
+               break;
+           case 'a' :
+               fprintf (stream, "[%s", reg_names[(ins >> 16) & 0xf]);
+               if (ins & (1<<24)) {
+                   fprintf (stream, ", ");
+                   print_ldr_str_offset (ins, stream);
+                   putc (']', stream);
+                   if (ins & (1<<21)) putc('!', stream);
+                   /* If it is a pc relative load, then it is probably
+                      a constant so print it */
+                   if (((ins >> 16) & 0xf) == 15 &&
+                       (ins & (1<<25)) == 0 &&
+                       (ins & (1<<20))) {
+                       int addr = memaddr + 8 +
+                           (ins & 0xfff) * ((ins & (1<<23)) ? 1 : -1);
+                       fprintf (stream, " (contents=");
+                       print_address (read_memory_integer(addr, 4), stream);
+                       fprintf (stream, ")");
+                   }
+               } else {
+                   fprintf (stream, "]," );
+                   print_ldr_str_offset (ins, stream);
+               }
+               break;
+           case 'b' :
+               print_address (memaddr + 8 + (((int)ins << 8) >> 6), stream);
+               break;
+           case 'A' :
+               fprintf (stream, "[%s", reg_names[(ins >> 16) & 0xf]);
+               if (ins & (1<<24)) {
+                   fprintf (stream, ", ");
+                   print_ldc_stc_offset (ins, stream);
+                   putc(']', stream);
+                   if (ins & (1<<21))
+                       putc('!', stream);
+               } else {
+                   fprintf (stream, "], ");
+                   print_ldc_stc_offset (ins, stream);
+               }
+               break;
+           case 'm' :
+               {
+                   int regnum, first = 1;
+                   putc('{', stream);
+                   for (regnum = 0; regnum < 16; regnum++)
+                       if (ins & (1<<regnum)) {
+                           if (!first)
+                               putc (',', stream);
+                           first = 0;
+                           fprintf (stream, "%s", reg_names[regnum]);
+                       }
+                   putc('}', stream);
+               }
+               break;
+           case 'P' :
+               val = ((ins >> 18) & 2) | ((ins >> 7) & 1);
+               putc(float_precision[val], stream);
+               break;
+           case 'Q' :
+               val = ((ins >> 21) & 2) | ((ins >> 15) & 1);
+               putc(float_precision[val], stream);
+               break;
+           case 'R' :
+               val = ((ins >> 5) & 3);
+               if (val) putc(float_rounding[val], stream);
+               break;
+           case 'f' :
+               assert(val >= 0 && val <= 15);
+               if (val > 7)
+                   fprintf (stream, "#%3.1f", float_immed[val - 8]);
+               else
+                   fprintf (stream, "f%d", val);
+               break;
+           default:
+               abort();
+           }
+       } else
+           putc(c, stream);
+    }
+    return 4;
+}
+
+static long
+immediate_value(operand)
+int operand;
+{
+    int val = operand & 0xff;
+    int shift = 2*(operand >> 8);
+    /* immediate value is (val ror shift) */
+    return (val >> shift) | (val << (32 - shift));
+}
+
+static void
+print_ldr_str_offset(ins, stream)
+unsigned long ins;
+FILE *stream;
+{
+    if ((ins & (1<<25)) == 0)
+       fprintf (stream, "#%d",
+                (ins & 0xfff) * ((ins & (1<<23)) ? 1 : -1));
+    else {
+       fprintf (stream, "%s%s", reg_names[ins & 0xf],
+                (ins & (1<<23)) ? "" : "-");
+       if (ins & 0xff0)
+           fprintf (stream, ", %s #%d",
+                    shift_names[(ins >> 5) & 3],
+                    (ins >> 7) & 0x1f);
+    }
+}
+
+static void
+print_ldc_stc_offset(ins, stream)
+unsigned long ins;
+FILE *stream;
+{
+    fprintf (stream, "#%d",
+            4 * (ins & 0xff) * ((ins & (1<<23)) ? 1 : -1));
+}
diff --git a/gdb/arm-xdep.c b/gdb/arm-xdep.c
new file mode 100644 (file)
index 0000000..b397974
--- /dev/null
@@ -0,0 +1,274 @@
+/* Acorn Risc Machine host machine support.
+   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "arm-opcode.h"
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#define N_TXTADDR(hdr) 0x8000
+#define N_DATADDR(hdr) (hdr.a_text + 0x8000)
+
+#include "gdbcore.h"
+
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+  register int regno;
+  register unsigned int regaddr;
+  char buf[MAX_REGISTER_RAW_SIZE];
+  register int i;
+
+  struct user u;
+  unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
+  offset = ptrace (PT_READ_U, inferior_pid, offset, 0) - KERNEL_U_ADDR;
+
+  registers_fetched ();
+  
+  for (regno = 0; regno < 16; regno++)
+    {
+      regaddr = offset + regno * 4;
+      *(int *)&buf[0] = ptrace (PT_READ_U, inferior_pid, regaddr, 0);
+      if (regno == PC_REGNUM)
+         *(int *)&buf[0] = GET_PC_PART(*(int *)&buf[0]);
+      supply_register (regno, buf);
+    }
+  *(int *)&buf[0] = ptrace (PT_READ_U, inferior_pid, offset + PC*4);
+  supply_register (PS_REGNUM, buf); /* set virtual register ps same as pc */
+
+  /* read the floating point registers */
+  offset = (char *) &u.u_fp_regs - (char *)&u;
+  *(int *)buf = ptrace (PT_READ_U, inferior_pid, offset, 0);
+  supply_register (FPS_REGNUM, buf);
+  for (regno = 16; regno < 24; regno++) {
+      regaddr = offset + 4 + 12 * (regno - 16);
+      for (i = 0; i < 12; i += sizeof(int))
+         *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid, regaddr + i, 0);
+      supply_register (regno, buf);
+  }
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  register unsigned int regaddr;
+  char buf[80];
+
+  struct user u;
+  unsigned long value;
+  unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
+  offset = ptrace (PT_READ_U, inferior_pid, offset, 0) - KERNEL_U_ADDR;
+
+  if (regno >= 0) {
+      if (regno >= 16) return;
+      regaddr = offset + 4 * regno;
+      errno = 0;
+      value = read_register(regno);
+      if (regno == PC_REGNUM)
+         value = SET_PC_PART(read_register (PS_REGNUM), value);
+      ptrace (PT_WRITE_U, inferior_pid, regaddr, value);
+      if (errno != 0)
+       {
+         sprintf (buf, "writing register number %d", regno);
+         perror_with_name (buf);
+       }
+    }
+  else for (regno = 0; regno < 15; regno++)
+    {
+      regaddr = offset + regno * 4;
+      errno = 0;
+      value = read_register(regno);
+      if (regno == PC_REGNUM)
+         value = SET_PC_PART(read_register (PS_REGNUM), value);
+      ptrace (6, inferior_pid, regaddr, value);
+      if (errno != 0)
+       {
+         sprintf (buf, "writing all regs, number %d", regno);
+         perror_with_name (buf);
+       }
+    }
+}
+\f
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+/* Structure to describe the chain of shared libraries used
+   by the execfile.
+   e.g. prog shares Xt which shares X11 which shares c. */
+
+struct shared_library {
+    struct exec_header header;
+    char name[SHLIBLEN];
+    CORE_ADDR text_start;      /* CORE_ADDR of 1st byte of text, this file */
+    long data_offset;          /* offset of data section in file */
+    int chan;                  /* file descriptor for the file */
+    struct shared_library *shares; /* library this one shares */
+};
+static struct shared_library *shlib = 0;
+
+/* Hook for `exec_file_command' command to call.  */
+
+extern void (*exec_file_display_hook) ();
+   
+static CORE_ADDR unshared_text_start;
+
+/* extended header from exec file (for shared library info) */
+
+static struct exec_header exec_header;
+\f
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct user u;
+
+       unsigned int reg_offset, fp_reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name ("Not a core file: reading upage");
+       if (val != sizeof u)
+         error ("Not a core file: could only read %d bytes", val);
+
+       /* We are depending on exec_file_command having been called
+          previously to set exec_data_start.  Since the executable
+          and the core file share the same text segment, the address
+          of the data segment will be the same in both.  */
+       data_start = exec_data_start;
+
+       data_end = data_start + NBPG * u.u_dsize;
+       stack_start = stack_end - NBPG * u.u_ssize;
+       data_offset = NBPG * UPAGES;
+       stack_offset = NBPG * (UPAGES + u.u_dsize);
+
+       /* Some machines put an absolute address in here and some put
+          the offset in the upage of the regs.  */
+       reg_offset = (int) u.u_ar0;
+       if (reg_offset > NBPG * UPAGES)
+         reg_offset -= KERNEL_U_ADDR;
+       fp_reg_offset = (char *) &u.u_fp_regs - (char *)&u;
+
+       /* I don't know where to find this info.
+          So, for now, mark it as not available.  */
+       N_SET_MAGIC (core_aouthdr, 0);
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < NUM_REGS; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             if (regno < 16)
+                 val = lseek (corechan, reg_offset + 4 * regno, 0);
+             else if (regno < 24)
+                 val = lseek (corechan, fp_reg_offset + 4 + 12*(regno - 24), 0);
+             else if (regno == 24)
+                 val = lseek (corechan, fp_reg_offset, 0);
+             else if (regno == 25)
+                 val = lseek (corechan, reg_offset + 4 * PC, 0);
+             if (val < 0
+                 || (val = myread (corechan, buf, sizeof buf)) < 0)
+               {
+                 char * buffer = (char *) alloca (strlen (reg_names[regno])
+                                                  + 30);
+                 strcpy (buffer, "Reading register ");
+                 strcat (buffer, reg_names[regno]);
+                                                  
+                 perror_with_name (buffer);
+               }
+
+             if (regno == PC_REGNUM)
+                 *(int *)buf = GET_PC_PART(*(int *)buf);
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
diff --git a/gdb/command.c b/gdb/command.c
new file mode 100644 (file)
index 0000000..0b541a7
--- /dev/null
@@ -0,0 +1,1150 @@
+/* Library for reading command lines and decoding commands.
+   Copyright (C) 1986, 1989, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "command.h"
+#include "symtab.h"
+#include "value.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+extern char *getenv ();
+
+/* Add element named NAME to command list *LIST.
+   FUN should be the function to execute the command;
+   it will get a character string as argument, with leading
+   and trailing blanks already eliminated.
+
+   DOC is a documentation string for the command.
+   Its first line should be a complete sentence.
+   It should start with ? for a command that is an abbreviation
+   or with * for a command that most users don't need to know about.  */
+
+struct cmd_list_element *
+add_cmd (name, class, fun, doc, list)
+     char *name;
+     enum command_class class;
+     void (*fun) ();
+     char *doc;
+     struct cmd_list_element **list;
+{
+  register struct cmd_list_element *c
+    = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
+
+  delete_cmd (name, list);
+  c->next = *list;
+  c->name = name;
+  c->class = class;
+  c->function = fun;
+  c->doc = doc;
+  c->prefixlist = 0;
+  c->prefixname = (char *)NULL;
+  c->allow_unknown = 0;
+  c->abbrev_flag = 0;
+  c->aux = 0;
+  c->type = not_set_cmd;
+  c->completer = make_symbol_completion_list;
+  c->var = 0;
+  c->var_type = var_boolean;
+  c->user_commands = 0;
+  *list = c;
+  return c;
+}
+
+/* Same as above, except that the abbrev_flag is set. */
+
+struct cmd_list_element *
+add_abbrev_cmd (name, class, fun, doc, list)
+     char *name;
+     enum command_class class;
+     void (*fun) ();
+     char *doc;
+     struct cmd_list_element **list;
+{
+  register struct cmd_list_element *c
+    = add_cmd (name, class, fun, doc, list);
+
+  c->abbrev_flag = 1;
+  return c;
+}
+
+struct cmd_list_element *
+add_alias_cmd (name, oldname, class, abbrev_flag, list)
+     char *name;
+     char *oldname;
+     enum command_class class;
+     int abbrev_flag;
+     struct cmd_list_element **list;
+{
+  /* Must do this since lookup_cmd tries to side-effect its first arg */
+  char *copied_name;
+  register struct cmd_list_element *old;
+  register struct cmd_list_element *c;
+  copied_name = (char *) alloca (strlen (oldname) + 1);
+  strcpy (copied_name, oldname);
+  old  = lookup_cmd (&copied_name, *list, "", 1, 1);
+
+  if (old == 0)
+    {
+      delete_cmd (name, list);
+      return 0;
+    }
+
+  c = add_cmd (name, class, old->function, old->doc, list);
+  c->prefixlist = old->prefixlist;
+  c->prefixname = old->prefixname;
+  c->allow_unknown = old->allow_unknown;
+  c->abbrev_flag = abbrev_flag;
+  c->aux = old->aux;
+  return c;
+}
+
+/* Like add_cmd but adds an element for a command prefix:
+   a name that should be followed by a subcommand to be looked up
+   in another command list.  PREFIXLIST should be the address
+   of the variable containing that list.  */
+
+struct cmd_list_element *
+add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
+               allow_unknown, list)
+     char *name;
+     enum command_class class;
+     void (*fun) ();
+     char *doc;
+     struct cmd_list_element **prefixlist;
+     char *prefixname;
+     int allow_unknown;
+     struct cmd_list_element **list;
+{
+  register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
+  c->prefixlist = prefixlist;
+  c->prefixname = prefixname;
+  c->allow_unknown = allow_unknown;
+  return c;
+}
+
+/* Like add_prefix_cmd butsets the abbrev_flag on the new command. */
+   
+struct cmd_list_element *
+add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
+               allow_unknown, list)
+     char *name;
+     enum command_class class;
+     void (*fun) ();
+     char *doc;
+     struct cmd_list_element **prefixlist;
+     char *prefixname;
+     int allow_unknown;
+     struct cmd_list_element **list;
+{
+  register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
+  c->prefixlist = prefixlist;
+  c->prefixname = prefixname;
+  c->allow_unknown = allow_unknown;
+  c->abbrev_flag = 1;
+  return c;
+}
+
+void
+not_just_help_class_command (args, from_tty, c)
+     char *args;
+     int from_tty;
+     struct cmd_list_element *c;
+{
+}
+
+/* Add element named NAME to command list LIST (the list for set
+   or some sublist thereof).
+   CLASS is as in add_cmd.
+   VAR_TYPE is the kind of thing we are setting.
+   VAR is address of the variable being controlled by this command.
+   DOC is the documentation string.  */
+struct cmd_list_element *
+add_set_cmd (name, class, var_type, var, doc, list)
+     char *name;
+     enum command_class class;
+     var_types var_type;
+     char *var;
+     char *doc;
+     struct cmd_list_element **list;
+{
+  /* For set/show, we have to call do_setshow_command
+     differently than an ordinary function (take commandlist as
+     well as arg), so the function field isn't helpful.  However,
+     function == NULL means that it's a help class, so set the function
+     to not_just_help_class_command.  */
+  struct cmd_list_element *c
+    = add_cmd (name, class, not_just_help_class_command, doc, list);
+
+  c->type = set_cmd;
+  c->var_type = var_type;
+  c->var = var;
+  return c;
+}
+
+/* Where SETCMD has already been added, add the corresponding show
+   command to LIST and return a pointer to it.  */
+struct cmd_list_element *
+add_show_from_set (setcmd, list)
+     struct cmd_list_element *setcmd;
+     struct cmd_list_element **list;
+{
+  struct cmd_list_element *showcmd =
+    (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
+
+  bcopy (setcmd, showcmd, sizeof (struct cmd_list_element));
+  delete_cmd (showcmd->name, list);
+  showcmd->type = show_cmd;
+  
+  /* Replace "set " at start of docstring with "show ".  */
+  if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e'
+      && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ')
+    showcmd->doc = concat ("Show ", setcmd->doc + 4, "");
+  else
+    fprintf (stderr, "GDB internal error: Bad docstring for set command\n");
+  
+  showcmd->next = *list;
+  *list = showcmd;
+  return showcmd;
+}
+
+/* Remove the command named NAME from the command list.  */
+
+void
+delete_cmd (name, list)
+     char *name;
+     struct cmd_list_element **list;
+{
+  register struct cmd_list_element *c;
+  struct cmd_list_element *p;
+
+  while (*list && !strcmp ((*list)->name, name))
+    {
+      p = (*list)->next;
+      free (*list);
+      *list = p;
+    }
+
+  if (*list)
+    for (c = *list; c->next;)
+      {
+       if (!strcmp (c->next->name, name))
+         {
+           p = c->next->next;
+           free (c->next);
+           c->next = p;
+         }
+       else
+         c = c->next;
+      }
+}
+
+void help_cmd (), help_list (), help_cmd_list ();
+
+/* This command really has to deal with two things:
+ *     1) I want documentation on *this string* (usually called by
+ * "help commandname").
+ *     2) I want documentation on *this list* (usually called by
+ * giving a command that requires subcommands.  Also called by saying
+ * just "help".)
+ *
+ *   I am going to split this into two seperate comamnds, help_cmd and
+ * help_list. 
+ */
+
+void
+help_cmd (command, stream)
+     char *command;
+     FILE *stream;
+{
+  struct cmd_list_element *c;
+  extern struct cmd_list_element *cmdlist;
+
+  if (!command)
+    {
+      help_list (cmdlist, "", all_classes, stream);
+      return;
+    }
+
+  c = lookup_cmd (&command, cmdlist, "", 0, 0);
+
+  if (c == 0)
+    return;
+
+  /* There are three cases here.
+     If c->prefixlist is nonzero, we have a prefix command.
+     Print its documentation, then list its subcommands.
+     
+     If c->function is nonzero, we really have a command.
+     Print its documentation and return.
+     
+     If c->function is zero, we have a class name.
+     Print its documentation (as if it were a command)
+     and then set class to the number of this class
+     so that the commands in the class will be listed.  */
+
+  fputs_filtered (c->doc, stream);
+  fputs_filtered ("\n", stream);
+
+  if (c->prefixlist == 0 && c->function != 0)
+    return;
+  fprintf_filtered (stream, "\n");
+
+  /* If this is a prefix command, print it's subcommands */
+  if (c->prefixlist)
+    help_list (*c->prefixlist, c->prefixname, all_commands, stream);
+
+  /* If this is a class name, print all of the commands in the class */
+  if (c->function == 0)
+    help_list (cmdlist, "", c->class, stream);
+}
+
+/*
+ * Get a specific kind of help on a command list.
+ *
+ * LIST is the list.
+ * CMDTYPE is the prefix to use in the title string.
+ * CLASS is the class with which to list the nodes of this list (see
+ * documentation for help_cmd_list below),  As usual, ALL_COMMANDS for
+ * everything, ALL_CLASSES for just classes, and non-negative for only things
+ * in a specific class.
+ * and STREAM is the output stream on which to print things.
+ * If you call this routine with a class >= 0, it recurses.
+ */
+void
+help_list (list, cmdtype, class, stream)
+     struct cmd_list_element *list;
+     char *cmdtype;
+     enum command_class class;
+     FILE *stream;
+{
+  int len;
+  char *cmdtype1, *cmdtype2;
+  
+  /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub"  */
+  len = strlen (cmdtype);
+  cmdtype1 = (char *) alloca (len + 1);
+  cmdtype1[0] = 0;
+  cmdtype2 = (char *) alloca (len + 4);
+  cmdtype2[0] = 0;
+  if (len)
+    {
+      cmdtype1[0] = ' ';
+      strncpy (cmdtype1 + 1, cmdtype, len - 1);
+      cmdtype1[len] = 0;
+      strncpy (cmdtype2, cmdtype, len - 1);
+      strcpy (cmdtype2 + len - 1, " sub");
+    }
+
+  if (class == all_classes)
+    fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
+  else
+    fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
+
+  help_cmd_list (list, class, cmdtype, (int)class >= 0, stream);
+
+  if (class == all_classes)
+    fprintf_filtered (stream, "\n\
+Type \"help%s\" followed by a class name for a list of commands in that class.",
+            cmdtype1);
+
+  fprintf_filtered (stream, "\n\
+Type \"help%s\" followed by %scommand name for full documentation.\n\
+Command name abbreviations are allowed if unambiguous.\n",
+          cmdtype1, cmdtype2);
+}
+     
+/* Print only the first line of STR on STREAM.  */
+static void
+print_doc_line (stream, str)
+     FILE *stream;
+     char *str;
+{
+  static char *line_buffer = 0;
+  static int line_size;
+  register char *p;
+
+  if (!line_buffer)
+    {
+      line_size = 80;
+      line_buffer = (char *) xmalloc (line_size);
+    }
+
+  p = str;
+  while (*p && *p != '\n' && *p != '.' && *p != ',')
+    p++;
+  if (p - str > line_size - 1)
+    {
+      line_size = p - str + 1;
+      free (line_buffer);
+      line_buffer = (char *) xmalloc (line_size);
+    }
+  strncpy (line_buffer, str, p - str);
+  line_buffer[p - str] = '\0';
+  if (islower (line_buffer[0]))
+    line_buffer[0] = toupper (line_buffer[0]);
+  fputs_filtered (line_buffer, stream);
+}
+
+/*
+ * Implement a help command on command list LIST.
+ * RECURSE should be non-zero if this should be done recursively on
+ * all sublists of LIST.
+ * PREFIX is the prefix to print before each command name.
+ * STREAM is the stream upon which the output should be written.
+ * CLASS should be:
+ *     A non-negative class number to list only commands in that
+ * class.
+ *     ALL_COMMANDS to list all commands in list.
+ *     ALL_CLASSES  to list all classes in list.
+ *
+ *   Note that RECURSE will be active on *all* sublists, not just the
+ * ones seclected by the criteria above (ie. the selection mechanism
+ * is at the low level, not the high-level).
+ */
+void
+help_cmd_list (list, class, prefix, recurse, stream)
+     struct cmd_list_element *list;
+     enum command_class class;
+     char *prefix;
+     int recurse;
+     FILE *stream;
+{
+  register struct cmd_list_element *c;
+
+  for (c = list; c; c = c->next)
+    {
+      if (c->abbrev_flag == 0 &&
+         (class == all_commands
+         || (class == all_classes && c->function == 0)
+         || (class == c->class && c->function != 0)))
+       {
+         fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
+         print_doc_line (stream, c->doc);
+         fputs_filtered ("\n", stream);
+       }
+      if (recurse
+         && c->prefixlist != 0
+         && c->abbrev_flag == 0)
+       help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
+    }
+}
+\f
+/* This routine takes a line of TEXT and a CLIST in which to
+   start the lookup.  When it returns it will have incremented the text
+   pointer past the section of text it matched, set *RESULT_LIST to
+   the list in which the last word was matched, and will return the
+   cmd list element which the text matches.  It will return 0 if no
+   match at all was possible.  It will return -1 if ambigous matches are
+   possible; in this case *RESULT_LIST will be set to the list in which
+   there are ambiguous choices (and text will be set to the ambiguous
+   text string).
+
+   It does no error reporting whatsoever; control will always return
+   to the superior routine.
+
+   In the case of an ambiguous return (-1), *RESULT_LIST will be set to
+   point at the prefix_command (ie. the best match) *or* (special
+   case) will be 0 if no prefix command was ever found.  For example,
+   in the case of "info a", "info" matches without ambiguity, but "a"
+   could be "args" or "address", so *RESULT_LIST is set to
+   the cmd_list_element for "info".  So in this case
+   result list should not be interpeted as a pointer to the beginning
+   of a list; it simply points to a specific command.
+
+   If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
+   affect the operation).
+
+   This routine does *not* modify the text pointed to by TEXT.
+   
+   If IGNORE_HELP_CLASSES is nonzero, ignore any command list
+   elements which are actually help classes rather than commands (i.e.
+   the function field of the struct cmd_list_element is 0).  */
+
+struct cmd_list_element *
+lookup_cmd_1 (text, clist, result_list, ignore_help_classes)
+     char **text;
+     struct cmd_list_element *clist, **result_list;
+     int ignore_help_classes;
+{
+  char *p, *command;
+  int len, tmp, nfound;
+  struct cmd_list_element *found, *c;
+
+  while (**text == ' ' || **text == '\t')
+    (*text)++;
+
+  /* Treating underscores as part of command words is important
+     so that "set args_foo()" doesn't get interpreted as
+     "set args _foo()".  */
+  for (p = *text;
+       *p && (isalnum(*p) || *p == '-' || *p == '_');
+       p++)
+    ;
+
+  /* If nothing but whitespace, return 0.  */
+  if (p == *text)
+    return 0;
+  
+  len = p - *text;
+
+  /* *text and p now bracket the first command word to lookup (and
+     it's length is len).  We copy this into a local temporary,
+     converting to lower case as we go.  */
+
+  command = (char *) alloca (len + 1);
+  for (tmp = 0; tmp < len; tmp++)
+    {
+      char x = (*text)[tmp];
+      command[tmp] = (x >= 'A' && x <= 'Z') ? x - 'A' + 'a' : x;
+    }
+  command[len] = '\0';
+
+  /* Look it up.  */
+  found = 0;
+  nfound = 0;
+  for (c = clist; c; c = c->next)
+    if (!strncmp (command, c->name, len)
+       && (!ignore_help_classes || c->function))
+      {
+       found = c;
+       nfound++;
+       if (c->name[len] == '\0')
+         {
+           nfound = 1;
+           break;
+         }
+      }
+
+  /* If nothing matches, we have a simple failure.  */
+  if (nfound == 0)
+    return 0;
+
+  if (nfound > 1)
+    {
+      if (result_list != NULL)
+       /* Will be modified in calling routine
+          if we know what the prefix command is.  */
+       *result_list = 0;               
+      return (struct cmd_list_element *) -1; /* Ambiguous.  */
+    }
+
+  /* We've matched something on this list.  Move text pointer forward. */
+
+  *text = p;
+  if (found->prefixlist)
+    {
+      c = lookup_cmd_1 (text, *found->prefixlist, result_list,
+                       ignore_help_classes);
+      if (!c)
+       {
+         /* Didn't find anything; this is as far as we got.  */
+         if (result_list != NULL)
+           *result_list = clist;
+         return found;
+       }
+      else if (c == (struct cmd_list_element *) -1)
+       {
+         /* We've gotten this far properley, but the next step
+            is ambiguous.  We need to set the result list to the best
+            we've found (if an inferior hasn't already set it).  */
+         if (result_list != NULL)
+           if (!*result_list)
+             /* This used to say *result_list = *found->prefixlist
+                If that was correct, need to modify the documentation
+                at the top of this function to clarify what is supposed
+                to be going on.  */
+             *result_list = found;
+         return c;
+       }
+      else
+       {
+         /* We matched!  */
+         return c;
+       }
+    }
+  else
+    {
+      if (result_list != NULL)
+       *result_list = clist;
+      return found;
+    }
+}
+
+/* Look up the contents of *LINE as a command in the command list LIST.
+   LIST is a chain of struct cmd_list_element's.
+   If it is found, return the struct cmd_list_element for that command
+   and update *LINE to point after the command name, at the first argument.
+   If not found, call error if ALLOW_UNKNOWN is zero
+   otherwise (or if error returns) return zero.
+   Call error if specified command is ambiguous,
+   unless ALLOW_UNKNOWN is negative.
+   CMDTYPE precedes the word "command" in the error message.
+
+   If INGNORE_HELP_CLASSES is nonzero, ignore any command list
+   elements which are actually help classes rather than commands (i.e.
+   the function field of the struct cmd_list_element is 0).  */
+
+struct cmd_list_element *
+lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes)
+     char **line;
+     struct cmd_list_element *list;
+     char *cmdtype;
+     int allow_unknown;
+     int ignore_help_classes;
+{
+  struct cmd_list_element *last_list = 0;
+  struct cmd_list_element *c =
+    lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
+  char *ptr = (*line) + strlen (*line) - 1;
+
+  /* Clear off trailing whitespace.  */
+  while (ptr >= *line && (*ptr == ' ' || *ptr == '\t'))
+    ptr--;
+  *(ptr + 1) = '\0';
+  
+  if (!c)
+    {
+      if (!allow_unknown)
+       {
+         if (!*line)
+           error ("Lack of needed %scommand", cmdtype);
+         else
+           {
+             char *p = *line, *q;
+
+             while (isalnum(*p) || *p == '-')
+               p++;
+
+             q = (char *) alloca (p - *line + 1);
+             strncpy (q, *line, p - *line);
+             q[p-*line] = '\0';
+             
+             error ("Undefined %scommand: \"%s\".", cmdtype, q);
+           }
+       }
+      else
+       return 0;
+    }
+  else if (c == (struct cmd_list_element *) -1)
+    {
+      /* Ambigous.  Local values should be off prefixlist or called
+        values.  */
+      int local_allow_unknown = (last_list ? last_list->allow_unknown :
+                                allow_unknown);
+      char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
+      struct cmd_list_element *local_list =
+       (last_list ? *(last_list->prefixlist) : list);
+      
+      if (local_allow_unknown < 0)
+       {
+         if (last_list)
+           return last_list;   /* Found something.  */
+         else
+           return 0;           /* Found nothing.  */
+       }
+      else
+       {
+         /* Report as error.  */
+         int amb_len;
+         char ambbuf[100];
+
+         for (amb_len = 0;
+              ((*line)[amb_len] && (*line)[amb_len] != ' '
+               && (*line)[amb_len] != '\t');
+              amb_len++)
+           ;
+         
+         ambbuf[0] = 0;
+         for (c = local_list; c; c = c->next)
+           if (!strncmp (*line, c->name, amb_len))
+             {
+               if (strlen (ambbuf) + strlen (c->name) + 6 < (int)sizeof ambbuf)
+                 {
+                   if (strlen (ambbuf))
+                     strcat (ambbuf, ", ");
+                   strcat (ambbuf, c->name);
+                 }
+               else
+                 {
+                   strcat (ambbuf, "..");
+                   break;
+                 }
+             }
+         error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
+                *line, ambbuf);
+         return 0;             /* lint */
+       }
+    }
+  else
+    {
+      /* We've got something.  It may still not be what the caller
+         wants (if this command *needs* a subcommand).  */
+      while (**line == ' ' || **line == '\t')
+       (*line)++;
+
+      if (c->prefixlist && **line && !c->allow_unknown)
+       error ("Undefined %scommand: \"%s\".", c->prefixname, *line);
+
+      /* Seems to be what he wants.  Return it.  */
+      return c;
+    }
+  return 0;
+}
+       
+#if 0
+/* Look up the contents of *LINE as a command in the command list LIST.
+   LIST is a chain of struct cmd_list_element's.
+   If it is found, return the struct cmd_list_element for that command
+   and update *LINE to point after the command name, at the first argument.
+   If not found, call error if ALLOW_UNKNOWN is zero
+   otherwise (or if error returns) return zero.
+   Call error if specified command is ambiguous,
+   unless ALLOW_UNKNOWN is negative.
+   CMDTYPE precedes the word "command" in the error message.  */
+
+struct cmd_list_element *
+lookup_cmd (line, list, cmdtype, allow_unknown)
+     char **line;
+     struct cmd_list_element *list;
+     char *cmdtype;
+     int allow_unknown;
+{
+  register char *p;
+  register struct cmd_list_element *c, *found;
+  int nfound;
+  char ambbuf[100];
+  char *processed_cmd;
+  int i, cmd_len;
+
+  /* Skip leading whitespace.  */
+
+  while (**line == ' ' || **line == '\t')
+    (*line)++;
+
+  /* Clear out trailing whitespace.  */
+
+  p = *line + strlen (*line);
+  while (p != *line && (p[-1] == ' ' || p[-1] == '\t'))
+    p--;
+  *p = 0;
+
+  /* Find end of command name.  */
+
+  p = *line;
+  while (*p == '-'
+        || (*p >= 'a' && *p <= 'z')
+        || (*p >= 'A' && *p <= 'Z')
+        || (*p >= '0' && *p <= '9'))
+    p++;
+
+  /* Look up the command name.
+     If exact match, keep that.
+     Otherwise, take command abbreviated, if unique.  Note that (in my
+     opinion) a null string does *not* indicate ambiguity; simply the
+     end of the argument.  */
+
+  if (p == *line)
+    {
+      if (!allow_unknown)
+       error ("Lack of needed %scommand", cmdtype);
+      return 0;
+    }
+  
+  /* Copy over to a local buffer, converting to lowercase on the way.
+     This is in case the command being parsed is a subcommand which
+     doesn't match anything, and that's ok.  We want the original
+     untouched for the routine of the original command.  */
+  
+  processed_cmd = (char *) alloca (p - *line + 1);
+  for (cmd_len = 0; cmd_len < p - *line; cmd_len++)
+    {
+      char x = (*line)[cmd_len];
+      if (x >= 'A' && x <= 'Z')
+       processed_cmd[cmd_len] = x - 'A' + 'a';
+      else
+       processed_cmd[cmd_len] = x;
+    }
+  processed_cmd[cmd_len] = '\0';
+
+  /* Check all possibilities in the current command list.  */
+  found = 0;
+  nfound = 0;
+  for (c = list; c; c = c->next)
+    {
+      if (!strncmp (processed_cmd, c->name, cmd_len))
+       {
+         found = c;
+         nfound++;
+         if (c->name[cmd_len] == 0)
+           {
+             nfound = 1;
+             break;
+           }
+       }
+    }
+
+  /* Report error for undefined command name.  */
+
+  if (nfound != 1)
+    {
+      if (nfound > 1 && allow_unknown >= 0)
+       {
+         ambbuf[0] = 0;
+         for (c = list; c; c = c->next)
+           if (!strncmp (processed_cmd, c->name, cmd_len))
+             {
+               if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf)
+                 {
+                   if (strlen (ambbuf))
+                     strcat (ambbuf, ", ");
+                   strcat (ambbuf, c->name);
+                 }
+               else
+                 {
+                   strcat (ambbuf, "..");
+                   break;
+                 }
+             }
+         error ("Ambiguous %scommand \"%s\": %s.", cmdtype,
+                processed_cmd, ambbuf);
+       }
+      else if (!allow_unknown)
+       error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd);
+      return 0;
+    }
+
+  /* Skip whitespace before the argument.  */
+
+  while (*p == ' ' || *p == '\t') p++;
+  *line = p;
+
+  if (found->prefixlist && *p)
+    {
+      c = lookup_cmd (line, *found->prefixlist, found->prefixname,
+                     found->allow_unknown);
+      if (c)
+       return c;
+    }
+
+  return found;
+}
+#endif
+
+/* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
+
+/* Return a vector of char pointers which point to the different
+   possible completions in LIST of TEXT.  */
+
+char **
+complete_on_cmdlist (list, text)
+     struct cmd_list_element *list;
+     char *text;
+{
+  struct cmd_list_element *ptr;
+  char **matchlist;
+  int sizeof_matchlist;
+  int matches;
+  int textlen = strlen (text);
+
+  sizeof_matchlist = 10;
+  matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
+  matches = 0;
+
+  for (ptr = list; ptr; ptr = ptr->next)
+    if (!strncmp (ptr->name, text, textlen)
+       && !ptr->abbrev_flag
+       && (ptr->function
+           || ptr->prefixlist))
+      {
+       if (matches == sizeof_matchlist)
+         {
+           sizeof_matchlist *= 2;
+           matchlist = (char **) xrealloc ((char *)matchlist,
+                                           (sizeof_matchlist
+                                            * sizeof (char *)));
+         }
+
+       matchlist[matches] = (char *) 
+         xmalloc (strlen (ptr->name) + 1);
+       strcpy (matchlist[matches++], ptr->name);
+      }
+
+  if (matches == 0)
+    {
+      free (matchlist);
+      matchlist = 0;
+    }
+  else
+    {
+      matchlist = (char **) xrealloc ((char *)matchlist, ((matches + 1)
+                                               * sizeof (char *)));
+      matchlist[matches] = (char *) 0;
+    }
+
+  return matchlist;
+}
+
+static int
+parse_binary_operation (arg)
+     char *arg;
+{
+  int length;
+
+  if (!arg || !*arg)
+    return 1;
+
+  length = strlen (arg);
+
+  while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
+    length--;
+
+  if (!strncmp (arg, "on", length)
+      || !strncmp (arg, "1", length)
+      || !strncmp (arg, "yes", length))
+    return 1;
+  else
+    if (!strncmp (arg, "off", length)
+       || !strncmp (arg, "0", length)
+       || !strncmp (arg, "no", length))
+      return 0;
+    else 
+      {
+       error ("\"on\" or \"off\" expected.");
+       return 0;
+      }
+}
+
+/* Do a "set" or "show" command.  ARG is NULL if no argument, or the text
+   of the argument, and FROM_TTY is nonzero if this command is being entered
+   directly by the user (i.e. these are just like any other
+   command).  C is the command list element for the command.  */
+void
+do_setshow_command (arg, from_tty, c)
+     char *arg;
+     int from_tty;
+     struct cmd_list_element *c;
+{
+  if (c->type == set_cmd)
+    {
+      switch (c->var_type)
+       {
+       case var_string:
+         {
+           char *new;
+           char *p;
+           char *q;
+           int ch;
+           
+           if (arg == NULL)
+             arg = "";
+           new = (char *) xmalloc (strlen (arg) + 2);
+           p = arg; q = new;
+           while (ch = *p++)
+             {
+               if (ch == '\\')
+                 {
+                   /* \ at end of argument is used after spaces
+                      so they won't be lost.  */
+                   if (*p == 0)
+                     break;
+                   ch = parse_escape (&p);
+                   if (ch == 0)
+                     break; /* C loses */
+                   else if (ch > 0)
+                     *q++ = ch;
+                 }
+               else
+                 *q++ = ch;
+             }
+           if (*(p - 1) != '\\')
+             *q++ = ' ';
+           *q++ = '\0';
+           new = (char *) xrealloc (new, q - new);
+           if (*(char **)c->var != NULL)
+             free (*(char **)c->var);
+           *(char **) c->var = new;
+         }
+         break;
+       case var_string_noescape:
+         if (arg == NULL)
+           arg = "";
+         if (*(char **)c->var != NULL)
+           free (*(char **)c->var);
+         *(char **) c->var = savestring (arg, strlen (arg));
+         break;
+       case var_filename:
+         if (arg == NULL)
+           error_no_arg ("filename to set it to.");
+         if (*(char **)c->var != NULL)
+           free (*(char **)c->var);
+         *(char **)c->var = tilde_expand (arg);
+         break;
+       case var_boolean:
+         *(int *) c->var = parse_binary_operation (arg);
+         break;
+       case var_uinteger:
+         if (arg == NULL)
+           error_no_arg ("integer to set it to.");
+         *(int *) c->var = parse_and_eval_address (arg);
+         if (*(int *) c->var == 0)
+           *(int *) c->var = UINT_MAX;
+         break;
+       case var_zinteger:
+         if (arg == NULL)
+           error_no_arg ("integer to set it to.");
+         *(int *) c->var = parse_and_eval_address (arg);
+         break;
+       default:
+         error ("gdb internal error: bad var_type in do_setshow_command");
+       }
+    }
+  else if (c->type == show_cmd)
+    {
+      /* Print doc minus "show" at start.  */
+      print_doc_line (stdout, c->doc + 5);
+      
+      fputs_filtered (" is ", stdout);
+      wrap_here ("    ");
+      switch (c->var_type)
+       {
+      case var_string:
+       {
+         unsigned char *p;
+         fputs_filtered ("\"", stdout);
+         for (p = *(unsigned char **) c->var; *p != '\0'; p++)
+           printchar (*p, stdout, '"');
+         fputs_filtered ("\"", stdout);
+       }
+       break;
+      case var_string_noescape:
+      case var_filename:
+       fputs_filtered ("\"", stdout);
+       fputs_filtered (*(char **) c->var, stdout);
+       fputs_filtered ("\"", stdout);
+       break;
+      case var_boolean:
+       fputs_filtered (*(int *) c->var ? "on" : "off", stdout);
+       break;
+      case var_uinteger:
+       if (*(unsigned int *) c->var == UINT_MAX) {
+         fputs_filtered ("unlimited", stdout);
+         break;
+       }
+       /* else fall through */
+      case var_zinteger:
+       fprintf_filtered (stdout, "%d", *(unsigned int *) c->var);
+       break;
+      default:
+       error ("gdb internal error: bad var_type in do_setshow_command");
+      }
+      fputs_filtered (".\n", stdout);
+    }
+  else
+    error ("gdb internal error: bad cmd_type in do_setshow_command");
+  (*c->function) (NULL, from_tty, c);
+}
+
+/* Show all the settings in a list of show commands.  */
+
+void
+cmd_show_list (list, from_tty, prefix)
+     struct cmd_list_element *list;
+     int from_tty;
+     char *prefix;
+{
+  for (; list != NULL; list = list->next) {
+    /* If we find a prefix, run its list, prefixing our output by its
+       prefix (with "show " skipped).  */
+    if (list->prefixlist && !list->abbrev_flag)
+      cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
+    if (list->type == show_cmd)
+      {
+       fputs_filtered (prefix, stdout);
+       fputs_filtered (list->name, stdout);
+       fputs_filtered (":  ", stdout);
+       do_setshow_command ((char *)NULL, from_tty, list);
+      }
+  }
+}
+
+static void
+shell_escape (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  int rc, status, pid;
+  char *p, *user_shell;
+  extern char *rindex ();
+
+  if ((user_shell = (char *) getenv ("SHELL")) == NULL)
+    user_shell = "/bin/sh";
+
+  /* Get the name of the shell for arg0 */
+  if ((p = rindex (user_shell, '/')) == NULL)
+    p = user_shell;
+  else
+    p++;                       /* Get past '/' */
+
+  if ((pid = fork()) == 0)
+    {
+      if (!arg)
+       execl (user_shell, p, 0);
+      else
+       execl (user_shell, p, "-c", arg, 0);
+
+      fprintf (stderr, "Exec of shell failed\n");
+      exit (0);
+    }
+
+  if (pid != -1)
+    while ((rc = wait (&status)) != pid && rc != -1)
+      ;
+  else
+    error ("Fork failed");
+}
+
+static void
+make_command (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  char *p;
+
+  if (arg == 0)
+    p = "make";
+  else
+    {
+      p = xmalloc (sizeof("make ") + strlen(arg));
+      strcpy (p, "make ");
+      strcpy (p + sizeof("make ")-1, arg);
+    }
+  
+  shell_escape (p, from_tty);
+}
+
+void
+_initialize_command ()
+{
+  add_com ("shell", class_support, shell_escape,
+          "Execute the rest of the line as a shell command.  \n\
+With no arguments, run an inferior shell.");
+
+  add_com ("make", class_support, make_command,
+          "Run the ``make'' program using the rest of the line as arguments.");
+}
diff --git a/gdb/config.gdb b/gdb/config.gdb
new file mode 100755 (executable)
index 0000000..917d94e
--- /dev/null
@@ -0,0 +1,185 @@
+#!/bin/sh
+
+# Shell script to do machine-dependent things in
+# preparation for compiling gdb.
+#
+# Usage: config.gdb machine
+#
+# If config.gdb succeeds, it leaves its status in config.status.
+# If config.gdb fails after disturbing the status quo, 
+#      config.status is removed.
+
+progname=$0
+host=
+target=
+list_hosts=
+list_targets=
+srcdir=
+
+for arg in $*; do
+  case $arg in
+    -srcdir=*|+srcdir=*)
+      srcdir=`echo $arg | sed 's/[+-]srcdir=//'`
+      ;;
+    -host|+host)
+      list_hosts=true
+      ;;
+    -target|+target)
+      list_targets=true
+      ;;
+    -host=*|+host=*)
+      if [ "$host" = "" ]; then
+        host=`echo $arg | sed 's/[+-]host=//'`
+      else
+        echo Error: Attempt to specify host machine twice
+        bad=true
+      fi
+      ;;
+    -target=*|+target=*)
+      if [ "$target" = "" ]; then
+        target=`echo $arg | sed 's/[+-]target=//'`
+      else
+        echo Error: Attempt to specify target machine twice
+        bad=true
+      fi
+      ;;
+    *)
+      if [ "$host" = "" ]; then
+       host=$arg
+      else
+        if [ "$target" = "" ]; then
+          target=$arg
+        else
+          echo Error: More arguments than host and target machine names
+         bad=true
+        fi
+      fi
+      ;;
+  esac
+done
+
+if [ "$target" = "" ]; then target=$host; fi
+if [ "$host" = "" ]; then bad=true; fi
+
+# Find the source files, if location was not specified
+if [ "$srcdir" = "" ]; then
+  srcdirdefaulted=true
+  srcdir=.
+  if [ ! -r main.c ]; then
+    srcdir=..
+  fi
+fi
+if [ ! -r ${srcdir}/main.c ]; then
+  if [ "$srcdirdefaulted" != "true" ]; then
+    echo "$progname: Can't find debugger sources in \`${srcdir}'." 1>&2
+  else
+    echo "$progname: Can't find debugger sources in \`.' or \`..'." 1>&2
+  fi
+  exit 1
+fi
+
+if [ "$list_hosts" = "true" ]; then
+  cd $srcdir/xconfig
+  for i in * ; do
+# The {} in ${i} are required or else /bin/sh in sony newsos 3.2 removes
+# the quote after it.
+  awk <$i "NR == 1 { lastchar = substr(\"${i}\", length(\"${i}\"), 1)
+if (lastchar != \"~\" && lastchar != \"#\") \
+printf \"%-12s %s\n\", \"${i}\", substr(\$0,2) }"
+  done
+fi
+
+if [ "$list_targets" = "true" ]; then
+  cd $srcdir/tconfig
+  for i in * ; do
+  awk <$i "NR == 1 { lastchar = substr(\"${i}\", length(\"${i}\"), 1)
+if (lastchar != \"~\" && lastchar != \"#\") \
+printf \"%-12s %s\n\", \"${i}\", substr(\$0,2) }"
+  done
+fi
+
+if [ "$list_hosts" = "true" -o "$list_targets" = "true" ]; then
+  exit 0
+fi
+
+if [ "$host" != "" -a ! -f $srcdir/xconfig/$host ]; then
+  echo "No such host $host"
+  bad=true
+fi
+
+if [ "$target" != "" -a ! -f $srcdir/tconfig/$target ]; then
+  echo "No such target $target"
+  bad=true
+fi
+
+if [ "$bad" = "true" ] ; then
+  echo "Usage: "
+  echo "  $progname [+srcdir=\`dir'] machine"
+  echo "    For normal usage"
+  echo "  $progname [+srcdir=\`dir'] \`host' \`target'"
+  echo "  $progname [+srcdir=\`dir'] +host=\`host' +target=\`target'"
+  echo "    If you are doing remote debugging between machines of two"
+  echo "    different types (cross-debugging).  \`host' is the type of"
+  echo "    machine on which GDB will be running.  \`target' is the"
+  echo "    machine that the program you are debugging will be"
+  echo "    running on."
+  echo "  $progname +host"
+  echo "    Print a list of valid host machine types."
+  echo "  $progname +target"
+  echo "    Print a list of valid target machine types."
+  echo
+  echo "  +srcdir=\`dir' means that the sources are in \`dir'.  For"
+  echo "    example, \`cd /obj/hp300; config.gdb +srcdir=/src/gdb hp300'"
+  echo "    If +srcdir is not specified, sources can either be in \`.'"
+  echo "    or \`..'."
+  echo
+
+  if [ -r config.status ]
+  then
+    cat config.status
+  fi
+  exit 1
+fi
+
+rm -f tm.h xm.h
+
+cat $srcdir/xconfig/$host $srcdir/tconfig/$target | awk '$1 == "#msg" {
+  print substr($0,6)}'
+paramfile=${srcdir}/`awk '
+  $1 == "TM_FILE=" { print $2 }' <$srcdir/tconfig/$target`
+if [ "$paramfile" != "${srcdir}/" ] ; then
+  # Make a symlink if possible, otherwise try a hard link
+  ln -s $paramfile tm.h 2>/dev/null || ln $paramfile tm.h
+fi
+
+paramfile=${srcdir}/`awk '
+  $1 == "XM_FILE=" { print $2 }' <$srcdir/xconfig/$host`
+if [ "$paramfile" != "${srcdir}/" ] ; then
+  # Make a symlink if possible, otherwise try a hard link
+  ln -s $paramfile xm.h 2>/dev/null || ln $paramfile xm.h
+fi
+
+rm -f config.status
+
+case ${srcdir} in
+  .)
+    ;;
+  *)
+    echo "srcdir=${srcdir}" >./Makefile.srcdir
+    grep -s "source ${srcdir}/.gdbinit" .gdbinit 2>/dev/null || \
+      echo "source ${srcdir}/.gdbinit" >> .gdbinit
+    if [ ! -d readline ]; then
+      mkdir readline
+      # This could be a symlink, but getting the name right (because
+      # srcdir can be either relative or absolute) would be hairy.
+      cp ${srcdir}/readline/Makefile readline
+    fi
+esac
+
+make "srcdir=${srcdir}" \
+  "M_MAKEFILE=$srcdir/tconfig/$target $srcdir/xconfig/$host" \
+  -f $srcdir/Makefile.dist Makefile
+
+echo "GDB is now set up for host machine $host and target machine $target." \
+       | tee config.status
+exit 0
diff --git a/gdb/config.status b/gdb/config.status
new file mode 100755 (executable)
index 0000000..ec87176
--- /dev/null
@@ -0,0 +1 @@
+GDB is now set up for host machine none and target machine none.
diff --git a/gdb/config/3b1.mh b/gdb/config/3b1.mh
new file mode 100644 (file)
index 0000000..76fc51d
--- /dev/null
@@ -0,0 +1,27 @@
+# AT&T 3b1/Unix pc
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# I don't think cc has been tried.  -traditional for <sys/ioctl.h>
+# (not sure whether necessary).
+CC= gcc -traditional
+# GCC runs out of virtual memory.
+PINSN_CC= cc
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-3b1.h
diff --git a/gdb/config/3b1.mt b/gdb/config/3b1.mt
new file mode 100644 (file)
index 0000000..8a73b46
--- /dev/null
@@ -0,0 +1,21 @@
+# AT&T 3b1/Unix pc
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o
+TM_FILE= tm-3b1.h
diff --git a/gdb/config/altos.mh b/gdb/config/altos.mh
new file mode 100644 (file)
index 0000000..03f93bf
--- /dev/null
@@ -0,0 +1,24 @@
+# Altos 3068 (68k, System V release 2)
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o altos-xdep.o
+XM_FILE= xm-altos.h
+REGEX=regex.o
+REGEX1=regex.o
+SYSV_DEFINE=-DSYSV
diff --git a/gdb/config/altos.mt b/gdb/config/altos.mt
new file mode 100644 (file)
index 0000000..5d43893
--- /dev/null
@@ -0,0 +1,21 @@
+# Altos 3068 (68k, System V release 2)
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= m68k-pinsn.o exec.o
+TM_FILE= tm-altos.h
diff --git a/gdb/config/altosgas.mh b/gdb/config/altosgas.mh
new file mode 100644 (file)
index 0000000..2ade447
--- /dev/null
@@ -0,0 +1,27 @@
+# Altos 3068 (68k, System V release 2), using COFF encapsulation
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Use of the coff encapsulation features require the GNU binutils utilities
+#msg To be ahead of their System V counterparts in your path.
+
+XDEPFILES= infptrace.o altos-xdep.o
+XM_FILE= xm-altos.h
+REGEX=regex.o
+REGEX1=regex.o
+SYSV_DEFINE=-DSYSV
diff --git a/gdb/config/altosgas.mt b/gdb/config/altosgas.mt
new file mode 100644 (file)
index 0000000..3c502fc
--- /dev/null
@@ -0,0 +1,24 @@
+# Altos 3068 (68k, System V release 2), using COFF encapsulation
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Use of the coff encapsulation features require the GNU binutils utilities
+#msg To be ahead of their System V counterparts in your path.
+
+TDEPFILES= m68k-pinsn.o exec.o
+TM_FILE= tm-altosgas.h
diff --git a/gdb/config/am29k b/gdb/config/am29k
new file mode 100755 (executable)
index 0000000..8a9b475
--- /dev/null
@@ -0,0 +1,23 @@
+# AMD 29000 on EB29K board over a serial line.
+# Copyright (C) 1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o am29k-pinsn.o remote-eb.o am29k-tdep.o
+TM_FILE= tm-29k.h
+# The following is for ../include/a.out.encap.h
+TM_CFLAGS = -DCOFF_ENCAPSULATE -DTARGET=TARGET_AM29K
diff --git a/gdb/config/arm.mh b/gdb/config/arm.mh
new file mode 100644 (file)
index 0000000..8dc057a
--- /dev/null
@@ -0,0 +1,21 @@
+# Acorn RISC machine running RISCiX (4.3bsd)
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o arm-xdep.o arm-convert.o
+XM_FILE= xm-arm.h
diff --git a/gdb/config/arm.mt b/gdb/config/arm.mt
new file mode 100644 (file)
index 0000000..d26c862
--- /dev/null
@@ -0,0 +1,21 @@
+# Acorn RISC machine running RISCiX (4.3bsd)
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= arm-tdep.o arm-pinsn.o
+TM_FILE= tm-arm.h
diff --git a/gdb/config/bigmips.mh b/gdb/config/bigmips.mh
new file mode 100644 (file)
index 0000000..1b1cd48
--- /dev/null
@@ -0,0 +1,21 @@
+# Big-endian MIPS machine such as Sony News
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o mips-xdep.o coredep.o
+XM_FILE= xm-bigmips.h
diff --git a/gdb/config/bigmips.mt b/gdb/config/bigmips.mt
new file mode 100644 (file)
index 0000000..0e594d8
--- /dev/null
@@ -0,0 +1,21 @@
+# Big-endian MIPS machine such as Sony News
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= mips-pinsn.o mips-tdep.o mipsread.o exec.o
+TM_FILE= tm-bigmips.h
diff --git a/gdb/config/convex.mh b/gdb/config/convex.mh
new file mode 100644 (file)
index 0000000..b681f28
--- /dev/null
@@ -0,0 +1,21 @@
+# Convex Unix (4bsd)
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= convex-xdep.o
+XM_FILE= xm-convex.h
diff --git a/gdb/config/convex.mt b/gdb/config/convex.mt
new file mode 100644 (file)
index 0000000..f7938a2
--- /dev/null
@@ -0,0 +1,21 @@
+# Convex Unix (4bsd)
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= convex-tdep.o convex-pinsn.o
+TM_FILE= tm-convex.h
diff --git a/gdb/config/hp300bsd.mh b/gdb/config/hp300bsd.mh
new file mode 100644 (file)
index 0000000..ae3bb82
--- /dev/null
@@ -0,0 +1,21 @@
+# Hewlett-Packard 9000 series 300, running BSD
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-hp300bsd.h
diff --git a/gdb/config/hp300bsd.mt b/gdb/config/hp300bsd.mt
new file mode 100644 (file)
index 0000000..ea03374
--- /dev/null
@@ -0,0 +1,21 @@
+# Hewlett-Packard 9000 series 300, running BSD
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o
+TM_FILE= tm-hp300bsd.h
diff --git a/gdb/config/hp300hpux.mh b/gdb/config/hp300hpux.mh
new file mode 100644 (file)
index 0000000..3488ef0
--- /dev/null
@@ -0,0 +1,33 @@
+# Hewlett-Packard 9000 series 300, running HPUX
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The following is true because gcc uses a different .o file format
+# than the native HPUX compiler
+#msg If you compile GDB with GCC on HPUX, you must make sure
+#msg that the `nm' used in `munch' is GNU nm
+#msg
+
+# The headers in the directory hp-include override system headers
+# and tell GDB to use BSD executable file format (hence -Ihp-include)
+XDEPFILES= infptrace.o hp300hpux-xdep.o
+XM_FILE= xm-hp300hpux.h
+SYSV_DEFINE=-DSYSV
+REGEX=regex.o
+REGEX1=regex.o
+ALLOCA=alloca.o
diff --git a/gdb/config/hp300hpux.mt b/gdb/config/hp300hpux.mt
new file mode 100644 (file)
index 0000000..cee6ba7
--- /dev/null
@@ -0,0 +1,28 @@
+# Hewlett-Packard 9000 series 300, running HPUX
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Note that GDB only can read symbols from programs that were
+#msg compiled with GCC
+#msg
+
+# The headers in the directory hp-include override system headers
+# and tell GDB to use BSD executable file format (hence -Ihp-include)
+TM_CFLAGS=-Ihp-include
+TDEPFILES= exec.o m68k-pinsn.o
+TM_FILE= tm-hp300hpux.h
diff --git a/gdb/config/i386v-g.mh b/gdb/config/i386v-g.mh
new file mode 100644 (file)
index 0000000..a14a85e
--- /dev/null
@@ -0,0 +1,25 @@
+# Intel 386 running System V, using COFF encapsulation
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o i386-xdep.o
+XM_FILE= xm-i386v.h
+XM_CLIBS= -lPW
+SYSV_DEFINE=-DSYSV
+REGEX=regex.o
+REGEX1=regex.o
diff --git a/gdb/config/i386v-g.mt b/gdb/config/i386v-g.mt
new file mode 100644 (file)
index 0000000..b93b9ce
--- /dev/null
@@ -0,0 +1,25 @@
+# Intel 386 running System V, using COFF encapsulation
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Use of the COFF encapsulation features requires the GNU binary utilities
+#msg to be ahead of their System V counterparts in your path.
+#msg
+
+TDEPFILES= exec.o i386-tdep.o i386-pinsn.o
+TM_FILE= tm-i386v-g.h
diff --git a/gdb/config/i386v.mh b/gdb/config/i386v.mh
new file mode 100644 (file)
index 0000000..c65cd37
--- /dev/null
@@ -0,0 +1,25 @@
+# Intel 386 running System V
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o i386-xdep.o
+XM_FILE= xm-i386v.h
+XM_CLIBS= -lPW
+SYSV_DEFINE=-DSYSV
+REGEX=regex.o
+REGEX1=regex.o
diff --git a/gdb/config/i386v.mt b/gdb/config/i386v.mt
new file mode 100644 (file)
index 0000000..14d9b59
--- /dev/null
@@ -0,0 +1,21 @@
+# Intel 386 running System V
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o i386-tdep.o i386-pinsn.o
+TM_FILE= tm-i386v.h
diff --git a/gdb/config/i386v32-g.mh b/gdb/config/i386v32-g.mh
new file mode 100644 (file)
index 0000000..4dfb1a4
--- /dev/null
@@ -0,0 +1,25 @@
+# Intel 386 running System V release 2, using COFF encapsulation
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o i386-xdep.o
+XM_FILE= xm-i386v32.h
+XM_CLIBS= -lPW
+SYSV_DEFINE=-DSYSV
+REGEX=regex.o
+REGEX1=regex.o
diff --git a/gdb/config/i386v32-g.mt b/gdb/config/i386v32-g.mt
new file mode 100644 (file)
index 0000000..2432551
--- /dev/null
@@ -0,0 +1,24 @@
+# Intel 386 running System V release 2, using COFF encapsulation
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Use of the COFF encapsulation features requires the GNU binary utilities
+#msg to be ahead of their System V counterparts in your path.
+
+TDEPFILES= exec.o i386-tdep.o i386-pinsn.o
+TM_FILE= tm-i386v-g.h
diff --git a/gdb/config/i386v32.mh b/gdb/config/i386v32.mh
new file mode 100644 (file)
index 0000000..c184745
--- /dev/null
@@ -0,0 +1,25 @@
+# Intel 386 running System V release 2
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o i386-xdep.o
+XM_FILE= xm-i386v32.h
+XM_CLIBS= -lPW
+SYSV_DEFINE=-DSYSV
+REGEX=regex.o
+REGEX1=regex.o
diff --git a/gdb/config/i386v32.mt b/gdb/config/i386v32.mt
new file mode 100644 (file)
index 0000000..5cca19d
--- /dev/null
@@ -0,0 +1,21 @@
+# Intel 386 running System V release 2
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o i386-tdep.o i386-pinsn.o
+TM_FILE= tm-i386v.h
diff --git a/gdb/config/i960.mt b/gdb/config/i960.mt
new file mode 100644 (file)
index 0000000..d92b73e
--- /dev/null
@@ -0,0 +1,23 @@
+# Intel 80960, under NINDY or under VxWorks, selected at runtime.
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg
+#msg You must specify either "nindy960" or "vxworks960"; there is no
+#msg generic i960 target any more.
+#msg
diff --git a/gdb/config/isi.mh b/gdb/config/isi.mh
new file mode 100644 (file)
index 0000000..1ae1c7a
--- /dev/null
@@ -0,0 +1,21 @@
+# ISI Optimum V (3.05) under 4.3bsd.
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-isi.h
diff --git a/gdb/config/isi.mt b/gdb/config/isi.mt
new file mode 100644 (file)
index 0000000..aab33e1
--- /dev/null
@@ -0,0 +1,21 @@
+# ISI Optimum V (3.05) under 4.3bsd.
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o
+TM_FILE= tm-isi.h
diff --git a/gdb/config/littlemips.mh b/gdb/config/littlemips.mh
new file mode 100644 (file)
index 0000000..2d4298c
--- /dev/null
@@ -0,0 +1,21 @@
+# Little-endian MIPS machine such as DECstation.
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o mips-xdep.o coredep.o
+XM_FILE= xm-mips.h
diff --git a/gdb/config/littlemips.mt b/gdb/config/littlemips.mt
new file mode 100644 (file)
index 0000000..709bc57
--- /dev/null
@@ -0,0 +1,21 @@
+# Little-endian MIPS machine such as DECstation.
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= mips-pinsn.o mips-tdep.o mipsread.o exec.o
+TM_FILE= tm-mips.h
diff --git a/gdb/config/m88k.mh b/gdb/config/m88k.mh
new file mode 100644 (file)
index 0000000..a703d1a
--- /dev/null
@@ -0,0 +1,21 @@
+# Motorola 88000 running DGUX
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= 
+XM_FILE= xm-88k.h
diff --git a/gdb/config/m88k.mt b/gdb/config/m88k.mt
new file mode 100644 (file)
index 0000000..f3b67dc
--- /dev/null
@@ -0,0 +1,23 @@
+# Motorola 88000 running DGUX
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= tdesc.o
+TM_CLIBS= tdesc/libdc.o
+TM_CDEPS= tdesc/libdc.o
+TM_FILE= tm-88k.h
diff --git a/gdb/config/merlin.mh b/gdb/config/merlin.mh
new file mode 100644 (file)
index 0000000..ecb8cf9
--- /dev/null
@@ -0,0 +1,24 @@
+# Merlin running utek 2.1
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-merlin.h
+# See SHELL_FILE in m-merlin.h for a explanation of this.
+M_INSTALL=cp /bin/sh /usr/local/lib/gdb-sh; \
+chmod ogu+rw /usr/local/lib/gdb-sh
diff --git a/gdb/config/merlin.mt b/gdb/config/merlin.mt
new file mode 100644 (file)
index 0000000..1ed8caa
--- /dev/null
@@ -0,0 +1,21 @@
+# Merlin running utek 2.1
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o ns32k-pinsn.o
+TM_FILE= tm-merlin.h
diff --git a/gdb/config/mh-vax b/gdb/config/mh-vax
new file mode 100755 (executable)
index 0000000..8dbb707
--- /dev/null
@@ -0,0 +1,28 @@
+# DEC VAX running BSD or Ultrix
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The following types of /bin/cc failures have been observed:
+# 1.  Something in readline.c which I have never seen
+# 2.  ``"values.c", line 816: compiler error: schain botch''
+#msg /bin/cc has been known to fail on VAXen running BSD4.3
+#msg If this occurs, use gcc
+#msg  (but see comments in Makefile.dist about compiling with gcc).
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-vax.h
diff --git a/gdb/config/news.mh b/gdb/config/news.mh
new file mode 100644 (file)
index 0000000..1bb7765
--- /dev/null
@@ -0,0 +1,21 @@
+# Sony news series 700/800/900 (68020) running NewsOS version 3.
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o news-xdep.o
+XM_FILE= xm-news.h
diff --git a/gdb/config/news.mt b/gdb/config/news.mt
new file mode 100644 (file)
index 0000000..c26465a
--- /dev/null
@@ -0,0 +1,21 @@
+# Sony news series 700/800/900 (68020) running NewsOS version 3.
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= m68k-pinsn.o exec.o
+TM_FILE= tm-news.h
diff --git a/gdb/config/news1000.mh b/gdb/config/news1000.mh
new file mode 100644 (file)
index 0000000..940aaee
--- /dev/null
@@ -0,0 +1,21 @@
+# Sony news series 1000 (68030) running NewsOS version 3.
+# Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o news-xdep.o
+XM_FILE= xm-news1000.h
diff --git a/gdb/config/news1000.mt b/gdb/config/news1000.mt
new file mode 100644 (file)
index 0000000..d390504
--- /dev/null
@@ -0,0 +1,21 @@
+# Sony news series 1000 (68030) running NewsOS version 3.
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= m68k-pinsn.o exec.o
+TM_FILE= tm-news.h
diff --git a/gdb/config/nindy960.mt b/gdb/config/nindy960.mt
new file mode 100644 (file)
index 0000000..f7dc6f7
--- /dev/null
@@ -0,0 +1,22 @@
+# Intel 80960, in an embedded system under the NINDY monitor
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o i960-pinsn.o i960-tdep.o nindy-tdep.o remote-nindy.o nindy.o Onindy.o ttybreak.o ttyflush.o
+TM_FILE= tm-nindy960.h
+TM_CFLAGS=
diff --git a/gdb/config/none.mh b/gdb/config/none.mh
new file mode 100644 (file)
index 0000000..74e7048
--- /dev/null
@@ -0,0 +1,21 @@
+# Target config file for "no target".  This can be used to build you
+# a Makefile that only runs administrative commands like 'clean',
+# 'gdb.tar.Z', etc.
+#
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/gdb/config/none.mt b/gdb/config/none.mt
new file mode 100644 (file)
index 0000000..c6b5db9
--- /dev/null
@@ -0,0 +1,3 @@
+# "no target".
+# This can be used to build you a Makefile that only runs administrative
+# commands like 'clean', 'gdb.tar.Z', etc.
diff --git a/gdb/config/np1.mh b/gdb/config/np1.mh
new file mode 100644 (file)
index 0000000..fcf88f2
--- /dev/null
@@ -0,0 +1,21 @@
+# Gould NP1
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o gould-xdep.o
+XM_FILE= xm-np1.h
diff --git a/gdb/config/np1.mt b/gdb/config/np1.mt
new file mode 100644 (file)
index 0000000..4fafd7b
--- /dev/null
@@ -0,0 +1,21 @@
+# Gould NP1
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o gould-pinsn.o
+TM_FILE= tm-np1.h
diff --git a/gdb/config/pn.mh b/gdb/config/pn.mh
new file mode 100644 (file)
index 0000000..7e8f807
--- /dev/null
@@ -0,0 +1,21 @@
+# Gould Powernode
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o coredep.o
+XM_FILE= xm-pn.h
diff --git a/gdb/config/pn.mt b/gdb/config/pn.mt
new file mode 100644 (file)
index 0000000..ad26b9c
--- /dev/null
@@ -0,0 +1,21 @@
+# Gould Powernode
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o gould-pinsn.o
+TM_FILE= tm-pn.h
diff --git a/gdb/config/pyramid.mh b/gdb/config/pyramid.mh
new file mode 100644 (file)
index 0000000..59561ec
--- /dev/null
@@ -0,0 +1,25 @@
+# Pyramidax under OSx 4.0 (4.2bsd).
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg If you don't compile GDB with GCC, you'll need to add
+#msg ALLOCA=alloca.o and ALLOCA1=alloca.o to the Makefile.
+#msg 
+
+XDEPFILES= pyr-xdep.o infptrace.o
+XM_FILE= xm-pyr.h
diff --git a/gdb/config/pyramid.mt b/gdb/config/pyramid.mt
new file mode 100644 (file)
index 0000000..d62e88e
--- /dev/null
@@ -0,0 +1,25 @@
+# Pyramid under OSx 4.0 (4.2bsd).
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#msg Note that GDB on Pyramids only works with GCC,
+#msg at least for some programs.
+#msg
+
+TDEPFILES= pyr-pinsn.o pyr-tdep.o exec.o
+TM_FILE= tm-pyr.h
diff --git a/gdb/config/sun2os3.mh b/gdb/config/sun2os3.mh
new file mode 100644 (file)
index 0000000..87f8130
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 2, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sun3-xdep.o
+XM_FILE= xm-sun2.h
diff --git a/gdb/config/sun2os3.mt b/gdb/config/sun2os3.mt
new file mode 100644 (file)
index 0000000..99dc7f7
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 2, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o m68k-pinsn.o m68k-tdep.o
+TM_FILE= tm-sun2.h
diff --git a/gdb/config/sun2os4.mh b/gdb/config/sun2os4.mh
new file mode 100644 (file)
index 0000000..f525cf6
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 2, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sun3-xdep.o
+XM_FILE= xm-sun2.h
diff --git a/gdb/config/sun2os4.mt b/gdb/config/sun2os4.mt
new file mode 100644 (file)
index 0000000..d70dd81
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 2, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o m68k-pinsn.o solib.o m68k-tdep.o
+TM_FILE= tm-sun2os4.h
diff --git a/gdb/config/sun3.mh b/gdb/config/sun3.mh
new file mode 100644 (file)
index 0000000..6a91b49
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 3, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+XDEPFILES= infptrace.o sun3-xdep.o
+XM_FILE= xm-sun3os4.h
diff --git a/gdb/config/sun3.mt b/gdb/config/sun3.mt
new file mode 100644 (file)
index 0000000..ae6e351
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 3, running SunOS 4, as a target system
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o solib.o m68k-tdep.o
+TM_FILE= tm-sun3os4.h
diff --git a/gdb/config/sun386.mh b/gdb/config/sun386.mh
new file mode 100644 (file)
index 0000000..a2cb431
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 386i
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sun386-xdep.o
+XM_FILE= xm-sun386.h
diff --git a/gdb/config/sun386.mt b/gdb/config/sun386.mt
new file mode 100644 (file)
index 0000000..1a0bca5
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 386i target configuration file.
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o i386-pinsn.o solib.o
+TM_FILE= tm-sun386.h
diff --git a/gdb/config/sun3os3.mh b/gdb/config/sun3os3.mh
new file mode 100644 (file)
index 0000000..4408552
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 3, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sun3-xdep.o
+XM_FILE= xm-sun3.h
diff --git a/gdb/config/sun3os3.mt b/gdb/config/sun3os3.mt
new file mode 100644 (file)
index 0000000..3eea3bf
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 3, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o m68k-pinsn.o m68k-tdep.o
+TM_FILE= tm-sun3.h
diff --git a/gdb/config/sun3os4.mh b/gdb/config/sun3os4.mh
new file mode 100644 (file)
index 0000000..6a91b49
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 3, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+XDEPFILES= infptrace.o sun3-xdep.o
+XM_FILE= xm-sun3os4.h
diff --git a/gdb/config/sun3os4.mt b/gdb/config/sun3os4.mt
new file mode 100644 (file)
index 0000000..ae6e351
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 3, running SunOS 4, as a target system
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o solib.o m68k-tdep.o
+TM_FILE= tm-sun3os4.h
diff --git a/gdb/config/sun4.mh b/gdb/config/sun4.mh
new file mode 100644 (file)
index 0000000..8054271
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 4 or Sparcstation, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sparc-xdep.o
+XM_FILE= xm-sun4os4.h
diff --git a/gdb/config/sun4.mt b/gdb/config/sun4.mt
new file mode 100644 (file)
index 0000000..030872d
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 4 or Sparcstation, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o sparc-tdep.o sparc-pinsn.o solib.o
+TM_FILE= tm-sun4os4.h
diff --git a/gdb/config/sun4os3.mh b/gdb/config/sun4os3.mh
new file mode 100644 (file)
index 0000000..fdb0ddd
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 4 or Sparcstation, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sparc-xdep.o
+XM_FILE= xm-sparc.h
diff --git a/gdb/config/sun4os3.mt b/gdb/config/sun4os3.mt
new file mode 100644 (file)
index 0000000..b90a65c
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 4 or Sparcstation, running SunOS 3
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o sparc-tdep.o sparc-pinsn.o
+TM_FILE= tm-sparc.h
diff --git a/gdb/config/sun4os4.mh b/gdb/config/sun4os4.mh
new file mode 100644 (file)
index 0000000..8054271
--- /dev/null
@@ -0,0 +1,21 @@
+# Sun 4 or Sparcstation, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o sparc-xdep.o
+XM_FILE= xm-sun4os4.h
diff --git a/gdb/config/sun4os4.mt b/gdb/config/sun4os4.mt
new file mode 100644 (file)
index 0000000..030872d
--- /dev/null
@@ -0,0 +1,26 @@
+# Sun 4 or Sparcstation, running SunOS 4
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# The system-supplied assembler re-orders the symbols so that gdb
+# can't find "gcc_compiled.".
+#msg If you compile your program with GCC, use the GNU assembler.
+#msg
+
+TDEPFILES= exec.o sparc-tdep.o sparc-pinsn.o solib.o
+TM_FILE= tm-sun4os4.h
diff --git a/gdb/config/symmetry.mh b/gdb/config/symmetry.mh
new file mode 100644 (file)
index 0000000..514c527
--- /dev/null
@@ -0,0 +1,21 @@
+# Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o symmetry-xdep.o
+XM_FILE= xm-symmetry.h
diff --git a/gdb/config/symmetry.mt b/gdb/config/symmetry.mt
new file mode 100644 (file)
index 0000000..4f2f37b
--- /dev/null
@@ -0,0 +1,21 @@
+# Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= symmetry-tdep.o i386-pinsn.o
+TM_FILE= tm-symmetry.h
diff --git a/gdb/config/umax.mh b/gdb/config/umax.mh
new file mode 100644 (file)
index 0000000..34e74d5
--- /dev/null
@@ -0,0 +1,21 @@
+# Encore running umax 4.2
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+XDEPFILES= infptrace.o umax-xdep.o
+XM_FILE= xm-umax.h
diff --git a/gdb/config/umax.mt b/gdb/config/umax.mt
new file mode 100644 (file)
index 0000000..994da6d
--- /dev/null
@@ -0,0 +1,21 @@
+# Encore running umax 4.2
+# Copyright (C) 1990 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o ns32k-pinsn.o
+TM_FILE= tm-umax.h
diff --git a/gdb/config/vax.mt b/gdb/config/vax.mt
new file mode 100644 (file)
index 0000000..a8e749a
--- /dev/null
@@ -0,0 +1,21 @@
+# DEC VAX running BSD or Ultrix
+# Copyright (C) 1989-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= vax-pinsn.o exec.o
+TM_FILE= tm-vax.h
diff --git a/gdb/config/vxworks68.mt b/gdb/config/vxworks68.mt
new file mode 100644 (file)
index 0000000..1514c0e
--- /dev/null
@@ -0,0 +1,21 @@
+# VxWorks running on a 68000, as a target system
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o m68k-pinsn.o m68k-tdep.o remote-vx.o xdr_ld.o xdr_ptrace.o xdr_rdb.o xdr_regs.o
+TM_FILE= tm-vxworks68.h
diff --git a/gdb/config/vxworks960.mt b/gdb/config/vxworks960.mt
new file mode 100644 (file)
index 0000000..1cc95e0
--- /dev/null
@@ -0,0 +1,23 @@
+# VxWorks running on an Intel 960, as a target system
+# Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+TDEPFILES= exec.o i960-pinsn.o i960-tdep.o remote-vx.o xdr_ld.o xdr_ptrace.o xdr_rdb.o xdr_regs.o
+TM_FILE= tm-vxworks960.h
+# Define this for the vx-share routines, which don't see param.h.
+TM_CFLAGS= -DI80960
diff --git a/gdb/convex-opcode.h b/gdb/convex-opcode.h
new file mode 100755 (executable)
index 0000000..523c874
--- /dev/null
@@ -0,0 +1,1677 @@
+/* Include information for instruction dissasembly on the Convex.
+   Copyright (C) 1989, Free Software Foundation.  
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define xxx 0
+#define rrr 1
+#define rr 2
+#define rxr 3
+#define r 4
+#define nops 5
+#define nr 6
+#define pcrel 7
+#define lr 8
+#define rxl 9
+#define rlr 10
+#define rrl 11
+#define iml 12
+#define imr 13
+#define a1r 14
+#define a1l 15
+#define a2r 16
+#define a2l 17
+#define a3 18
+#define a4 19
+#define a5 20
+#define V 1
+#define S 2
+#define VM 3
+#define A 4
+#define VL 5
+#define VS 6
+#define VLS 7
+#define PSW 8
+/* Prevent an error during "make depend".  */
+#if !defined (PC)
+#define PC 9
+#endif
+#define ITR 10
+#define VV 11
+#define ITSR 12
+#define TOC 13
+#define CIR 14
+#define TTR 15
+#define VMU 16
+#define VML 17
+#define ICR 18
+#define TCPU 19
+#define CPUID 20
+#define TID 21
+char *op[] = {
+  "",
+  "v0\0v1\0v2\0v3\0v4\0v5\0v6\0v7",
+  "s0\0s1\0s2\0s3\0s4\0s5\0s6\0s7",
+  "vm",
+  "sp\0a1\0a2\0a3\0a4\0a5\0ap\0fp",
+  "vl",
+  "vs",
+  "vls",
+  "psw",
+  "pc",
+  "itr",
+  "vv",
+  "itsr",
+  "toc",
+  "cir",
+  "ttr",
+  "vmu",
+  "vml",
+  "icr",
+  "tcpu",
+  "cpuid",
+  "tid",
+};
+struct formstr format0[] = {
+  {0,0,rrr,V,S,S},     /* mov */
+  {0,0,rrr,S,S,V},     /* mov */
+  {1,1,rrr,V,V,V},     /* merg.t */
+  {2,1,rrr,V,V,V},     /* mask.t */
+  {1,2,rrr,V,S,V},     /* merg.f */
+  {2,2,rrr,V,S,V},     /* mask.f */
+  {1,1,rrr,V,S,V},     /* merg.t */
+  {2,1,rrr,V,S,V},     /* mask.t */
+  {3,3,rrr,V,V,V},     /* mul.s */
+  {3,4,rrr,V,V,V},     /* mul.d */
+  {4,3,rrr,V,V,V},     /* div.s */
+  {4,4,rrr,V,V,V},     /* div.d */
+  {3,3,rrr,V,S,V},     /* mul.s */
+  {3,4,rrr,V,S,V},     /* mul.d */
+  {4,3,rrr,V,S,V},     /* div.s */
+  {4,4,rrr,V,S,V},     /* div.d */
+  {5,0,rrr,V,V,V},     /* and */
+  {6,0,rrr,V,V,V},     /* or */
+  {7,0,rrr,V,V,V},     /* xor */
+  {8,0,rrr,V,V,V},     /* shf */
+  {5,0,rrr,V,S,V},     /* and */
+  {6,0,rrr,V,S,V},     /* or */
+  {7,0,rrr,V,S,V},     /* xor */
+  {8,0,rrr,V,S,V},     /* shf */
+  {9,3,rrr,V,V,V},     /* add.s */
+  {9,4,rrr,V,V,V},     /* add.d */
+  {10,3,rrr,V,V,V},    /* sub.s */
+  {10,4,rrr,V,V,V},    /* sub.d */
+  {9,3,rrr,V,S,V},     /* add.s */
+  {9,4,rrr,V,S,V},     /* add.d */
+  {10,3,rrr,V,S,V},    /* sub.s */
+  {10,4,rrr,V,S,V},    /* sub.d */
+  {9,5,rrr,V,V,V},     /* add.b */
+  {9,6,rrr,V,V,V},     /* add.h */
+  {9,7,rrr,V,V,V},     /* add.w */
+  {9,8,rrr,V,V,V},     /* add.l */
+  {9,5,rrr,V,S,V},     /* add.b */
+  {9,6,rrr,V,S,V},     /* add.h */
+  {9,7,rrr,V,S,V},     /* add.w */
+  {9,8,rrr,V,S,V},     /* add.l */
+  {10,5,rrr,V,V,V},    /* sub.b */
+  {10,6,rrr,V,V,V},    /* sub.h */
+  {10,7,rrr,V,V,V},    /* sub.w */
+  {10,8,rrr,V,V,V},    /* sub.l */
+  {10,5,rrr,V,S,V},    /* sub.b */
+  {10,6,rrr,V,S,V},    /* sub.h */
+  {10,7,rrr,V,S,V},    /* sub.w */
+  {10,8,rrr,V,S,V},    /* sub.l */
+  {3,5,rrr,V,V,V},     /* mul.b */
+  {3,6,rrr,V,V,V},     /* mul.h */
+  {3,7,rrr,V,V,V},     /* mul.w */
+  {3,8,rrr,V,V,V},     /* mul.l */
+  {3,5,rrr,V,S,V},     /* mul.b */
+  {3,6,rrr,V,S,V},     /* mul.h */
+  {3,7,rrr,V,S,V},     /* mul.w */
+  {3,8,rrr,V,S,V},     /* mul.l */
+  {4,5,rrr,V,V,V},     /* div.b */
+  {4,6,rrr,V,V,V},     /* div.h */
+  {4,7,rrr,V,V,V},     /* div.w */
+  {4,8,rrr,V,V,V},     /* div.l */
+  {4,5,rrr,V,S,V},     /* div.b */
+  {4,6,rrr,V,S,V},     /* div.h */
+  {4,7,rrr,V,S,V},     /* div.w */
+  {4,8,rrr,V,S,V},     /* div.l */
+};
+struct formstr format1[] = {
+  {11,0,xxx,0,0,0},    /* exit */
+  {12,0,a3,0,0,0},     /* jmp */
+  {13,2,a3,0,0,0},     /* jmpi.f */
+  {13,1,a3,0,0,0},     /* jmpi.t */
+  {14,2,a3,0,0,0},     /* jmpa.f */
+  {14,1,a3,0,0,0},     /* jmpa.t */
+  {15,2,a3,0,0,0},     /* jmps.f */
+  {15,1,a3,0,0,0},     /* jmps.t */
+  {16,0,a3,0,0,0},     /* tac */
+  {17,0,a1r,A,0,0},    /* ldea */
+  {18,8,a1l,VLS,0,0},  /* ld.l */
+  {18,9,a1l,VM,0,0},   /* ld.x */
+  {19,0,a3,0,0,0},     /* tas */
+  {20,0,a3,0,0,0},     /* pshea */
+  {21,8,a2l,VLS,0,0},  /* st.l */
+  {21,9,a2l,VM,0,0},   /* st.x */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {22,0,a3,0,0,0},     /* call */
+  {23,0,a3,0,0,0},     /* calls */
+  {24,0,a3,0,0,0},     /* callq */
+  {25,0,a1r,A,0,0},    /* pfork */
+  {26,5,a2r,S,0,0},    /* ste.b */
+  {26,6,a2r,S,0,0},    /* ste.h */
+  {26,7,a2r,S,0,0},    /* ste.w */
+  {26,8,a2r,S,0,0},    /* ste.l */
+  {18,5,a1r,A,0,0},    /* ld.b */
+  {18,6,a1r,A,0,0},    /* ld.h */
+  {18,7,a1r,A,0,0},    /* ld.w */
+  {27,7,a1r,A,0,0},    /* incr.w */
+  {21,5,a2r,A,0,0},    /* st.b */
+  {21,6,a2r,A,0,0},    /* st.h */
+  {21,7,a2r,A,0,0},    /* st.w */
+  {27,8,a1r,S,0,0},    /* incr.l */
+  {18,5,a1r,S,0,0},    /* ld.b */
+  {18,6,a1r,S,0,0},    /* ld.h */
+  {18,7,a1r,S,0,0},    /* ld.w */
+  {18,8,a1r,S,0,0},    /* ld.l */
+  {21,5,a2r,S,0,0},    /* st.b */
+  {21,6,a2r,S,0,0},    /* st.h */
+  {21,7,a2r,S,0,0},    /* st.w */
+  {21,8,a2r,S,0,0},    /* st.l */
+  {18,5,a1r,V,0,0},    /* ld.b */
+  {18,6,a1r,V,0,0},    /* ld.h */
+  {18,7,a1r,V,0,0},    /* ld.w */
+  {18,8,a1r,V,0,0},    /* ld.l */
+  {21,5,a2r,V,0,0},    /* st.b */
+  {21,6,a2r,V,0,0},    /* st.h */
+  {21,7,a2r,V,0,0},    /* st.w */
+  {21,8,a2r,V,0,0},    /* st.l */
+};
+struct formstr format2[] = {
+  {28,5,rr,A,A,0},     /* cvtw.b */
+  {28,6,rr,A,A,0},     /* cvtw.h */
+  {29,7,rr,A,A,0},     /* cvtb.w */
+  {30,7,rr,A,A,0},     /* cvth.w */
+  {28,5,rr,S,S,0},     /* cvtw.b */
+  {28,6,rr,S,S,0},     /* cvtw.h */
+  {29,7,rr,S,S,0},     /* cvtb.w */
+  {30,7,rr,S,S,0},     /* cvth.w */
+  {28,3,rr,S,S,0},     /* cvtw.s */
+  {31,7,rr,S,S,0},     /* cvts.w */
+  {32,3,rr,S,S,0},     /* cvtd.s */
+  {31,4,rr,S,S,0},     /* cvts.d */
+  {31,8,rr,S,S,0},     /* cvts.l */
+  {32,8,rr,S,S,0},     /* cvtd.l */
+  {33,3,rr,S,S,0},     /* cvtl.s */
+  {33,4,rr,S,S,0},     /* cvtl.d */
+  {34,0,rr,A,A,0},     /* ldpa */
+  {8,0,nr,A,0,0},      /* shf */
+  {18,6,nr,A,0,0},     /* ld.h */
+  {18,7,nr,A,0,0},     /* ld.w */
+  {33,7,rr,S,S,0},     /* cvtl.w */
+  {28,8,rr,S,S,0},     /* cvtw.l */
+  {35,1,rr,S,S,0},     /* plc.t */
+  {36,0,rr,S,S,0},     /* tzc */
+  {37,6,rr,A,A,0},     /* eq.h */
+  {37,7,rr,A,A,0},     /* eq.w */
+  {37,6,nr,A,0,0},     /* eq.h */
+  {37,7,nr,A,0,0},     /* eq.w */
+  {37,5,rr,S,S,0},     /* eq.b */
+  {37,6,rr,S,S,0},     /* eq.h */
+  {37,7,rr,S,S,0},     /* eq.w */
+  {37,8,rr,S,S,0},     /* eq.l */
+  {38,6,rr,A,A,0},     /* leu.h */
+  {38,7,rr,A,A,0},     /* leu.w */
+  {38,6,nr,A,0,0},     /* leu.h */
+  {38,7,nr,A,0,0},     /* leu.w */
+  {38,5,rr,S,S,0},     /* leu.b */
+  {38,6,rr,S,S,0},     /* leu.h */
+  {38,7,rr,S,S,0},     /* leu.w */
+  {38,8,rr,S,S,0},     /* leu.l */
+  {39,6,rr,A,A,0},     /* ltu.h */
+  {39,7,rr,A,A,0},     /* ltu.w */
+  {39,6,nr,A,0,0},     /* ltu.h */
+  {39,7,nr,A,0,0},     /* ltu.w */
+  {39,5,rr,S,S,0},     /* ltu.b */
+  {39,6,rr,S,S,0},     /* ltu.h */
+  {39,7,rr,S,S,0},     /* ltu.w */
+  {39,8,rr,S,S,0},     /* ltu.l */
+  {40,6,rr,A,A,0},     /* le.h */
+  {40,7,rr,A,A,0},     /* le.w */
+  {40,6,nr,A,0,0},     /* le.h */
+  {40,7,nr,A,0,0},     /* le.w */
+  {40,5,rr,S,S,0},     /* le.b */
+  {40,6,rr,S,S,0},     /* le.h */
+  {40,7,rr,S,S,0},     /* le.w */
+  {40,8,rr,S,S,0},     /* le.l */
+  {41,6,rr,A,A,0},     /* lt.h */
+  {41,7,rr,A,A,0},     /* lt.w */
+  {41,6,nr,A,0,0},     /* lt.h */
+  {41,7,nr,A,0,0},     /* lt.w */
+  {41,5,rr,S,S,0},     /* lt.b */
+  {41,6,rr,S,S,0},     /* lt.h */
+  {41,7,rr,S,S,0},     /* lt.w */
+  {41,8,rr,S,S,0},     /* lt.l */
+  {9,7,rr,S,A,0},      /* add.w */
+  {8,0,rr,A,A,0},      /* shf */
+  {0,0,rr,A,A,0},      /* mov */
+  {0,0,rr,S,A,0},      /* mov */
+  {0,7,rr,S,S,0},      /* mov.w */
+  {8,0,rr,S,S,0},      /* shf */
+  {0,0,rr,S,S,0},      /* mov */
+  {0,0,rr,A,S,0},      /* mov */
+  {5,0,rr,A,A,0},      /* and */
+  {6,0,rr,A,A,0},      /* or */
+  {7,0,rr,A,A,0},      /* xor */
+  {42,0,rr,A,A,0},     /* not */
+  {5,0,rr,S,S,0},      /* and */
+  {6,0,rr,S,S,0},      /* or */
+  {7,0,rr,S,S,0},      /* xor */
+  {42,0,rr,S,S,0},     /* not */
+  {40,3,rr,S,S,0},     /* le.s */
+  {40,4,rr,S,S,0},     /* le.d */
+  {41,3,rr,S,S,0},     /* lt.s */
+  {41,4,rr,S,S,0},     /* lt.d */
+  {9,3,rr,S,S,0},      /* add.s */
+  {9,4,rr,S,S,0},      /* add.d */
+  {10,3,rr,S,S,0},     /* sub.s */
+  {10,4,rr,S,S,0},     /* sub.d */
+  {37,3,rr,S,S,0},     /* eq.s */
+  {37,4,rr,S,S,0},     /* eq.d */
+  {43,6,rr,A,A,0},     /* neg.h */
+  {43,7,rr,A,A,0},     /* neg.w */
+  {3,3,rr,S,S,0},      /* mul.s */
+  {3,4,rr,S,S,0},      /* mul.d */
+  {4,3,rr,S,S,0},      /* div.s */
+  {4,4,rr,S,S,0},      /* div.d */
+  {9,6,rr,A,A,0},      /* add.h */
+  {9,7,rr,A,A,0},      /* add.w */
+  {9,6,nr,A,0,0},      /* add.h */
+  {9,7,nr,A,0,0},      /* add.w */
+  {9,5,rr,S,S,0},      /* add.b */
+  {9,6,rr,S,S,0},      /* add.h */
+  {9,7,rr,S,S,0},      /* add.w */
+  {9,8,rr,S,S,0},      /* add.l */
+  {10,6,rr,A,A,0},     /* sub.h */
+  {10,7,rr,A,A,0},     /* sub.w */
+  {10,6,nr,A,0,0},     /* sub.h */
+  {10,7,nr,A,0,0},     /* sub.w */
+  {10,5,rr,S,S,0},     /* sub.b */
+  {10,6,rr,S,S,0},     /* sub.h */
+  {10,7,rr,S,S,0},     /* sub.w */
+  {10,8,rr,S,S,0},     /* sub.l */
+  {3,6,rr,A,A,0},      /* mul.h */
+  {3,7,rr,A,A,0},      /* mul.w */
+  {3,6,nr,A,0,0},      /* mul.h */
+  {3,7,nr,A,0,0},      /* mul.w */
+  {3,5,rr,S,S,0},      /* mul.b */
+  {3,6,rr,S,S,0},      /* mul.h */
+  {3,7,rr,S,S,0},      /* mul.w */
+  {3,8,rr,S,S,0},      /* mul.l */
+  {4,6,rr,A,A,0},      /* div.h */
+  {4,7,rr,A,A,0},      /* div.w */
+  {4,6,nr,A,0,0},      /* div.h */
+  {4,7,nr,A,0,0},      /* div.w */
+  {4,5,rr,S,S,0},      /* div.b */
+  {4,6,rr,S,S,0},      /* div.h */
+  {4,7,rr,S,S,0},      /* div.w */
+  {4,8,rr,S,S,0},      /* div.l */
+};
+struct formstr format3[] = {
+  {32,3,rr,V,V,0},     /* cvtd.s */
+  {31,4,rr,V,V,0},     /* cvts.d */
+  {33,4,rr,V,V,0},     /* cvtl.d */
+  {32,8,rr,V,V,0},     /* cvtd.l */
+  {0,0,rrl,S,S,VM},    /* mov */
+  {0,0,rlr,S,VM,S},    /* mov */
+  {0,0,0,0,0,0},
+  {44,0,rr,S,S,0},     /* lop */
+  {36,0,rr,V,V,0},     /* tzc */
+  {44,0,rr,V,V,0},     /* lop */
+  {0,0,0,0,0,0},
+  {42,0,rr,V,V,0},     /* not */
+  {8,0,rr,S,V,0},      /* shf */
+  {35,1,rr,V,V,0},     /* plc.t */
+  {45,2,rr,V,V,0},     /* cprs.f */
+  {45,1,rr,V,V,0},     /* cprs.t */
+  {37,3,rr,V,V,0},     /* eq.s */
+  {37,4,rr,V,V,0},     /* eq.d */
+  {43,3,rr,V,V,0},     /* neg.s */
+  {43,4,rr,V,V,0},     /* neg.d */
+  {37,3,rr,S,V,0},     /* eq.s */
+  {37,4,rr,S,V,0},     /* eq.d */
+  {43,3,rr,S,S,0},     /* neg.s */
+  {43,4,rr,S,S,0},     /* neg.d */
+  {40,3,rr,V,V,0},     /* le.s */
+  {40,4,rr,V,V,0},     /* le.d */
+  {41,3,rr,V,V,0},     /* lt.s */
+  {41,4,rr,V,V,0},     /* lt.d */
+  {40,3,rr,S,V,0},     /* le.s */
+  {40,4,rr,S,V,0},     /* le.d */
+  {41,3,rr,S,V,0},     /* lt.s */
+  {41,4,rr,S,V,0},     /* lt.d */
+  {37,5,rr,V,V,0},     /* eq.b */
+  {37,6,rr,V,V,0},     /* eq.h */
+  {37,7,rr,V,V,0},     /* eq.w */
+  {37,8,rr,V,V,0},     /* eq.l */
+  {37,5,rr,S,V,0},     /* eq.b */
+  {37,6,rr,S,V,0},     /* eq.h */
+  {37,7,rr,S,V,0},     /* eq.w */
+  {37,8,rr,S,V,0},     /* eq.l */
+  {40,5,rr,V,V,0},     /* le.b */
+  {40,6,rr,V,V,0},     /* le.h */
+  {40,7,rr,V,V,0},     /* le.w */
+  {40,8,rr,V,V,0},     /* le.l */
+  {40,5,rr,S,V,0},     /* le.b */
+  {40,6,rr,S,V,0},     /* le.h */
+  {40,7,rr,S,V,0},     /* le.w */
+  {40,8,rr,S,V,0},     /* le.l */
+  {41,5,rr,V,V,0},     /* lt.b */
+  {41,6,rr,V,V,0},     /* lt.h */
+  {41,7,rr,V,V,0},     /* lt.w */
+  {41,8,rr,V,V,0},     /* lt.l */
+  {41,5,rr,S,V,0},     /* lt.b */
+  {41,6,rr,S,V,0},     /* lt.h */
+  {41,7,rr,S,V,0},     /* lt.w */
+  {41,8,rr,S,V,0},     /* lt.l */
+  {43,5,rr,V,V,0},     /* neg.b */
+  {43,6,rr,V,V,0},     /* neg.h */
+  {43,7,rr,V,V,0},     /* neg.w */
+  {43,8,rr,V,V,0},     /* neg.l */
+  {43,5,rr,S,S,0},     /* neg.b */
+  {43,6,rr,S,S,0},     /* neg.h */
+  {43,7,rr,S,S,0},     /* neg.w */
+  {43,8,rr,S,S,0},     /* neg.l */
+};
+struct formstr format4[] = {
+  {46,0,nops,0,0,0},   /* nop */
+  {47,0,pcrel,0,0,0},  /* br */
+  {48,2,pcrel,0,0,0},  /* bri.f */
+  {48,1,pcrel,0,0,0},  /* bri.t */
+  {49,2,pcrel,0,0,0},  /* bra.f */
+  {49,1,pcrel,0,0,0},  /* bra.t */
+  {50,2,pcrel,0,0,0},  /* brs.f */
+  {50,1,pcrel,0,0,0},  /* brs.t */
+};
+struct formstr format5[] = {
+  {51,5,rr,V,V,0},     /* ldvi.b */
+  {51,6,rr,V,V,0},     /* ldvi.h */
+  {51,7,rr,V,V,0},     /* ldvi.w */
+  {51,8,rr,V,V,0},     /* ldvi.l */
+  {28,3,rr,V,V,0},     /* cvtw.s */
+  {31,7,rr,V,V,0},     /* cvts.w */
+  {28,8,rr,V,V,0},     /* cvtw.l */
+  {33,7,rr,V,V,0},     /* cvtl.w */
+  {52,5,rxr,V,V,0},    /* stvi.b */
+  {52,6,rxr,V,V,0},    /* stvi.h */
+  {52,7,rxr,V,V,0},    /* stvi.w */
+  {52,8,rxr,V,V,0},    /* stvi.l */
+  {52,5,rxr,S,V,0},    /* stvi.b */
+  {52,6,rxr,S,V,0},    /* stvi.h */
+  {52,7,rxr,S,V,0},    /* stvi.w */
+  {52,8,rxr,S,V,0},    /* stvi.l */
+};
+struct formstr format6[] = {
+  {53,0,r,A,0,0},      /* ldsdr */
+  {54,0,r,A,0,0},      /* ldkdr */
+  {55,3,r,S,0,0},      /* ln.s */
+  {55,4,r,S,0,0},      /* ln.d */
+  {56,0,nops,0,0,0},   /* patu */
+  {57,0,r,A,0,0},      /* pate */
+  {58,0,nops,0,0,0},   /* pich */
+  {59,0,nops,0,0,0},   /* plch */
+  {0,0,lr,PSW,A,0},    /* mov */
+  {0,0,rxl,A,PSW,0},   /* mov */
+  {0,0,lr,PC,A,0},     /* mov */
+  {60,0,r,S,0,0},      /* idle */
+  {0,0,lr,ITR,S,0},    /* mov */
+  {0,0,rxl,S,ITR,0},   /* mov */
+  {0,0,0,0,0,0},
+  {0,0,rxl,S,ITSR,0},  /* mov */
+  {61,0,nops,0,0,0},   /* rtnq */
+  {62,0,nops,0,0,0},   /* cfork */
+  {63,0,nops,0,0,0},   /* rtn */
+  {64,0,nops,0,0,0},   /* wfork */
+  {65,0,nops,0,0,0},   /* join */
+  {66,0,nops,0,0,0},   /* rtnc */
+  {67,3,r,S,0,0},      /* exp.s */
+  {67,4,r,S,0,0},      /* exp.d */
+  {68,3,r,S,0,0},      /* sin.s */
+  {68,4,r,S,0,0},      /* sin.d */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {69,3,r,S,0,0},      /* cos.s */
+  {69,4,r,S,0,0},      /* cos.d */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {70,7,r,A,0,0},      /* psh.w */
+  {0,0,0,0,0,0},
+  {71,7,r,A,0,0},      /* pop.w */
+  {0,0,0,0,0,0},
+  {70,7,r,S,0,0},      /* psh.w */
+  {70,8,r,S,0,0},      /* psh.l */
+  {71,7,r,S,0,0},      /* pop.w */
+  {71,8,r,S,0,0},      /* pop.l */
+  {72,0,nops,0,0,0},   /* eni */
+  {73,0,nops,0,0,0},   /* dsi */
+  {74,0,nops,0,0,0},   /* bkpt */
+  {75,0,nops,0,0,0},   /* msync */
+  {76,0,r,S,0,0},      /* mski */
+  {77,0,r,S,0,0},      /* xmti */
+  {0,0,rxl,S,VV,0},    /* mov */
+  {78,0,nops,0,0,0},   /* tstvv */
+  {0,0,lr,VS,A,0},     /* mov */
+  {0,0,rxl,A,VS,0},    /* mov */
+  {0,0,lr,VL,A,0},     /* mov */
+  {0,0,rxl,A,VL,0},    /* mov */
+  {0,7,lr,VS,S,0},     /* mov.w */
+  {0,7,rxl,S,VS,0},    /* mov.w */
+  {0,7,lr,VL,S,0},     /* mov.w */
+  {0,7,rxl,S,VL,0},    /* mov.w */
+  {79,0,r,A,0,0},      /* diag */
+  {80,0,nops,0,0,0},   /* pbkpt */
+  {81,3,r,S,0,0},      /* sqrt.s */
+  {81,4,r,S,0,0},      /* sqrt.d */
+  {82,0,nops,0,0,0},   /* casr */
+  {0,0,0,0,0,0},
+  {83,3,r,S,0,0},      /* atan.s */
+  {83,4,r,S,0,0},      /* atan.d */
+};
+struct formstr format7[] = {
+  {84,5,r,V,0,0},      /* sum.b */
+  {84,6,r,V,0,0},      /* sum.h */
+  {84,7,r,V,0,0},      /* sum.w */
+  {84,8,r,V,0,0},      /* sum.l */
+  {85,0,r,V,0,0},      /* all */
+  {86,0,r,V,0,0},      /* any */
+  {87,0,r,V,0,0},      /* parity */
+  {0,0,0,0,0,0},
+  {88,5,r,V,0,0},      /* max.b */
+  {88,6,r,V,0,0},      /* max.h */
+  {88,7,r,V,0,0},      /* max.w */
+  {88,8,r,V,0,0},      /* max.l */
+  {89,5,r,V,0,0},      /* min.b */
+  {89,6,r,V,0,0},      /* min.h */
+  {89,7,r,V,0,0},      /* min.w */
+  {89,8,r,V,0,0},      /* min.l */
+  {84,3,r,V,0,0},      /* sum.s */
+  {84,4,r,V,0,0},      /* sum.d */
+  {90,3,r,V,0,0},      /* prod.s */
+  {90,4,r,V,0,0},      /* prod.d */
+  {88,3,r,V,0,0},      /* max.s */
+  {88,4,r,V,0,0},      /* max.d */
+  {89,3,r,V,0,0},      /* min.s */
+  {89,4,r,V,0,0},      /* min.d */
+  {90,5,r,V,0,0},      /* prod.b */
+  {90,6,r,V,0,0},      /* prod.h */
+  {90,7,r,V,0,0},      /* prod.w */
+  {90,8,r,V,0,0},      /* prod.l */
+  {35,2,lr,VM,S,0},    /* plc.f */
+  {35,1,lr,VM,S,0},    /* plc.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr formatx[] = {
+  {0,0,0,0,0,0},
+};
+struct formstr format1a[] = {
+  {91,0,imr,A,0,0},    /* halt */
+  {92,0,a4,0,0,0},     /* sysc */
+  {18,6,imr,A,0,0},    /* ld.h */
+  {18,7,imr,A,0,0},    /* ld.w */
+  {5,0,imr,A,0,0},     /* and */
+  {6,0,imr,A,0,0},     /* or */
+  {7,0,imr,A,0,0},     /* xor */
+  {8,0,imr,A,0,0},     /* shf */
+  {9,6,imr,A,0,0},     /* add.h */
+  {9,7,imr,A,0,0},     /* add.w */
+  {10,6,imr,A,0,0},    /* sub.h */
+  {10,7,imr,A,0,0},    /* sub.w */
+  {3,6,imr,A,0,0},     /* mul.h */
+  {3,7,imr,A,0,0},     /* mul.w */
+  {4,6,imr,A,0,0},     /* div.h */
+  {4,7,imr,A,0,0},     /* div.w */
+  {18,7,iml,VL,0,0},   /* ld.w */
+  {18,7,iml,VS,0,0},   /* ld.w */
+  {0,0,0,0,0,0},
+  {8,7,imr,S,0,0},     /* shf.w */
+  {93,0,a5,0,0,0},     /* trap */
+  {0,0,0,0,0,0},
+  {37,6,imr,A,0,0},    /* eq.h */
+  {37,7,imr,A,0,0},    /* eq.w */
+  {38,6,imr,A,0,0},    /* leu.h */
+  {38,7,imr,A,0,0},    /* leu.w */
+  {39,6,imr,A,0,0},    /* ltu.h */
+  {39,7,imr,A,0,0},    /* ltu.w */
+  {40,6,imr,A,0,0},    /* le.h */
+  {40,7,imr,A,0,0},    /* le.w */
+  {41,6,imr,A,0,0},    /* lt.h */
+  {41,7,imr,A,0,0},    /* lt.w */
+};
+struct formstr format1b[] = {
+  {18,4,imr,S,0,0},    /* ld.d */
+  {18,10,imr,S,0,0},   /* ld.u */
+  {18,8,imr,S,0,0},    /* ld.l */
+  {18,7,imr,S,0,0},    /* ld.w */
+  {5,0,imr,S,0,0},     /* and */
+  {6,0,imr,S,0,0},     /* or */
+  {7,0,imr,S,0,0},     /* xor */
+  {8,0,imr,S,0,0},     /* shf */
+  {9,6,imr,S,0,0},     /* add.h */
+  {9,7,imr,S,0,0},     /* add.w */
+  {10,6,imr,S,0,0},    /* sub.h */
+  {10,7,imr,S,0,0},    /* sub.w */
+  {3,6,imr,S,0,0},     /* mul.h */
+  {3,7,imr,S,0,0},     /* mul.w */
+  {4,6,imr,S,0,0},     /* div.h */
+  {4,7,imr,S,0,0},     /* div.w */
+  {9,3,imr,S,0,0},     /* add.s */
+  {10,3,imr,S,0,0},    /* sub.s */
+  {3,3,imr,S,0,0},     /* mul.s */
+  {4,3,imr,S,0,0},     /* div.s */
+  {40,3,imr,S,0,0},    /* le.s */
+  {41,3,imr,S,0,0},    /* lt.s */
+  {37,6,imr,S,0,0},    /* eq.h */
+  {37,7,imr,S,0,0},    /* eq.w */
+  {38,6,imr,S,0,0},    /* leu.h */
+  {38,7,imr,S,0,0},    /* leu.w */
+  {39,6,imr,S,0,0},    /* ltu.h */
+  {39,7,imr,S,0,0},    /* ltu.w */
+  {40,6,imr,S,0,0},    /* le.h */
+  {40,7,imr,S,0,0},    /* le.w */
+  {41,6,imr,S,0,0},    /* lt.h */
+  {41,7,imr,S,0,0},    /* lt.w */
+};
+struct formstr e0_format0[] = {
+  {10,3,rrr,S,V,V},    /* sub.s */
+  {10,4,rrr,S,V,V},    /* sub.d */
+  {4,3,rrr,S,V,V},     /* div.s */
+  {4,4,rrr,S,V,V},     /* div.d */
+  {10,11,rrr,S,V,V},   /* sub.s.f */
+  {10,12,rrr,S,V,V},   /* sub.d.f */
+  {4,11,rrr,S,V,V},    /* div.s.f */
+  {4,12,rrr,S,V,V},    /* div.d.f */
+  {3,11,rrr,V,V,V},    /* mul.s.f */
+  {3,12,rrr,V,V,V},    /* mul.d.f */
+  {4,11,rrr,V,V,V},    /* div.s.f */
+  {4,12,rrr,V,V,V},    /* div.d.f */
+  {3,11,rrr,V,S,V},    /* mul.s.f */
+  {3,12,rrr,V,S,V},    /* mul.d.f */
+  {4,11,rrr,V,S,V},    /* div.s.f */
+  {4,12,rrr,V,S,V},    /* div.d.f */
+  {5,2,rrr,V,V,V},     /* and.f */
+  {6,2,rrr,V,V,V},     /* or.f */
+  {7,2,rrr,V,V,V},     /* xor.f */
+  {8,2,rrr,V,V,V},     /* shf.f */
+  {5,2,rrr,V,S,V},     /* and.f */
+  {6,2,rrr,V,S,V},     /* or.f */
+  {7,2,rrr,V,S,V},     /* xor.f */
+  {8,2,rrr,V,S,V},     /* shf.f */
+  {9,11,rrr,V,V,V},    /* add.s.f */
+  {9,12,rrr,V,V,V},    /* add.d.f */
+  {10,11,rrr,V,V,V},   /* sub.s.f */
+  {10,12,rrr,V,V,V},   /* sub.d.f */
+  {9,11,rrr,V,S,V},    /* add.s.f */
+  {9,12,rrr,V,S,V},    /* add.d.f */
+  {10,11,rrr,V,S,V},   /* sub.s.f */
+  {10,12,rrr,V,S,V},   /* sub.d.f */
+  {9,13,rrr,V,V,V},    /* add.b.f */
+  {9,14,rrr,V,V,V},    /* add.h.f */
+  {9,15,rrr,V,V,V},    /* add.w.f */
+  {9,16,rrr,V,V,V},    /* add.l.f */
+  {9,13,rrr,V,S,V},    /* add.b.f */
+  {9,14,rrr,V,S,V},    /* add.h.f */
+  {9,15,rrr,V,S,V},    /* add.w.f */
+  {9,16,rrr,V,S,V},    /* add.l.f */
+  {10,13,rrr,V,V,V},   /* sub.b.f */
+  {10,14,rrr,V,V,V},   /* sub.h.f */
+  {10,15,rrr,V,V,V},   /* sub.w.f */
+  {10,16,rrr,V,V,V},   /* sub.l.f */
+  {10,13,rrr,V,S,V},   /* sub.b.f */
+  {10,14,rrr,V,S,V},   /* sub.h.f */
+  {10,15,rrr,V,S,V},   /* sub.w.f */
+  {10,16,rrr,V,S,V},   /* sub.l.f */
+  {3,13,rrr,V,V,V},    /* mul.b.f */
+  {3,14,rrr,V,V,V},    /* mul.h.f */
+  {3,15,rrr,V,V,V},    /* mul.w.f */
+  {3,16,rrr,V,V,V},    /* mul.l.f */
+  {3,13,rrr,V,S,V},    /* mul.b.f */
+  {3,14,rrr,V,S,V},    /* mul.h.f */
+  {3,15,rrr,V,S,V},    /* mul.w.f */
+  {3,16,rrr,V,S,V},    /* mul.l.f */
+  {4,13,rrr,V,V,V},    /* div.b.f */
+  {4,14,rrr,V,V,V},    /* div.h.f */
+  {4,15,rrr,V,V,V},    /* div.w.f */
+  {4,16,rrr,V,V,V},    /* div.l.f */
+  {4,13,rrr,V,S,V},    /* div.b.f */
+  {4,14,rrr,V,S,V},    /* div.h.f */
+  {4,15,rrr,V,S,V},    /* div.w.f */
+  {4,16,rrr,V,S,V},    /* div.l.f */
+};
+struct formstr e0_format1[] = {
+  {0,0,0,0,0,0},
+  {94,0,a3,0,0,0},     /* tst */
+  {95,0,a3,0,0,0},     /* lck */
+  {96,0,a3,0,0,0},     /* ulk */
+  {17,0,a1r,S,0,0},    /* ldea */
+  {97,0,a1r,A,0,0},    /* spawn */
+  {98,0,a1r,A,0,0},    /* ldcmr */
+  {99,0,a2r,A,0,0},    /* stcmr */
+  {100,0,a1r,A,0,0},   /* popr */
+  {101,0,a2r,A,0,0},   /* pshr */
+  {102,7,a1r,A,0,0},   /* rcvr.w */
+  {103,7,a2r,A,0,0},   /* matm.w */
+  {104,7,a2r,A,0,0},   /* sndr.w */
+  {104,8,a2r,S,0,0},   /* sndr.l */
+  {102,8,a1r,S,0,0},   /* rcvr.l */
+  {103,8,a2r,S,0,0},   /* matm.l */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {105,7,a2r,A,0,0},   /* putr.w */
+  {105,8,a2r,S,0,0},   /* putr.l */
+  {106,7,a1r,A,0,0},   /* getr.w */
+  {106,8,a1r,S,0,0},   /* getr.l */
+  {26,13,a2r,S,0,0},   /* ste.b.f */
+  {26,14,a2r,S,0,0},   /* ste.h.f */
+  {26,15,a2r,S,0,0},   /* ste.w.f */
+  {26,16,a2r,S,0,0},   /* ste.l.f */
+  {107,7,a2r,A,0,0},   /* matr.w */
+  {108,7,a2r,A,0,0},   /* mat.w */
+  {109,7,a1r,A,0,0},   /* get.w */
+  {110,7,a1r,A,0,0},   /* rcv.w */
+  {0,0,0,0,0,0},
+  {111,7,a1r,A,0,0},   /* inc.w */
+  {112,7,a2r,A,0,0},   /* put.w */
+  {113,7,a2r,A,0,0},   /* snd.w */
+  {107,8,a2r,S,0,0},   /* matr.l */
+  {108,8,a2r,S,0,0},   /* mat.l */
+  {109,8,a1r,S,0,0},   /* get.l */
+  {110,8,a1r,S,0,0},   /* rcv.l */
+  {0,0,0,0,0,0},
+  {111,8,a1r,S,0,0},   /* inc.l */
+  {112,8,a2r,S,0,0},   /* put.l */
+  {113,8,a2r,S,0,0},   /* snd.l */
+  {18,13,a1r,V,0,0},   /* ld.b.f */
+  {18,14,a1r,V,0,0},   /* ld.h.f */
+  {18,15,a1r,V,0,0},   /* ld.w.f */
+  {18,16,a1r,V,0,0},   /* ld.l.f */
+  {21,13,a2r,V,0,0},   /* st.b.f */
+  {21,14,a2r,V,0,0},   /* st.h.f */
+  {21,15,a2r,V,0,0},   /* st.w.f */
+  {21,16,a2r,V,0,0},   /* st.l.f */
+};
+struct formstr e0_format2[] = {
+  {28,5,rr,V,V,0},     /* cvtw.b */
+  {28,6,rr,V,V,0},     /* cvtw.h */
+  {29,7,rr,V,V,0},     /* cvtb.w */
+  {30,7,rr,V,V,0},     /* cvth.w */
+  {28,13,rr,V,V,0},    /* cvtw.b.f */
+  {28,14,rr,V,V,0},    /* cvtw.h.f */
+  {29,15,rr,V,V,0},    /* cvtb.w.f */
+  {30,15,rr,V,V,0},    /* cvth.w.f */
+  {31,8,rr,V,V,0},     /* cvts.l */
+  {32,7,rr,V,V,0},     /* cvtd.w */
+  {33,3,rr,V,V,0},     /* cvtl.s */
+  {28,4,rr,V,V,0},     /* cvtw.d */
+  {31,16,rr,V,V,0},    /* cvts.l.f */
+  {32,15,rr,V,V,0},    /* cvtd.w.f */
+  {33,11,rr,V,V,0},    /* cvtl.s.f */
+  {28,12,rr,V,V,0},    /* cvtw.d.f */
+  {114,0,rr,S,S,0},    /* enal */
+  {8,7,rr,S,S,0},      /* shf.w */
+  {115,0,rr,S,S,0},    /* enag */
+  {0,0,0,0,0,0},
+  {28,4,rr,S,S,0},     /* cvtw.d */
+  {32,7,rr,S,S,0},     /* cvtd.w */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {116,3,rr,S,S,0},    /* frint.s */
+  {116,4,rr,S,S,0},    /* frint.d */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {116,3,rr,V,V,0},    /* frint.s */
+  {116,4,rr,V,V,0},    /* frint.d */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {116,11,rr,V,V,0},   /* frint.s.f */
+  {116,12,rr,V,V,0},   /* frint.d.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {81,3,rr,V,V,0},     /* sqrt.s */
+  {81,4,rr,V,V,0},     /* sqrt.d */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {81,11,rr,V,V,0},    /* sqrt.s.f */
+  {81,12,rr,V,V,0},    /* sqrt.d.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e0_format3[] = {
+  {32,11,rr,V,V,0},    /* cvtd.s.f */
+  {31,12,rr,V,V,0},    /* cvts.d.f */
+  {33,12,rr,V,V,0},    /* cvtl.d.f */
+  {32,16,rr,V,V,0},    /* cvtd.l.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {36,2,rr,V,V,0},     /* tzc.f */
+  {44,2,rr,V,V,0},     /* lop.f */
+  {117,2,rr,V,V,0},    /* xpnd.f */
+  {42,2,rr,V,V,0},     /* not.f */
+  {8,2,rr,S,V,0},      /* shf.f */
+  {35,17,rr,V,V,0},    /* plc.t.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {37,11,rr,V,V,0},    /* eq.s.f */
+  {37,12,rr,V,V,0},    /* eq.d.f */
+  {43,11,rr,V,V,0},    /* neg.s.f */
+  {43,12,rr,V,V,0},    /* neg.d.f */
+  {37,11,rr,S,V,0},    /* eq.s.f */
+  {37,12,rr,S,V,0},    /* eq.d.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {40,11,rr,V,V,0},    /* le.s.f */
+  {40,12,rr,V,V,0},    /* le.d.f */
+  {41,11,rr,V,V,0},    /* lt.s.f */
+  {41,12,rr,V,V,0},    /* lt.d.f */
+  {40,11,rr,S,V,0},    /* le.s.f */
+  {40,12,rr,S,V,0},    /* le.d.f */
+  {41,11,rr,S,V,0},    /* lt.s.f */
+  {41,12,rr,S,V,0},    /* lt.d.f */
+  {37,13,rr,V,V,0},    /* eq.b.f */
+  {37,14,rr,V,V,0},    /* eq.h.f */
+  {37,15,rr,V,V,0},    /* eq.w.f */
+  {37,16,rr,V,V,0},    /* eq.l.f */
+  {37,13,rr,S,V,0},    /* eq.b.f */
+  {37,14,rr,S,V,0},    /* eq.h.f */
+  {37,15,rr,S,V,0},    /* eq.w.f */
+  {37,16,rr,S,V,0},    /* eq.l.f */
+  {40,13,rr,V,V,0},    /* le.b.f */
+  {40,14,rr,V,V,0},    /* le.h.f */
+  {40,15,rr,V,V,0},    /* le.w.f */
+  {40,16,rr,V,V,0},    /* le.l.f */
+  {40,13,rr,S,V,0},    /* le.b.f */
+  {40,14,rr,S,V,0},    /* le.h.f */
+  {40,15,rr,S,V,0},    /* le.w.f */
+  {40,16,rr,S,V,0},    /* le.l.f */
+  {41,13,rr,V,V,0},    /* lt.b.f */
+  {41,14,rr,V,V,0},    /* lt.h.f */
+  {41,15,rr,V,V,0},    /* lt.w.f */
+  {41,16,rr,V,V,0},    /* lt.l.f */
+  {41,13,rr,S,V,0},    /* lt.b.f */
+  {41,14,rr,S,V,0},    /* lt.h.f */
+  {41,15,rr,S,V,0},    /* lt.w.f */
+  {41,16,rr,S,V,0},    /* lt.l.f */
+  {43,13,rr,V,V,0},    /* neg.b.f */
+  {43,14,rr,V,V,0},    /* neg.h.f */
+  {43,15,rr,V,V,0},    /* neg.w.f */
+  {43,16,rr,V,V,0},    /* neg.l.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e0_format4[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e0_format5[] = {
+  {51,13,rr,V,V,0},    /* ldvi.b.f */
+  {51,14,rr,V,V,0},    /* ldvi.h.f */
+  {51,15,rr,V,V,0},    /* ldvi.w.f */
+  {51,16,rr,V,V,0},    /* ldvi.l.f */
+  {28,11,rr,V,V,0},    /* cvtw.s.f */
+  {31,15,rr,V,V,0},    /* cvts.w.f */
+  {28,16,rr,V,V,0},    /* cvtw.l.f */
+  {33,15,rr,V,V,0},    /* cvtl.w.f */
+  {52,13,rxr,V,V,0},   /* stvi.b.f */
+  {52,14,rxr,V,V,0},   /* stvi.h.f */
+  {52,15,rxr,V,V,0},   /* stvi.w.f */
+  {52,16,rxr,V,V,0},   /* stvi.l.f */
+  {52,13,rxr,S,V,0},   /* stvi.b.f */
+  {52,14,rxr,S,V,0},   /* stvi.h.f */
+  {52,15,rxr,S,V,0},   /* stvi.w.f */
+  {52,16,rxr,S,V,0},   /* stvi.l.f */
+};
+struct formstr e0_format6[] = {
+  {0,0,rxl,S,CIR,0},   /* mov */
+  {0,0,lr,CIR,S,0},    /* mov */
+  {0,0,lr,TOC,S,0},    /* mov */
+  {0,0,lr,CPUID,S,0},  /* mov */
+  {0,0,rxl,S,TTR,0},   /* mov */
+  {0,0,lr,TTR,S,0},    /* mov */
+  {118,0,nops,0,0,0},  /* ctrsl */
+  {119,0,nops,0,0,0},  /* ctrsg */
+  {0,0,rxl,S,VMU,0},   /* mov */
+  {0,0,lr,VMU,S,0},    /* mov */
+  {0,0,rxl,S,VML,0},   /* mov */
+  {0,0,lr,VML,S,0},    /* mov */
+  {0,0,rxl,S,ICR,0},   /* mov */
+  {0,0,lr,ICR,S,0},    /* mov */
+  {0,0,rxl,S,TCPU,0},  /* mov */
+  {0,0,lr,TCPU,S,0},   /* mov */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {120,0,nops,0,0,0},  /* stop */
+  {0,0,0,0,0,0},
+  {0,0,rxl,S,TID,0},   /* mov */
+  {0,0,lr,TID,S,0},    /* mov */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e0_format7[] = {
+  {84,13,r,V,0,0},     /* sum.b.f */
+  {84,14,r,V,0,0},     /* sum.h.f */
+  {84,15,r,V,0,0},     /* sum.w.f */
+  {84,16,r,V,0,0},     /* sum.l.f */
+  {85,2,r,V,0,0},      /* all.f */
+  {86,2,r,V,0,0},      /* any.f */
+  {87,2,r,V,0,0},      /* parity.f */
+  {0,0,0,0,0,0},
+  {88,13,r,V,0,0},     /* max.b.f */
+  {88,14,r,V,0,0},     /* max.h.f */
+  {88,15,r,V,0,0},     /* max.w.f */
+  {88,16,r,V,0,0},     /* max.l.f */
+  {89,13,r,V,0,0},     /* min.b.f */
+  {89,14,r,V,0,0},     /* min.h.f */
+  {89,15,r,V,0,0},     /* min.w.f */
+  {89,16,r,V,0,0},     /* min.l.f */
+  {84,11,r,V,0,0},     /* sum.s.f */
+  {84,12,r,V,0,0},     /* sum.d.f */
+  {90,11,r,V,0,0},     /* prod.s.f */
+  {90,12,r,V,0,0},     /* prod.d.f */
+  {88,11,r,V,0,0},     /* max.s.f */
+  {88,12,r,V,0,0},     /* max.d.f */
+  {89,11,r,V,0,0},     /* min.s.f */
+  {89,12,r,V,0,0},     /* min.d.f */
+  {90,13,r,V,0,0},     /* prod.b.f */
+  {90,14,r,V,0,0},     /* prod.h.f */
+  {90,15,r,V,0,0},     /* prod.w.f */
+  {90,16,r,V,0,0},     /* prod.l.f */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e1_format0[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {10,18,rrr,S,V,V},   /* sub.s.t */
+  {10,19,rrr,S,V,V},   /* sub.d.t */
+  {4,18,rrr,S,V,V},    /* div.s.t */
+  {4,19,rrr,S,V,V},    /* div.d.t */
+  {3,18,rrr,V,V,V},    /* mul.s.t */
+  {3,19,rrr,V,V,V},    /* mul.d.t */
+  {4,18,rrr,V,V,V},    /* div.s.t */
+  {4,19,rrr,V,V,V},    /* div.d.t */
+  {3,18,rrr,V,S,V},    /* mul.s.t */
+  {3,19,rrr,V,S,V},    /* mul.d.t */
+  {4,18,rrr,V,S,V},    /* div.s.t */
+  {4,19,rrr,V,S,V},    /* div.d.t */
+  {5,1,rrr,V,V,V},     /* and.t */
+  {6,1,rrr,V,V,V},     /* or.t */
+  {7,1,rrr,V,V,V},     /* xor.t */
+  {8,1,rrr,V,V,V},     /* shf.t */
+  {5,1,rrr,V,S,V},     /* and.t */
+  {6,1,rrr,V,S,V},     /* or.t */
+  {7,1,rrr,V,S,V},     /* xor.t */
+  {8,1,rrr,V,S,V},     /* shf.t */
+  {9,18,rrr,V,V,V},    /* add.s.t */
+  {9,19,rrr,V,V,V},    /* add.d.t */
+  {10,18,rrr,V,V,V},   /* sub.s.t */
+  {10,19,rrr,V,V,V},   /* sub.d.t */
+  {9,18,rrr,V,S,V},    /* add.s.t */
+  {9,19,rrr,V,S,V},    /* add.d.t */
+  {10,18,rrr,V,S,V},   /* sub.s.t */
+  {10,19,rrr,V,S,V},   /* sub.d.t */
+  {9,20,rrr,V,V,V},    /* add.b.t */
+  {9,21,rrr,V,V,V},    /* add.h.t */
+  {9,22,rrr,V,V,V},    /* add.w.t */
+  {9,23,rrr,V,V,V},    /* add.l.t */
+  {9,20,rrr,V,S,V},    /* add.b.t */
+  {9,21,rrr,V,S,V},    /* add.h.t */
+  {9,22,rrr,V,S,V},    /* add.w.t */
+  {9,23,rrr,V,S,V},    /* add.l.t */
+  {10,20,rrr,V,V,V},   /* sub.b.t */
+  {10,21,rrr,V,V,V},   /* sub.h.t */
+  {10,22,rrr,V,V,V},   /* sub.w.t */
+  {10,23,rrr,V,V,V},   /* sub.l.t */
+  {10,20,rrr,V,S,V},   /* sub.b.t */
+  {10,21,rrr,V,S,V},   /* sub.h.t */
+  {10,22,rrr,V,S,V},   /* sub.w.t */
+  {10,23,rrr,V,S,V},   /* sub.l.t */
+  {3,20,rrr,V,V,V},    /* mul.b.t */
+  {3,21,rrr,V,V,V},    /* mul.h.t */
+  {3,22,rrr,V,V,V},    /* mul.w.t */
+  {3,23,rrr,V,V,V},    /* mul.l.t */
+  {3,20,rrr,V,S,V},    /* mul.b.t */
+  {3,21,rrr,V,S,V},    /* mul.h.t */
+  {3,22,rrr,V,S,V},    /* mul.w.t */
+  {3,23,rrr,V,S,V},    /* mul.l.t */
+  {4,20,rrr,V,V,V},    /* div.b.t */
+  {4,21,rrr,V,V,V},    /* div.h.t */
+  {4,22,rrr,V,V,V},    /* div.w.t */
+  {4,23,rrr,V,V,V},    /* div.l.t */
+  {4,20,rrr,V,S,V},    /* div.b.t */
+  {4,21,rrr,V,S,V},    /* div.h.t */
+  {4,22,rrr,V,S,V},    /* div.w.t */
+  {4,23,rrr,V,S,V},    /* div.l.t */
+};
+struct formstr e1_format1[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {26,20,a2r,S,0,0},   /* ste.b.t */
+  {26,21,a2r,S,0,0},   /* ste.h.t */
+  {26,22,a2r,S,0,0},   /* ste.w.t */
+  {26,23,a2r,S,0,0},   /* ste.l.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {18,20,a1r,V,0,0},   /* ld.b.t */
+  {18,21,a1r,V,0,0},   /* ld.h.t */
+  {18,22,a1r,V,0,0},   /* ld.w.t */
+  {18,23,a1r,V,0,0},   /* ld.l.t */
+  {21,20,a2r,V,0,0},   /* st.b.t */
+  {21,21,a2r,V,0,0},   /* st.h.t */
+  {21,22,a2r,V,0,0},   /* st.w.t */
+  {21,23,a2r,V,0,0},   /* st.l.t */
+};
+struct formstr e1_format2[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {28,20,rr,V,V,0},    /* cvtw.b.t */
+  {28,21,rr,V,V,0},    /* cvtw.h.t */
+  {29,22,rr,V,V,0},    /* cvtb.w.t */
+  {30,22,rr,V,V,0},    /* cvth.w.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {31,23,rr,V,V,0},    /* cvts.l.t */
+  {32,22,rr,V,V,0},    /* cvtd.w.t */
+  {33,18,rr,V,V,0},    /* cvtl.s.t */
+  {28,19,rr,V,V,0},    /* cvtw.d.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {116,18,rr,V,V,0},   /* frint.s.t */
+  {116,19,rr,V,V,0},   /* frint.d.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {81,18,rr,V,V,0},    /* sqrt.s.t */
+  {81,19,rr,V,V,0},    /* sqrt.d.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e1_format3[] = {
+  {32,18,rr,V,V,0},    /* cvtd.s.t */
+  {31,19,rr,V,V,0},    /* cvts.d.t */
+  {33,19,rr,V,V,0},    /* cvtl.d.t */
+  {32,23,rr,V,V,0},    /* cvtd.l.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {36,1,rr,V,V,0},     /* tzc.t */
+  {44,1,rr,V,V,0},     /* lop.t */
+  {117,1,rr,V,V,0},    /* xpnd.t */
+  {42,1,rr,V,V,0},     /* not.t */
+  {8,1,rr,S,V,0},      /* shf.t */
+  {35,24,rr,V,V,0},    /* plc.t.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {37,18,rr,V,V,0},    /* eq.s.t */
+  {37,19,rr,V,V,0},    /* eq.d.t */
+  {43,18,rr,V,V,0},    /* neg.s.t */
+  {43,19,rr,V,V,0},    /* neg.d.t */
+  {37,18,rr,S,V,0},    /* eq.s.t */
+  {37,19,rr,S,V,0},    /* eq.d.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {40,18,rr,V,V,0},    /* le.s.t */
+  {40,19,rr,V,V,0},    /* le.d.t */
+  {41,18,rr,V,V,0},    /* lt.s.t */
+  {41,19,rr,V,V,0},    /* lt.d.t */
+  {40,18,rr,S,V,0},    /* le.s.t */
+  {40,19,rr,S,V,0},    /* le.d.t */
+  {41,18,rr,S,V,0},    /* lt.s.t */
+  {41,19,rr,S,V,0},    /* lt.d.t */
+  {37,20,rr,V,V,0},    /* eq.b.t */
+  {37,21,rr,V,V,0},    /* eq.h.t */
+  {37,22,rr,V,V,0},    /* eq.w.t */
+  {37,23,rr,V,V,0},    /* eq.l.t */
+  {37,20,rr,S,V,0},    /* eq.b.t */
+  {37,21,rr,S,V,0},    /* eq.h.t */
+  {37,22,rr,S,V,0},    /* eq.w.t */
+  {37,23,rr,S,V,0},    /* eq.l.t */
+  {40,20,rr,V,V,0},    /* le.b.t */
+  {40,21,rr,V,V,0},    /* le.h.t */
+  {40,22,rr,V,V,0},    /* le.w.t */
+  {40,23,rr,V,V,0},    /* le.l.t */
+  {40,20,rr,S,V,0},    /* le.b.t */
+  {40,21,rr,S,V,0},    /* le.h.t */
+  {40,22,rr,S,V,0},    /* le.w.t */
+  {40,23,rr,S,V,0},    /* le.l.t */
+  {41,20,rr,V,V,0},    /* lt.b.t */
+  {41,21,rr,V,V,0},    /* lt.h.t */
+  {41,22,rr,V,V,0},    /* lt.w.t */
+  {41,23,rr,V,V,0},    /* lt.l.t */
+  {41,20,rr,S,V,0},    /* lt.b.t */
+  {41,21,rr,S,V,0},    /* lt.h.t */
+  {41,22,rr,S,V,0},    /* lt.w.t */
+  {41,23,rr,S,V,0},    /* lt.l.t */
+  {43,20,rr,V,V,0},    /* neg.b.t */
+  {43,21,rr,V,V,0},    /* neg.h.t */
+  {43,22,rr,V,V,0},    /* neg.w.t */
+  {43,23,rr,V,V,0},    /* neg.l.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e1_format4[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e1_format5[] = {
+  {51,20,rr,V,V,0},    /* ldvi.b.t */
+  {51,21,rr,V,V,0},    /* ldvi.h.t */
+  {51,22,rr,V,V,0},    /* ldvi.w.t */
+  {51,23,rr,V,V,0},    /* ldvi.l.t */
+  {28,18,rr,V,V,0},    /* cvtw.s.t */
+  {31,22,rr,V,V,0},    /* cvts.w.t */
+  {28,23,rr,V,V,0},    /* cvtw.l.t */
+  {33,22,rr,V,V,0},    /* cvtl.w.t */
+  {52,20,rxr,V,V,0},   /* stvi.b.t */
+  {52,21,rxr,V,V,0},   /* stvi.h.t */
+  {52,22,rxr,V,V,0},   /* stvi.w.t */
+  {52,23,rxr,V,V,0},   /* stvi.l.t */
+  {52,20,rxr,S,V,0},   /* stvi.b.t */
+  {52,21,rxr,S,V,0},   /* stvi.h.t */
+  {52,22,rxr,S,V,0},   /* stvi.w.t */
+  {52,23,rxr,S,V,0},   /* stvi.l.t */
+};
+struct formstr e1_format6[] = {
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+struct formstr e1_format7[] = {
+  {84,20,r,V,0,0},     /* sum.b.t */
+  {84,21,r,V,0,0},     /* sum.h.t */
+  {84,22,r,V,0,0},     /* sum.w.t */
+  {84,23,r,V,0,0},     /* sum.l.t */
+  {85,1,r,V,0,0},      /* all.t */
+  {86,1,r,V,0,0},      /* any.t */
+  {87,1,r,V,0,0},      /* parity.t */
+  {0,0,0,0,0,0},
+  {88,20,r,V,0,0},     /* max.b.t */
+  {88,21,r,V,0,0},     /* max.h.t */
+  {88,22,r,V,0,0},     /* max.w.t */
+  {88,23,r,V,0,0},     /* max.l.t */
+  {89,20,r,V,0,0},     /* min.b.t */
+  {89,21,r,V,0,0},     /* min.h.t */
+  {89,22,r,V,0,0},     /* min.w.t */
+  {89,23,r,V,0,0},     /* min.l.t */
+  {84,18,r,V,0,0},     /* sum.s.t */
+  {84,19,r,V,0,0},     /* sum.d.t */
+  {90,18,r,V,0,0},     /* prod.s.t */
+  {90,19,r,V,0,0},     /* prod.d.t */
+  {88,18,r,V,0,0},     /* max.s.t */
+  {88,19,r,V,0,0},     /* max.d.t */
+  {89,18,r,V,0,0},     /* min.s.t */
+  {89,19,r,V,0,0},     /* min.d.t */
+  {90,20,r,V,0,0},     /* prod.b.t */
+  {90,21,r,V,0,0},     /* prod.h.t */
+  {90,22,r,V,0,0},     /* prod.w.t */
+  {90,23,r,V,0,0},     /* prod.l.t */
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+  {0,0,0,0,0,0},
+};
+char *lop[] = {
+  "mov",       /* 0 */
+  "merg",      /* 1 */
+  "mask",      /* 2 */
+  "mul",       /* 3 */
+  "div",       /* 4 */
+  "and",       /* 5 */
+  "or",        /* 6 */
+  "xor",       /* 7 */
+  "shf",       /* 8 */
+  "add",       /* 9 */
+  "sub",       /* 10 */
+  "exit",      /* 11 */
+  "jmp",       /* 12 */
+  "jmpi",      /* 13 */
+  "jmpa",      /* 14 */
+  "jmps",      /* 15 */
+  "tac",       /* 16 */
+  "ldea",      /* 17 */
+  "ld",        /* 18 */
+  "tas",       /* 19 */
+  "pshea",     /* 20 */
+  "st",        /* 21 */
+  "call",      /* 22 */
+  "calls",     /* 23 */
+  "callq",     /* 24 */
+  "pfork",     /* 25 */
+  "ste",       /* 26 */
+  "incr",      /* 27 */
+  "cvtw",      /* 28 */
+  "cvtb",      /* 29 */
+  "cvth",      /* 30 */
+  "cvts",      /* 31 */
+  "cvtd",      /* 32 */
+  "cvtl",      /* 33 */
+  "ldpa",      /* 34 */
+  "plc",       /* 35 */
+  "tzc",       /* 36 */
+  "eq",        /* 37 */
+  "leu",       /* 38 */
+  "ltu",       /* 39 */
+  "le",        /* 40 */
+  "lt",        /* 41 */
+  "not",       /* 42 */
+  "neg",       /* 43 */
+  "lop",       /* 44 */
+  "cprs",      /* 45 */
+  "nop",       /* 46 */
+  "br",        /* 47 */
+  "bri",       /* 48 */
+  "bra",       /* 49 */
+  "brs",       /* 50 */
+  "ldvi",      /* 51 */
+  "stvi",      /* 52 */
+  "ldsdr",     /* 53 */
+  "ldkdr",     /* 54 */
+  "ln",        /* 55 */
+  "patu",      /* 56 */
+  "pate",      /* 57 */
+  "pich",      /* 58 */
+  "plch",      /* 59 */
+  "idle",      /* 60 */
+  "rtnq",      /* 61 */
+  "cfork",     /* 62 */
+  "rtn",       /* 63 */
+  "wfork",     /* 64 */
+  "join",      /* 65 */
+  "rtnc",      /* 66 */
+  "exp",       /* 67 */
+  "sin",       /* 68 */
+  "cos",       /* 69 */
+  "psh",       /* 70 */
+  "pop",       /* 71 */
+  "eni",       /* 72 */
+  "dsi",       /* 73 */
+  "bkpt",      /* 74 */
+  "msync",     /* 75 */
+  "mski",      /* 76 */
+  "xmti",      /* 77 */
+  "tstvv",     /* 78 */
+  "diag",      /* 79 */
+  "pbkpt",     /* 80 */
+  "sqrt",      /* 81 */
+  "casr",      /* 82 */
+  "atan",      /* 83 */
+  "sum",       /* 84 */
+  "all",       /* 85 */
+  "any",       /* 86 */
+  "parity",    /* 87 */
+  "max",       /* 88 */
+  "min",       /* 89 */
+  "prod",      /* 90 */
+  "halt",      /* 91 */
+  "sysc",      /* 92 */
+  "trap",      /* 93 */
+  "tst",       /* 94 */
+  "lck",       /* 95 */
+  "ulk",       /* 96 */
+  "spawn",     /* 97 */
+  "ldcmr",     /* 98 */
+  "stcmr",     /* 99 */
+  "popr",      /* 100 */
+  "pshr",      /* 101 */
+  "rcvr",      /* 102 */
+  "matm",      /* 103 */
+  "sndr",      /* 104 */
+  "putr",      /* 105 */
+  "getr",      /* 106 */
+  "matr",      /* 107 */
+  "mat",       /* 108 */
+  "get",       /* 109 */
+  "rcv",       /* 110 */
+  "inc",       /* 111 */
+  "put",       /* 112 */
+  "snd",       /* 113 */
+  "enal",      /* 114 */
+  "enag",      /* 115 */
+  "frint",     /* 116 */
+  "xpnd",      /* 117 */
+  "ctrsl",     /* 118 */
+  "ctrsg",     /* 119 */
+  "stop",      /* 120 */
+};
+char *rop[] = {
+  "",  /* 0 */
+  ".t",        /* 1 */
+  ".f",        /* 2 */
+  ".s",        /* 3 */
+  ".d",        /* 4 */
+  ".b",        /* 5 */
+  ".h",        /* 6 */
+  ".w",        /* 7 */
+  ".l",        /* 8 */
+  ".x",        /* 9 */
+  ".u",        /* 10 */
+  ".s.f",      /* 11 */
+  ".d.f",      /* 12 */
+  ".b.f",      /* 13 */
+  ".h.f",      /* 14 */
+  ".w.f",      /* 15 */
+  ".l.f",      /* 16 */
+  ".t.f",      /* 17 */
+  ".s.t",      /* 18 */
+  ".d.t",      /* 19 */
+  ".b.t",      /* 20 */
+  ".h.t",      /* 21 */
+  ".w.t",      /* 22 */
+  ".l.t",      /* 23 */
+  ".t.t",      /* 24 */
+};
diff --git a/gdb/convex-pinsn.c b/gdb/convex-pinsn.c
new file mode 100644 (file)
index 0000000..a283d29
--- /dev/null
@@ -0,0 +1,314 @@
+/* Print Convex instructions for GDB, the GNU debugger.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+
+/* reg (fmt_field, inst_field) --
+   the {first,second,third} operand of instruction as fmt_field = [ijk]
+   gets the value of the field from the [ijk] position of the instruction */
+
+#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
+
+/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
+
+#define lit(i) op[fmt->i]
+
+/* aj[j] -- name for A register j */
+
+#define aj ((char (*)[3])(op[A]))
+\f
+union inst {
+    struct {
+       unsigned   : 7;
+       unsigned i : 3;
+       unsigned j : 3;
+       unsigned k : 3;
+       unsigned   : 16;
+       unsigned   : 32;
+    } f0;
+    struct {
+       unsigned   : 8;
+       unsigned indir : 1;
+       unsigned len : 1;
+       unsigned j : 3;
+       unsigned k : 3;
+       unsigned   : 16;
+       unsigned   : 32;
+    } f1;
+    unsigned char byte[8];
+    unsigned short half[4];
+    char signed_byte[8];
+    short signed_half[4];
+};
+
+struct opform {
+    int mask;                  /* opcode mask */
+    int shift;                 /* opcode align */
+    struct formstr *formstr[3];        /* ST, E0, E1 */
+};
+
+struct formstr {
+    unsigned lop:8, rop:5;     /* opcode */
+    unsigned fmt:5;            /* inst format */
+    unsigned i:5, j:5, k:2;    /* operand formats */
+};
+
+#include "convex-opcode.h"
+
+unsigned char formdecode [] = {
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+    4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+struct opform opdecode[] = {
+    0x7e00, 9, format0, e0_format0, e1_format0,
+    0x3f00, 8, format1, e0_format1, e1_format1,
+    0x1fc0, 6, format2, e0_format2, e1_format2,
+    0x0fc0, 6, format3, e0_format3, e1_format3,
+    0x0700, 8, format4, e0_format4, e1_format4,
+    0x03c0, 6, format5, e0_format5, e1_format5,
+    0x01f8, 3, format6, e0_format6, e1_format6,
+    0x00f8, 3, format7, e0_format7, e1_format7,
+    0x0000, 0, formatx, formatx, formatx,
+    0x0f80, 7, formatx, formatx, formatx,
+    0x0f80, 7, formatx, formatx, formatx,
+};
+\f
+/* Print the instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  union inst inst;
+  struct formstr *fmt;
+  register int format, op1, pfx;
+  int l;
+
+  read_memory (memaddr, &inst, sizeof inst);
+
+  /* Remove and note prefix, if present */
+    
+  pfx = inst.half[0];
+  if ((pfx & 0xfff0) == 0x7ef0)
+    {
+      pfx = ((pfx >> 3) & 1) + 1;
+      *(long long *) &inst = *(long long *) &inst.half[1];
+    }
+  else pfx = 0;
+
+  /* Split opcode into format.op1 and look up in appropriate table */
+
+  format = formdecode[inst.byte[0]];
+  op1 = (inst.half[0] & opdecode[format].mask) >> opdecode[format].shift;
+  if (format == 9)
+    {
+      if (pfx)
+       fmt = formatx;
+      else if (inst.f1.j == 0)
+       fmt = &format1a[op1];
+      else if (inst.f1.j == 1)
+       fmt = &format1b[op1];
+      else
+       fmt = formatx;
+    }
+  else
+    fmt = &opdecode[format].formstr[pfx][op1];
+
+  /* Print it */
+
+  if (fmt->fmt == xxx)
+    {
+      /* noninstruction */
+      fprintf (stream, "0x%04x", pfx ? pfx : inst.half[0]);
+      return 2;
+    }
+
+  if (pfx)
+    pfx = 2;
+
+  fprintf (stream, "%s%s%s", lop[fmt->lop], rop[fmt->rop],
+          &"        "[strlen(lop[fmt->lop]) + strlen(rop[fmt->rop])]);
+
+  switch (fmt->fmt)
+    {
+    case rrr:                  /* three register */
+      fprintf (stream, "%s,%s,%s", reg(i,i), reg(j,j), reg(k,k));
+      return pfx + 2;
+
+    case rr:                   /* two register */
+      fprintf (stream, "%s,%s", reg(i,j), reg(j,k));
+      return pfx + 2;
+
+    case rxr:                  /* two register, reversed i and j fields */
+      fprintf (stream, "%s,%s", reg(i,k), reg(j,j));
+      return pfx + 2;
+
+    case r:                    /* one register */
+      fprintf (stream, "%s", reg(i,k));
+      return pfx + 2;
+
+    case nops:                 /* no operands */
+      return pfx + 2;
+
+    case nr:                   /* short immediate, one register */
+      fprintf (stream, "#%d,%s", inst.f0.j, reg(i,k));
+      return pfx + 2;
+
+    case pcrel:                        /* pc relative */
+      print_address (memaddr + 2 * inst.signed_byte[1], stream);
+      return pfx + 2;
+
+    case lr:                   /* literal, one register */
+      fprintf (stream, "%s,%s", lit(i), reg(j,k));
+      return pfx + 2;
+
+    case rxl:                  /* one register, literal */
+      fprintf (stream, "%s,%s", reg(i,k), lit(j));
+      return pfx + 2;
+
+    case rlr:                  /* register, literal, register */
+      fprintf (stream, "%s,%s,%s", reg(i,j), lit(j), reg(k,k));
+      return pfx + 2;
+
+    case rrl:                  /* register, register, literal */
+      fprintf (stream, "%s,%s,%s", reg(i,j), reg(j,k), lit(k));
+      return pfx + 2;
+
+    case iml:                  /* immediate, literal */
+      if (inst.f1.len)
+       {
+         fprintf (stream, "#%#x,%s",
+                  (inst.signed_half[1] << 16) + inst.half[2], lit(i));
+         return pfx + 6;
+       }
+      else
+       {
+         fprintf (stream, "#%d,%s", inst.signed_half[1], lit(i));
+         return pfx + 4;
+       }
+
+    case imr:                  /* immediate, register */
+      if (inst.f1.len)
+       {
+         fprintf (stream, "#%#x,%s",
+                  (inst.signed_half[1] << 16) + inst.half[2], reg(i,k));
+         return pfx + 6;
+       }
+      else
+       {
+         fprintf (stream, "#%d,%s", inst.signed_half[1], reg(i,k));
+         return pfx + 4;
+       }
+
+    case a1r:                  /* memory, register */
+      l = print_effa (inst, stream);
+      fprintf (stream, ",%s", reg(i,k));
+      return pfx + l;
+
+    case a1l:                  /* memory, literal  */
+      l = print_effa (inst, stream);
+      fprintf (stream, ",%s", lit(i));
+      return pfx + l;
+
+    case a2r:                  /* register, memory */
+      fprintf (stream, "%s,", reg(i,k));
+      return pfx + print_effa (inst, stream);
+
+    case a2l:                  /* literal, memory */
+      fprintf (stream, "%s,", lit(i));
+      return pfx + print_effa (inst, stream);
+
+    case a3:                   /* memory */
+      return pfx + print_effa (inst, stream);
+
+    case a4:                   /* system call */
+      l = 29; goto a4a5;
+    case a5:                   /* trap */
+      l = 27;
+    a4a5:
+      if (inst.f1.len)
+       {
+         unsigned int m = (inst.signed_half[1] << 16) + inst.half[2];
+         fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
+         return pfx + 6;
+       }
+      else
+       {
+         unsigned int m = inst.signed_half[1];
+         fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
+         return pfx + 4;
+       }
+    }
+}
+
+
+/* print effective address @nnn(aj), return instruction length */
+
+int print_effa (inst, stream)
+     union inst inst;
+     FILE *stream;
+{
+  int n, l;
+
+  if (inst.f1.len)
+    {
+      n = (inst.signed_half[1] << 16) + inst.half[2];
+      l = 6;
+    }
+  else
+    {
+      n = inst.signed_half[1];
+      l = 4;
+    }
+       
+  if (inst.f1.indir)
+    printf ("@");
+
+  if (!inst.f1.j)
+    {
+      print_address (n, stream);
+      return l;
+    }
+
+  fprintf (stream, (n & 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",
+          n, aj[inst.f1.j]);
+
+  return l;
+}
diff --git a/gdb/convex-tdep.c b/gdb/convex-tdep.c
new file mode 100644 (file)
index 0000000..c206e1e
--- /dev/null
@@ -0,0 +1,934 @@
+/* Convex stuff for GDB.
+   Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "command.h"
+#include "symtab.h"
+#include "value.h"
+#include "frame.h"
+#include "inferior.h"
+#include "wait.h"
+
+#include <signal.h>
+#include <fcntl.h>
+
+#include "gdbcore.h"
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <sys/pcntl.h>
+#include <sys/thread.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "gdbcmd.h"
+
+exec_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  int n;
+  struct stat st_exec;
+
+  /* Eliminate all traces of old exec file.
+     Mark text segment as empty.  */
+
+  if (execfile)
+    free (execfile);
+  execfile = 0;
+  data_start = 0;
+  data_end = 0;
+  text_start = 0;
+  text_end = 0;
+  exec_data_start = 0;
+  exec_data_end = 0;
+  if (execchan >= 0)
+    close (execchan);
+  execchan = -1;
+
+  n_exec = 0;
+
+  /* Now open and digest the file the user requested, if any.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+                       &execfile);
+      if (execchan < 0)
+       perror_with_name (filename);
+
+      if (myread (execchan, &filehdr, sizeof filehdr) < 0)
+       perror_with_name (filename);
+
+      if (! IS_SOFF_MAGIC (filehdr.h_magic))
+       error ("%s: not an executable file.", filename);
+
+      if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)
+       perror_with_name (filename);
+
+      /* Read through the section headers.
+        For text, data, etc, record an entry in the exec file map.
+        Record text_start and text_end.  */
+
+      lseek (execchan, (long) filehdr.h_scnptr, 0);
+
+      for (n = 0; n < filehdr.h_nscns; n++)
+       {
+         if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)
+           perror_with_name (filename);
+
+         if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
+             && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
+           {
+             exec_map[n_exec].mem_addr = scnhdr.s_vaddr;
+             exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
+             exec_map[n_exec].file_addr = scnhdr.s_scnptr;
+             exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;
+             n_exec++;
+
+             if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)
+               {
+                 text_start = scnhdr.s_vaddr;
+                 text_end =  scnhdr.s_vaddr + scnhdr.s_size;
+               }
+           }
+       }
+
+      fstat (execchan, &st_exec);
+      exec_mtime = st_exec.st_mtime;
+      
+      validate_files ();
+    }
+  else if (from_tty)
+    printf_filtered ("No exec file now.\n");
+
+  /* Tell display code (if any) about the changed file name.  */
+  if (exec_file_display_hook)
+    (*exec_file_display_hook) (filename);
+}
+
+/* Read data from SOFF exec or core file.
+   Return 0 on success, EIO if address out of bounds. */
+
+int
+xfer_core_file (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  register int n;
+  register int val;
+  int xferchan;
+  char **xferfile;
+  int fileptr;
+  int returnval = 0;
+
+  while (len > 0)
+    {
+      xferfile = 0;
+      xferchan = 0;
+
+      /* Determine which file the next bunch of addresses reside in,
+        and where in the file.  Set the file's read/write pointer
+        to point at the proper place for the desired address
+        and set xferfile and xferchan for the correct file.
+        If desired address is nonexistent, leave them zero.
+        i is set to the number of bytes that can be handled
+        along with the next address.  */
+
+      i = len;
+
+      for (n = 0; n < n_core; n++)
+       {
+         if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end
+             && (core_map[n].thread == -1
+                 || core_map[n].thread == inferior_thread))
+           {
+             i = min (len, core_map[n].mem_end - memaddr);
+             fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;
+             if (core_map[n].file_addr)
+               {
+                 xferfile = &corefile;
+                 xferchan = corechan;
+               }
+             break;
+           }
+         else if (core_map[n].mem_addr >= memaddr
+                  && core_map[n].mem_addr < memaddr + i)
+           i = core_map[n].mem_addr - memaddr;
+        }
+
+      if (!xferfile) 
+       for (n = 0; n < n_exec; n++)
+         {
+           if (memaddr >= exec_map[n].mem_addr
+               && memaddr < exec_map[n].mem_end)
+             {
+               i = min (len, exec_map[n].mem_end - memaddr);
+               fileptr = exec_map[n].file_addr + memaddr
+                 - exec_map[n].mem_addr;
+               if (exec_map[n].file_addr)
+                 {
+                   xferfile = &execfile;
+                   xferchan = execchan;
+                 }
+               break;
+             }
+           else if (exec_map[n].mem_addr >= memaddr
+                    && exec_map[n].mem_addr < memaddr + i)
+             i = exec_map[n].mem_addr - memaddr;
+         }
+
+      /* Now we know which file to use.
+        Set up its pointer and transfer the data.  */
+      if (xferfile)
+       {
+         if (*xferfile == 0)
+           if (xferfile == &execfile)
+             error ("No program file to examine.");
+           else
+             error ("No core dump file or running program to examine.");
+         val = lseek (xferchan, fileptr, 0);
+         if (val < 0)
+           perror_with_name (*xferfile);
+         val = myread (xferchan, myaddr, i);
+         if (val < 0)
+           perror_with_name (*xferfile);
+       }
+      /* If this address is for nonexistent memory,
+        read zeros if reading, or do nothing if writing.  */
+      else
+       {
+         bzero (myaddr, i);
+         returnval = EIO;
+       }
+
+      memaddr += i;
+      myaddr += i;
+      len -= i;
+    }
+  return returnval;
+}
+
+
+/* Here from info files command to print an address map.  */
+
+print_maps ()
+{
+  struct pmap ptrs[200];
+  int n;
+
+  /* ID strings for core and executable file sections */
+
+  static char *idstr[] =
+    {
+      "0", "text", "data", "tdata", "bss", "tbss", 
+      "common", "ttext", "ctx", "tctx", "10", "11", "12",
+    };
+
+  for (n = 0; n < n_core; n++)
+    {
+      core_map[n].which = 0;
+      ptrs[n] = core_map[n];
+    }
+  for (n = 0; n < n_exec; n++)
+    {
+      exec_map[n].which = 1;
+      ptrs[n_core+n] = exec_map[n];
+    }
+
+  qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);
+
+  for (n = 0; n < n_core + n_exec; n++)
+    {
+      struct pmap *p = &ptrs[n];
+      if (n > 0)
+       {
+         if (p->mem_addr < ptrs[n-1].mem_end)
+           p->mem_addr = ptrs[n-1].mem_end;
+         if (p->mem_addr >= p->mem_end)
+           continue;
+       }
+      printf_filtered ("%08x .. %08x  %-6s  %s\n",
+                      p->mem_addr, p->mem_end, idstr[p->type],
+                      p->which ? execfile : corefile);
+    }
+}
+
+/* Compare routine to put file sections in order.
+   Sort into increasing order on address, and put core file sections
+   before exec file sections if both files contain the same addresses.  */
+
+static ptr_cmp (a, b)
+     struct pmap *a, *b;
+{
+  if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;
+  return a->which - b->which;
+}
+\f
+/* Trapped internal variables are used to handle special registers.
+   A trapped i.v. calls a hook here every time it is dereferenced,
+   to provide a new value for the variable, and it calls a hook here
+   when a new value is assigned, to do something with the value.
+   
+   The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
+   The communication registers are $cN, $CN (N in 0..63).
+   They not handled as regular registers because it's expensive to
+   read them, and their size varies, and they have too many names.  */
+
+
+/* Return 1 if NAME is a trapped internal variable, else 0. */
+
+int
+is_trapped_internalvar (name)
+     char *name;
+{
+    if ((name[0] == 'c' || name[0] == 'C')
+       && name[1] >= '0' && name[1] <= '9'
+       && (name[2] == '\0'
+           || (name[2] >= '0' && name[2] <= '9'
+               && name[3] == '\0' && name[1] != '0'))
+       && atoi (&name[1]) < 64) return 1;
+
+  if ((name[0] == 'v' || name[0] == 'V')
+      && (((name[1] & -8) == '0' && name[2] == '\0')
+         || !strcmp (name, "vl")
+         || !strcmp (name, "vs") 
+         || !strcmp (name, "vm")))
+    return 1;
+  else return 0;
+}
+
+/* Return the value of trapped internal variable VAR */
+
+value
+value_of_trapped_internalvar (var)
+     struct internalvar *var;
+{
+  char *name = var->name;
+  value val;
+  struct type *type;
+  long len = *read_vector_register (VL_REGNUM);
+  if (len <= 0 || len > 128) len = 128;
+
+  if (!strcmp (name, "vl"))
+    {
+      val = value_from_long (builtin_type_int,
+                            (LONGEST) *read_vector_register_1 (VL_REGNUM));
+    }
+  else if (!strcmp (name, "vs"))
+    {
+      val = value_from_long (builtin_type_int,
+                            (LONGEST) *read_vector_register_1 (VS_REGNUM));
+    }
+  else if (!strcmp (name, "vm"))
+    {
+      long vm[4];
+      long i, *p;
+      bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);
+      type = vector_type (builtin_type_int, len);
+      val = allocate_value (type);
+      p = (long *) VALUE_CONTENTS (val);
+      for (i = 0; i < len; i++) 
+       *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
+    }
+  else if (name[0] == 'V')
+    {
+      type = vector_type (builtin_type_long_long, len);
+      val = allocate_value (type);
+      bcopy (read_vector_register_1 (name[1] - '0'),
+            VALUE_CONTENTS (val), TYPE_LENGTH (type));
+    }
+  else if (name[0] == 'v')
+    {
+      long *p1, *p2;
+      type = vector_type (builtin_type_long, len);
+      val = allocate_value (type);
+      p1 = read_vector_register_1 (name[1] - '0');
+      p2 = (long *) VALUE_CONTENTS (val);
+      while (--len >= 0) {p1++; *p2++ = *p1++;}
+    }
+
+  else if (name[0] == 'c')
+    val = value_from_long (builtin_type_int,
+                          read_comm_register (atoi (&name[1])));
+  else if (name[0] == 'C')
+    val = value_from_long (builtin_type_long_long,
+                          read_comm_register (atoi (&name[1])));
+
+  VALUE_LVAL (val) = lval_internalvar;
+  VALUE_INTERNALVAR (val) = var;
+  return val;
+}
+
+/* Construct the type for a vector register's value --
+   array[LENGTH] of ELEMENT_TYPE.  */
+
+static struct type *
+vector_type (element_type, length)
+     struct type *element_type;
+     long length;
+{
+  struct type *type = (struct type *) xmalloc (sizeof (struct type));
+  bzero (type, sizeof type);
+  TYPE_CODE (type) = TYPE_CODE_ARRAY;
+  TYPE_TARGET_TYPE (type) = element_type;
+  TYPE_LENGTH (type) = length * TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+  return type;
+}
+
+/* Handle a new value assigned to a trapped internal variable */
+
+void
+set_trapped_internalvar (var, val, bitpos, bitsize, offset)
+     struct internalvar *var;
+     value val;
+     int bitpos, bitsize, offset;
+{ 
+  char *name = var->name;
+  long long newval = value_as_long (val);
+
+  if (!strcmp (name, "vl")) 
+    write_vector_register (VL_REGNUM, 0, newval);
+  else if (!strcmp (name, "vs"))
+    write_vector_register (VS_REGNUM, 0, newval);
+  else if (name[0] == 'c' || name[0] == 'C')
+    write_comm_register (atoi (&name[1]), newval);
+  else if (!strcmp (name, "vm"))
+    error ("can't assign to $vm");
+  else
+    {
+      offset /= bitsize / 8;
+      write_vector_register (name[1] - '0', offset, newval);
+    }
+}
+
+/* Print an integer value when no format was specified.  gdb normally
+   prints these values in decimal, but the the leading 0x80000000 of
+   pointers produces intolerable 10-digit negative numbers.
+   If it looks like an address, print it in hex instead.  */
+
+decout (stream, type, val)
+     FILE *stream;
+     struct type *type;
+     LONGEST val;
+{
+  long lv = val;
+
+  switch (output_radix)
+    {
+    case 0:
+      if ((lv == val || (unsigned) lv == val)
+         && ((lv & 0xf0000000) == 0x80000000
+             || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
+       {
+         fprintf_filtered (stream, "%#x", lv);
+         return;
+       }
+
+    case 10:
+      fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
+      return;
+
+    case 8:
+      if (TYPE_LENGTH (type) <= sizeof lv)
+       fprintf_filtered (stream, "%#o", lv);
+      else
+       fprintf_filtered (stream, "%#llo", val);
+      return;
+
+    case 16:
+      if (TYPE_LENGTH (type) <= sizeof lv)
+       fprintf_filtered (stream, "%#x", lv);
+      else
+       fprintf_filtered (stream, "%#llx", val);
+      return;
+    }
+}
+
+/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
+   This command is mostly obsolete now that the print command allows
+   formats to apply to aggregates, but is still handy occasionally.  */
+
+static void
+set_base_command (arg)
+    char *arg;
+{
+  int new_radix;
+
+  if (!arg)
+    output_radix = 0;
+  else
+    {
+      new_radix = atoi (arg);
+      if (new_radix != 10 && new_radix != 16 && new_radix != 8) 
+       error ("base must be 8, 10 or 16, or null");
+      else output_radix = new_radix;
+    }
+}
+
+/* Turn pipelining on or off in the inferior. */
+
+static void
+set_pipelining_command (arg)
+    char *arg;
+{
+  if (!arg)
+    {
+      sequential = !sequential;
+      printf_filtered ("%s\n", sequential ? "off" : "on");
+    }
+  else if (!strcmp (arg, "on"))
+    sequential = 0;
+  else if (!strcmp (arg, "off"))
+    sequential = 1;
+  else error ("valid args are `on', to allow instructions to overlap, or\n\
+`off', to prevent it and thereby pinpoint exceptions.");
+}
+
+/* Enable, disable, or force parallel execution in the inferior.  */
+
+static void
+set_parallel_command (arg)
+     char *arg;
+{
+  struct rlimit rl;
+  int prevparallel = parallel;
+
+  if (!strncmp (arg, "fixed", strlen (arg)))
+    parallel = 2;  
+  else if (!strcmp (arg, "on"))
+    parallel = 1;
+  else if (!strcmp (arg, "off"))
+    parallel = 0;
+  else error ("valid args are `on', to allow multiple threads, or\n\
+`fixed', to force multiple threads, or\n\
+`off', to run with one thread only.");
+
+  if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
+    printf_filtered ("will take effect at next run.\n");
+
+  getrlimit (RLIMIT_CONCUR, &rl);
+  rl.rlim_cur = parallel ? rl.rlim_max : 1;
+  setrlimit (RLIMIT_CONCUR, &rl);
+
+  if (inferior_pid)
+    set_fixed_scheduling (inferior_pid, parallel == 2);
+}
+
+/* Add a new name for an existing command.  */
+
+static void 
+alias_command (arg)
+    char *arg;
+{
+    static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
+    char *newname = arg;
+    struct cmd_list_element *new, *old;
+
+    if (!arg)
+      error_no_arg ("newname oldname");
+       
+    new = lookup_cmd (&arg, cmdlist, "", -1);
+    if (new && !strncmp (newname, new->name, strlen (new->name)))
+      {
+       newname = new->name;
+       if (!(*arg == '-' 
+             || (*arg >= 'a' && *arg <= 'z')
+             || (*arg >= 'A' && *arg <= 'Z')
+             || (*arg >= '0' && *arg <= '9')))
+         error (aliaserr);
+      }
+    else
+      {
+       arg = newname;
+       while (*arg == '-' 
+              || (*arg >= 'a' && *arg <= 'z')
+              || (*arg >= 'A' && *arg <= 'Z')
+              || (*arg >= '0' && *arg <= '9'))
+         arg++;
+       if (*arg != ' ' && *arg != '\t')
+         error (aliaserr);
+       *arg = '\0';
+       arg++;
+      }
+
+    old = lookup_cmd (&arg, cmdlist, "", 0);
+
+    if (*arg != '\0')
+      error (aliaserr);
+
+    if (new && !strncmp (newname, new->name, strlen (new->name)))
+      {
+       char *tem;
+       if (new->class == (int) class_user || new->class == (int) class_alias)
+         tem = "Redefine command \"%s\"? ";
+       else
+         tem = "Really redefine built-in command \"%s\"? ";
+       if (!query (tem, new->name))
+         error ("Command \"%s\" not redefined.", new->name);
+      }
+
+    add_com (newname, class_alias, old->function, old->doc);
+}
+
+
+
+/* Print the current thread number, and any threads with signals in the
+   queue.  */
+
+thread_info ()
+{
+  struct threadpid *p;
+
+  if (have_inferior_p ())
+    {
+      ps.pi_buffer = (char *) &comm_registers;
+      ps.pi_nbytes = sizeof comm_registers;
+      ps.pi_offset = 0;
+      ps.pi_thread = inferior_thread;
+      ioctl (inferior_fd, PIXRDCREGS, &ps);
+    }
+
+  printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
+                  inferior_thread, stop_signal, stop_sigcode,
+                  subsig_name (stop_signal, stop_sigcode));
+  
+  for (p = signal_stack; p->pid; p--)
+    printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
+                    p->thread, p->signo, p->subsig,
+                    subsig_name (p->signo, p->subsig));
+               
+  if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
+    printf_filtered ("New thread start pc %#x\n",
+                    (long) (comm_registers.crreg.pcpsw >> 32));
+}
+
+/* Return string describing a signal.subcode number */
+
+static char *
+subsig_name (signo, subcode)
+     int signo, subcode;
+{
+  static char *subsig4[] = {
+    "error exit", "privileged instruction", "unknown",
+    "unknown", "undefined opcode",
+    0};
+  static char *subsig5[] = {0,
+    "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
+    "join trap", "idle trap", "last thread", "wfork trap",
+    "process breakpoint", "trap instruction",
+    0};
+  static char *subsig8[] = {0,
+    "int overflow", "int divide check", "float overflow",
+    "float divide check", "float underflow", "reserved operand",
+    "sqrt error", "exp error", "ln error", "sin error", "cos error",
+    0};
+  static char *subsig10[] = {0,
+    "invalid inward ring address", "invalid outward ring call",
+    "invalid inward ring return", "invalid syscall gate",
+    "invalid rtn frame length", "invalid comm reg address",
+    "invalid trap gate",
+    0};
+  static char *subsig11[] = {0,
+    "read access denied", "write access denied", "execute access denied",
+    "segment descriptor fault", "page table fault", "data reference fault",
+    "i/o access denied", "levt pte invalid",
+    0};
+
+  static char **subsig_list[] = 
+    {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
+
+  int i;
+  char *p = signo < NSIG ? sys_siglist[signo] : "unknown";
+
+  if (signo >= (sizeof subsig_list / sizeof *subsig_list)
+      || !subsig_list[signo])
+    return p;
+  for (i = 1; subsig_list[signo][i]; i++)
+    if (i == subcode)
+      return subsig_list[signo][subcode];
+  return p;
+}
+
+
+/* Print a compact display of thread status, essentially x/i $pc
+   for all active threads.  */
+
+static void
+threadstat ()
+{
+  int t;
+
+  for (t = 0; t < n_threads; t++)
+    if (thread_state[t] == PI_TALIVE)
+      {
+       printf_filtered ("%d%c %08x%c %d.%d ", t,
+                        (t == inferior_thread ? '*' : ' '), thread_pc[t],
+                        (thread_is_in_kernel[t] ? '#' : ' '),
+                        thread_signal[t], thread_sigcode[t]);
+       print_insn (thread_pc[t], stdout);
+       printf_filtered ("\n");
+      }
+}
+
+/* Change the current thread to ARG.  */
+
+set_thread_command (arg)
+     char *arg;
+{
+    int thread;
+
+    if (!arg)
+      {
+       threadstat ();
+       return;
+      }
+
+    thread = parse_and_eval_address (arg);
+
+    if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
+      error ("no such thread.");
+
+    select_thread (thread);
+
+    stop_pc = read_pc ();
+    flush_cached_frames ();
+    set_current_frame (create_new_frame (read_register (FP_REGNUM),
+                                        read_pc ()));
+    select_frame (get_current_frame (), 0);
+    print_sel_frame (1);
+}
+
+/* Here on CONT command; gdb's dispatch address is changed to come here.
+   Set global variable ALL_CONTINUE to tell resume() that it should
+   start up all threads, and that a thread switch will not blow gdb's
+   mind.  */
+
+static void
+convex_cont_command (proc_count_exp, from_tty)
+     char *proc_count_exp;
+     int from_tty;
+{
+  all_continue = 1;
+  cont_command (proc_count_exp, from_tty);
+}
+
+/* Here on 1CONT command.  Resume only the current thread.  */
+
+one_cont_command (proc_count_exp, from_tty)
+     char *proc_count_exp;
+     int from_tty;
+{
+  cont_command (proc_count_exp, from_tty);
+}
+
+/* Print the contents and lock bits of all communication registers,
+   or just register ARG if ARG is a communication register,
+   or the 3-word resource structure in memory at address ARG.  */
+
+comm_registers_info (arg)
+    char *arg;
+{
+  int i, regnum;
+
+  if (arg)
+    {
+      if (sscanf (arg, "0x%x", &regnum) == 1
+         || sscanf (arg, "%d", &regnum) == 1)
+       {
+         if (regnum > 0)
+           regnum &= ~0x8000;
+       }
+      else if (sscanf (arg, "$c%d", &regnum) == 1)
+       ;
+      else if (sscanf (arg, "$C%d", &regnum) == 1)
+       ;
+      else
+       regnum = parse_and_eval_address (arg);
+
+      if (regnum >= 64)
+       error ("%s: invalid register name.", arg);
+
+      /* if we got a (user) address, examine the resource struct there */
+
+      if (regnum < 0)
+       {
+         static int buf[3];
+         read_memory (regnum, buf, sizeof buf);
+         printf_filtered ("%08x  %08x%08x%s\n", regnum, buf[1], buf[2],
+                          buf[0] & 0xff ? " locked" : "");
+         return;
+       }
+    }
+
+  ps.pi_buffer = (char *) &comm_registers;
+  ps.pi_nbytes = sizeof comm_registers;
+  ps.pi_offset = 0;
+  ps.pi_thread = inferior_thread;
+  ioctl (inferior_fd, PIXRDCREGS, &ps);
+
+  for (i = 0; i < 64; i++)
+    if (!arg || i == regnum)
+      printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
+                      comm_registers.crreg.r4[i],
+                      (iscrlbit (comm_registers.crctl.lbits.cc, i)
+                       ? " locked" : ""));
+}
+
+/* Print the psw */
+
+static void 
+psw_info (arg)
+    char *arg;
+{
+  struct pswbit
+    {
+      int bit;
+      int pos;
+      char *text;
+    };
+
+  static struct pswbit pswbit[] =
+    {
+      { 0x80000000, -1, "A carry" }, 
+      { 0x40000000, -1, "A integer overflow" }, 
+      { 0x20000000, -1, "A zero divide" }, 
+      { 0x10000000, -1, "Integer overflow enable" }, 
+      { 0x08000000, -1, "Trace" }, 
+      { 0x06000000, 25, "Frame length" }, 
+      { 0x01000000, -1, "Sequential" }, 
+      { 0x00800000, -1, "S carry" }, 
+      { 0x00400000, -1, "S integer overflow" }, 
+      { 0x00200000, -1, "S zero divide" }, 
+      { 0x00100000, -1, "Zero divide enable" }, 
+      { 0x00080000, -1, "Floating underflow" }, 
+      { 0x00040000, -1, "Floating overflow" }, 
+      { 0x00020000, -1, "Floating reserved operand" }, 
+      { 0x00010000, -1, "Floating zero divide" }, 
+      { 0x00008000, -1, "Floating error enable" }, 
+      { 0x00004000, -1, "Floating underflow enable" }, 
+      { 0x00002000, -1, "IEEE" }, 
+      { 0x00001000, -1, "Sequential stores" }, 
+      { 0x00000800, -1, "Intrinsic error" }, 
+      { 0x00000400, -1, "Intrinsic error enable" }, 
+      { 0x00000200, -1, "Trace thread creates" }, 
+      { 0x00000100, -1, "Thread init trap" }, 
+      { 0x000000e0,  5, "Reserved" },
+      { 0x0000001f,  0, "Intrinsic error code" },
+      {0, 0, 0},
+    };
+
+  long psw;
+  struct pswbit *p;
+
+  if (arg)
+    psw = parse_and_eval_address (arg);
+  else
+    psw = read_register (PS_REGNUM);
+
+  for (p = pswbit; p->bit; p++)
+    {
+      if (p->pos < 0)
+       printf_filtered ("%08x  %s  %s\n", p->bit,
+                        (psw & p->bit) ? "yes" : "no ", p->text);
+      else
+       printf_filtered ("%08x %3d   %s\n", p->bit,
+                        (psw & p->bit) >> p->pos, p->text);
+    }
+}
+\f
+_initialize_convex_dep ()
+{
+  add_com ("alias", class_support, alias_command,
+          "Add a new name for an existing command.");
+
+  add_cmd ("base", class_vars, set_base_command,
+          "Change the integer output radix to 8, 10 or 16\n\
+or use just `set base' with no args to return to the ad-hoc default,\n\
+which is 16 for integers that look like addresses, 10 otherwise.",
+          &setlist);
+
+  add_cmd ("pipeline", class_run, set_pipelining_command,
+          "Enable or disable overlapped execution of instructions.\n\
+With `set pipe off', exceptions are reported with\n\
+$pc pointing at the instruction after the faulting one.\n\
+The default is `set pipe on', which runs faster.",
+          &setlist);
+
+  add_cmd ("parallel", class_run, set_parallel_command,
+          "Enable or disable multi-threaded execution of parallel code.\n\
+`set parallel off' means run the program on a single CPU.\n\
+`set parallel fixed' means run the program with all CPUs assigned to it.\n\
+`set parallel on' means run the program on any CPUs that are available.",
+          &setlist);
+
+  add_com ("1cont", class_run, one_cont_command,
+          "Continue the program, activating only the current thread.\n\
+Args are the same as the `cont' command.");
+
+  add_com ("thread", class_run, set_thread_command,
+          "Change the current thread, the one under scrutiny and control.\n\
+With no arg, show the active threads, the current one marked with *.");
+
+  add_info ("threads", thread_info,
+           "List status of active threads.");
+
+  add_info ("comm-registers", comm_registers_info,
+           "List communication registers and their contents.\n\
+A communication register name as argument means describe only that register.\n\
+An address as argument means describe the resource structure at that address.\n\
+`Locked' means that the register has been sent to but not yet received from.");
+
+  add_info ("psw", psw_info, 
+           "Display $ps, the processor status word, bit by bit.\n\
+An argument means display that value's interpretation as a psw.");
+
+  add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
+32-bit registers  $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
+64-bit registers  $S0-7 $V0-7 $C0-63\n\
+\n\
+info threads       display info on stopped threads waiting to signal\n\
+thread             display list of active threads\n\
+thread N           select thread N (its registers, stack, memory, etc.)\n\
+step, next, etc     step selected thread only\n\
+1cont              continue selected thread only\n\
+cont               continue all threads\n\
+info comm-registers display contents of comm register(s) or a resource struct\n\
+info psw           display processor status word $ps\n\
+set base N         change integer radix used by `print' without a format\n\
+set pipeline off    exceptions are precise, $pc points after the faulting insn\n\
+set pipeline on     normal mode, $pc is somewhere ahead of faulting insn\n\
+set parallel off    program runs on a single CPU\n\
+set parallel fixed  all CPUs are assigned to the program\n\
+set parallel on     normal mode, parallel execution on random available CPUs\n\
+",
+          &cmdlist);
+
+}
diff --git a/gdb/convex-xdep.c b/gdb/convex-xdep.c
new file mode 100644 (file)
index 0000000..f9f44a0
--- /dev/null
@@ -0,0 +1,983 @@
+/* Convex stuff for GDB.
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "command.h"
+#include "symtab.h"
+#include "value.h"
+#include "frame.h"
+#include "inferior.h"
+#include "wait.h"
+
+#include <signal.h>
+#include <fcntl.h>
+#include "gdbcore.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <sys/pcntl.h>
+#include <sys/thread.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <convex/vmparam.h>
+#include <convex/filehdr.h>
+#include <convex/opthdr.h>
+#include <convex/scnhdr.h>
+#include <convex/core.h>
+
+/* Per-thread data, read from the inferior at each stop and written
+   back at each resume.  */
+
+/* Number of active threads.
+   Tables are valid for thread numbers less than this.  */
+
+static int n_threads;
+
+#define MAXTHREADS 8
+               
+/* Thread state.  The remaining data is valid only if this is PI_TALIVE.  */
+
+static int thread_state[MAXTHREADS];
+
+/* Stop pc, signal, signal subcode */
+
+static int thread_pc[MAXTHREADS];
+static int thread_signal[MAXTHREADS];
+static int thread_sigcode[MAXTHREADS]; 
+
+/* Thread registers.
+   If thread is selected, the regs are in registers[] instead.  */
+
+static char thread_regs[MAXTHREADS][REGISTER_BYTES];
+
+/* 1 if the top frame on the thread's stack was a context frame,
+   meaning that the kernel is up to something and we should not
+   touch the thread at all except to resume it.  */
+
+static char thread_is_in_kernel[MAXTHREADS];
+
+/* The currently selected thread's number.  */
+
+static int inferior_thread;
+
+/* Inferior process's file handle and a process control block
+   to feed args to ioctl with.  */
+
+static int inferior_fd;
+static struct pcntl ps;
+
+/* SOFF file headers for exec or core file.  */
+
+static FILEHDR filehdr;
+static OPTHDR opthdr;
+static SCNHDR scnhdr;
+
+/* Address maps constructed from section headers of exec and core files.
+   Defines process address -> file address translation.  */
+
+struct pmap 
+{
+    long mem_addr;             /* process start address */
+    long mem_end;              /* process end+1 address */
+    long file_addr;            /* file start address */
+    long thread;               /* -1 shared; 0,1,... thread-local */
+    long type;                 /* S_TEXT S_DATA S_BSS S_TBSS etc */
+    long which;                        /* used to sort map for info files */
+};
+
+static int n_exec, n_core;
+static struct pmap exec_map[100];
+static struct pmap core_map[100];
+
+/* Offsets in the core file of core_context and core_tcontext blocks.  */
+
+static int context_offset;
+static int tcontext_offset[MAXTHREADS];
+
+/* Core file control blocks.  */
+
+static struct core_context_v70 c;
+static struct core_tcontext_v70 tc;
+static struct user u;
+static thread_t th;
+static proc_t pr;
+
+/* The registers of the currently selected thread.  */
+
+extern char registers[REGISTER_BYTES];
+
+/* Vector and communication registers from core dump or from inferior.
+   These are read on demand, ie, not normally valid.  */
+
+static struct vecst vector_registers;
+static struct creg_ctx comm_registers;
+
+/* Flag, set on a vanilla CONT command and cleared when the inferior
+   is continued.  */
+
+static int all_continue;
+
+/* Flag, set when the inferior is continued by a vanilla CONT command,
+   cleared if it is continued for any other purpose.  */
+
+static int thread_switch_ok;
+
+/* Stack of signals recieved from threads but not yet delivered to gdb.  */
+
+struct threadpid 
+{
+    int pid;
+    int thread;
+    int signo;
+    int subsig;
+    int pc;
+};
+
+static struct threadpid signal_stack_bot[100];
+static struct threadpid *signal_stack = signal_stack_bot;
+
+/* How to detect empty stack -- bottom frame is all zero.  */
+
+#define signal_stack_is_empty() (signal_stack->pid == 0)
+
+/* Mode controlled by SET PIPE command, controls the psw SEQ bit
+   which forces each instruction to complete before the next one starts.  */
+
+static int sequential = 0;
+
+/* Mode controlled by the SET PARALLEL command.  Values are:
+   0  concurrency limit 1 thread, dynamic scheduling
+   1  no concurrency limit, dynamic scheduling
+   2  no concurrency limit, fixed scheduling  */
+
+static int parallel = 1;
+
+/* Mode controlled by SET BASE command, output radix for unformatted
+   integer typeout, as in argument lists, aggregates, and so on.
+   Zero means guess whether it's an address (hex) or not (decimal).  */
+
+static int output_radix = 0;
+
+/* Signal subcode at last thread stop.  */
+
+static int stop_sigcode;
+
+/* Hack, see wait() below.  */
+
+static int exec_trap_timer;
+
+#include "gdbcmd.h"
+
+/* Nonzero if we are debugging an attached outside process
+   rather than an inferior.  */
+
+extern int attach_flag;
+
+
+
+static struct type *vector_type ();
+static long *read_vector_register ();
+static long *read_vector_register_1 ();
+static void write_vector_register ();
+static REGISTER_TYPE read_comm_register ();
+static void write_comm_register ();
+static void convex_cont_command ();
+static void thread_continue ();
+static void select_thread ();
+static void scan_stack ();
+static void set_fixed_scheduling ();
+static char *subsig_name ();
+static void psw_info ();
+static sig_noop ();
+static ptr_cmp ();
+
+extern char *sys_siglist[];
+\f
+/* Execute ptrace.  Convex V7 replaced ptrace with pattach.
+   Allow ptrace (0) as a no-op.  */
+
+int
+call_ptrace (request, pid, procaddr, buf)
+     int request, pid, procaddr, buf;
+{
+  if (request == 0)
+    return;
+  error ("no ptrace");
+}
+
+/* Replacement for system execle routine.
+   Convert it to an equivalent exect, which pattach insists on.  */
+
+execle (name, argv)
+     char *name, *argv;
+{
+  char ***envp = (char ***) &argv;
+  while (*envp++) ;
+
+  signal (SIGTRAP, sig_noop);
+  exect (name, &argv, *envp);
+}
+
+/* Stupid handler for stupid trace trap that otherwise causes
+   startup to stupidly hang.  */
+
+static sig_noop () 
+{}
+
+/* Read registers from inferior into registers[] array.
+   For convex, they are already there, read in when the inferior stops.  */
+
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+}
+
+/* Store our register values back into the inferior.
+   For Convex, do this only once, right before resuming inferior.  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+}
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+   to debugger memory starting at MYADDR. 
+   On failure (cannot read from inferior, usually because address is out
+   of bounds) returns the value of errno. */
+
+int
+read_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  errno = 0;
+  while (len > 0)
+    {
+      /* little-known undocumented max request size */
+      int i = (len < 12288) ? len : 12288;
+
+      lseek (inferior_fd, memaddr, 0);
+      read (inferior_fd, myaddr, i);
+
+      memaddr += i;
+      myaddr += i;
+      len -= i;
+    }
+  if (errno) 
+    bzero (myaddr, len);
+  return errno;
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+   to inferior's memory at MEMADDR.
+   Returns errno on failure (cannot write the inferior) */
+
+int
+write_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  errno = 0;
+  lseek (inferior_fd, memaddr, 0);
+  write (inferior_fd, myaddr, len);
+  return errno;
+}
+
+/* Here from create_inferior when the inferior process has been created
+   and started up.  We must do a pattach to grab it for debugging.
+
+   Also, intercept the CONT command by altering its dispatch address.  */
+
+create_inferior_hook (pid)
+    int pid;
+{
+  static char cont[] = "cont";
+  static char cont1[] = "c";
+  char *linep = cont;
+  char *linep1 = cont1;
+  char **line = &linep;
+  char **line1 = &linep1;
+  struct cmd_list_element *c;
+
+  c = lookup_cmd (line, cmdlist, "", 0);
+  c->function = convex_cont_command;
+  c = lookup_cmd (line1, cmdlist, "", 0);
+  c->function = convex_cont_command;
+
+  inferior_fd = pattach (pid, O_EXCL);
+  if (inferior_fd < 0)
+    perror_with_name ("pattach");
+  inferior_thread = 0;
+  set_fixed_scheduling (pid, parallel == 2);
+}
+
+/* Attach process PID for debugging.  */
+
+attach (pid)
+    int pid;
+{
+  int fd = pattach (pid, O_EXCL);
+  if (fd < 0)
+    perror_with_name ("pattach");
+  attach_flag = 1;
+  /* wait for strange kernel reverberations to go away */
+  sleep (1);
+
+  setpgrp (pid, pid);
+
+  inferior_fd = fd;
+  inferior_thread = 0;
+  return pid;
+}
+
+/* Stop debugging the process whose number is PID
+   and continue it with signal number SIGNAL.
+   SIGNAL = 0 means just continue it.  */
+
+void
+detach (signal)
+     int signal;
+{
+  signal_stack = signal_stack_bot;
+  thread_continue (-1, 0, signal);
+  ioctl (inferior_fd, PIXDETACH, &ps);
+  close (inferior_fd);
+  inferior_fd = 0;
+  attach_flag = 0;
+}
+
+/* Kill off the inferior process.  */
+
+kill_inferior ()
+{
+  if (inferior_pid == 0)
+    return;
+  ioctl (inferior_fd, PIXTERMINATE, 0);
+  wait (0);
+  target_mourn_inferior ();
+}
+
+/* This is used when GDB is exiting.  It gives less chance of error.*/
+
+kill_inferior_fast ()
+{
+  if (inferior_pid == 0)
+    return;
+  ioctl (inferior_fd, PIXTERMINATE, 0);
+  wait (0);
+}
+
+/* Read vector register REG, and return a pointer to the value.  */
+
+static long *
+read_vector_register (reg)
+    int reg;
+{
+  if (have_inferior_p ())
+    {
+      errno = 0;
+      ps.pi_buffer = (char *) &vector_registers;
+      ps.pi_nbytes = sizeof vector_registers;
+      ps.pi_offset = 0;
+      ps.pi_thread = inferior_thread;
+      ioctl (inferior_fd, PIXRDVREGS, &ps);
+      if (errno)
+       bzero (&vector_registers, sizeof vector_registers);
+    }
+  else if (corechan >= 0)
+    {
+      lseek (corechan, tcontext_offset[inferior_thread], 0);
+      if (myread (corechan, &tc, sizeof tc) < 0)
+       perror_with_name (corefile);
+      lseek (corechan, tc.core_thread_p, 0);
+      if (myread (corechan, &th, sizeof th) < 0)
+       perror_with_name (corefile);
+      lseek (corechan, tc.core_vregs_p, 0);
+      if (myread (corechan, &vector_registers, 16*128) < 0)
+       perror_with_name (corefile);
+      vector_registers.vm[0] = th.t_vect_ctx.vc_vm[0];
+      vector_registers.vm[1] = th.t_vect_ctx.vc_vm[1];
+      vector_registers.vls = th.t_vect_ctx.vc_vls;
+    }
+
+  return read_vector_register_1 (reg);
+}
+
+/* Return a pointer to vector register REG, which must already have been
+   fetched from the inferior or core file.  */
+
+static long *
+read_vector_register_1 (reg) 
+    int reg;
+{
+  switch (reg)
+    {
+    case VM_REGNUM:
+      return (long *) vector_registers.vm;
+    case VS_REGNUM:
+      return (long *) &vector_registers.vls;
+    case VL_REGNUM:
+      return 1 + (long *) &vector_registers.vls;
+    default:
+      return (long *) &vector_registers.vr[reg];
+    }
+}
+
+/* Write vector register REG, element ELEMENT, new value VAL.
+   NB: must use read-modify-write on the entire vector state,
+   since pattach does not do offsetted writes correctly.  */
+
+static void
+write_vector_register (reg, element, val)
+    int reg, element;
+    REGISTER_TYPE val;
+{
+  if (have_inferior_p ())
+    {
+      errno = 0;
+      ps.pi_thread = inferior_thread;
+      ps.pi_offset = 0;
+      ps.pi_buffer = (char *) &vector_registers;
+      ps.pi_nbytes = sizeof vector_registers;
+
+      ioctl (inferior_fd, PIXRDVREGS, &ps);
+
+      switch (reg)
+       {
+       case VL_REGNUM:
+         vector_registers.vls =
+           (vector_registers.vls & 0xffffffff00000000LL)
+             + (unsigned long) val;
+         break;
+
+       case VS_REGNUM:
+         vector_registers.vls =
+           (val << 32) + (unsigned long) vector_registers.vls;
+         break;
+           
+       default:
+         vector_registers.vr[reg].el[element] = val;
+         break;
+       }
+
+      ioctl (inferior_fd, PIXWRVREGS, &ps);
+
+      if (errno)
+       perror_with_name ("writing vector register");
+    }
+}
+
+/* Return the contents of communication register NUM.  */ 
+
+static REGISTER_TYPE 
+read_comm_register (num)
+     int num;
+{
+  if (have_inferior_p ())
+    {
+      ps.pi_buffer = (char *) &comm_registers;
+      ps.pi_nbytes = sizeof comm_registers;
+      ps.pi_offset = 0;
+      ps.pi_thread = inferior_thread;
+      ioctl (inferior_fd, PIXRDCREGS, &ps);
+    }
+  return comm_registers.crreg.r4[num];
+}
+
+/* Store a new value VAL into communication register NUM.  
+   NB: Must use read-modify-write on the whole comm register set
+   since pattach does not do offsetted writes correctly.  */
+
+static void
+write_comm_register (num, val)
+     int num;
+     REGISTER_TYPE val;
+{
+  if (have_inferior_p ())
+    {
+      ps.pi_buffer = (char *) &comm_registers;
+      ps.pi_nbytes = sizeof comm_registers;
+      ps.pi_offset = 0;
+      ps.pi_thread = inferior_thread;
+      ioctl (inferior_fd, PIXRDCREGS, &ps);
+      comm_registers.crreg.r4[num] = val;
+      ioctl (inferior_fd, PIXWRCREGS, &ps);
+    }
+}
+
+/* Resume execution of the inferior process.
+   If STEP is nonzero, single-step it.
+   If SIGNAL is nonzero, give it that signal.  */
+
+void
+resume (step, signal)
+     int step;
+     int signal;
+{
+  errno = 0;
+  if (step || signal)
+    thread_continue (inferior_thread, step, signal);
+  else
+    thread_continue (-1, 0, 0);
+}
+
+/* Maybe resume some threads.
+   THREAD is which thread to resume, or -1 to resume them all.
+   STEP and SIGNAL are as in resume.
+
+   Global variable ALL_CONTINUE is set when we are here to do a
+   `cont' command; otherwise we may be doing `finish' or a call or
+   something else that will not tolerate an automatic thread switch.
+
+   If there are stopped threads waiting to deliver signals, and
+   ALL_CONTINUE, do not actually resume anything.  gdb will do a wait
+   and see one of the stopped threads in the queue.  */
+
+static void
+thread_continue (thread, step, signal)
+     int thread, step, signal;
+{
+  int n;
+
+  /* If we are to continue all threads, but not for the CONTINUE command,
+     pay no attention and continue only the selected thread.  */
+
+  if (thread < 0 && ! all_continue)
+    thread = inferior_thread;
+
+  /* If we are not stepping, we have now executed the continue part
+     of a CONTINUE command.  */
+
+  if (! step)
+    all_continue = 0;
+
+  /* Allow wait() to switch threads if this is an all-out continue.  */
+
+  thread_switch_ok = thread < 0;
+
+  /* If there are threads queued up, don't resume.  */
+
+  if (thread_switch_ok && ! signal_stack_is_empty ())
+    return;
+
+  /* OK, do it.  */
+
+  for (n = 0; n < n_threads; n++)
+    if (thread_state[n] == PI_TALIVE)
+      {
+       select_thread (n);
+
+       if ((thread < 0 || n == thread) && ! thread_is_in_kernel[n])
+         {
+           /* Blam the trace bits in the stack's saved psws to match 
+              the desired step mode.  This is required so that
+              single-stepping a return doesn't restore a psw with a
+              clear trace bit and fly away, and conversely,
+              proceeding through a return in a routine that was
+              stepped into doesn't cause a phantom break by restoring
+              a psw with the trace bit set. */
+           scan_stack (PSW_T_BIT, step);
+           scan_stack (PSW_S_BIT, sequential);
+         }
+
+       ps.pi_buffer = registers;
+       ps.pi_nbytes = REGISTER_BYTES;
+       ps.pi_offset = 0;
+       ps.pi_thread = n;
+       if (! thread_is_in_kernel[n])
+         if (ioctl (inferior_fd, PIXWRREGS, &ps))
+           perror_with_name ("PIXWRREGS");
+
+       if (thread < 0 || n == thread)
+         {
+           ps.pi_pc = 1;
+           ps.pi_signo = signal;
+           if (ioctl (inferior_fd, step ? PIXSTEP : PIXCONTINUE, &ps) < 0)
+             perror_with_name ("PIXCONTINUE");
+         }
+      }
+
+  if (ioctl (inferior_fd, PIXRUN, &ps) < 0)
+    perror_with_name ("PIXRUN");
+}
+
+/* Replacement for system wait routine.  
+
+   The system wait returns with one or more threads stopped by
+   signals.  Put stopped threads on a stack and return them one by
+   one, so that it appears that wait returns one thread at a time.
+
+   Global variable THREAD_SWITCH_OK is set when gdb can tolerate wait
+   returning a new thread.  If it is false, then only one thread is
+   running; we will do a real wait, the thread will do something, and
+   we will return that.  */
+
+pid_t
+wait (w)
+    union wait *w;
+{
+  int pid;
+
+  if (!w)
+    return wait3 (0, 0, 0);
+
+  /* Do a real wait if we were told to, or if there are no queued threads.  */
+
+  if (! thread_switch_ok || signal_stack_is_empty ())
+    {
+      int thread;
+
+      pid = wait3 (w, 0, 0);
+
+      if (!WIFSTOPPED (*w) || pid != inferior_pid)
+       return pid;
+
+      /* The inferior has done something and stopped.  Read in all the
+        threads' registers, and queue up any signals that happened.  */
+
+      if (ioctl (inferior_fd, PIXGETTHCOUNT, &ps) < 0)
+       perror_with_name ("PIXGETTHCOUNT");
+      
+      n_threads = ps.pi_othdcnt;
+      for (thread = 0; thread < n_threads; thread++)
+       {
+         ps.pi_thread = thread;
+         if (ioctl (inferior_fd, PIXGETSUBCODE, &ps) < 0)
+           perror_with_name ("PIXGETSUBCODE");
+         thread_state[thread] = ps.pi_otstate;
+
+         if (ps.pi_otstate == PI_TALIVE)
+           {
+             select_thread (thread);
+             ps.pi_buffer = registers;
+             ps.pi_nbytes = REGISTER_BYTES;
+             ps.pi_offset = 0;
+             ps.pi_thread = thread;
+             if (ioctl (inferior_fd, PIXRDREGS, &ps) < 0)
+               perror_with_name ("PIXRDREGS");
+
+             registers_fetched ();
+
+             thread_pc[thread] = read_pc ();
+             thread_signal[thread] = ps.pi_osigno;
+             thread_sigcode[thread] = ps.pi_osigcode;
+
+             /* If the thread's stack has a context frame
+                on top, something fucked is going on.  I do not
+                know what, but do I know this: the only thing you
+                can do with such a thread is continue it.  */
+
+             thread_is_in_kernel[thread] = 
+               ((read_register (PS_REGNUM) >> 25) & 3) == 0;
+
+             /* Signals push an extended frame and then fault
+                with a ridiculous pc.  Pop the frame.  */
+
+             if (thread_pc[thread] > STACK_END_ADDR)
+               {
+                 POP_FRAME;
+                 if (is_break_pc (thread_pc[thread]))
+                   thread_pc[thread] = read_pc () - 2;
+                 else
+                   thread_pc[thread] = read_pc ();
+                 write_register (PC_REGNUM, thread_pc[thread]);
+               }
+             
+             if (ps.pi_osigno || ps.pi_osigcode)
+               {
+                 signal_stack++;
+                 signal_stack->pid = pid;
+                 signal_stack->thread = thread;
+                 signal_stack->signo = thread_signal[thread];
+                 signal_stack->subsig = thread_sigcode[thread];
+                 signal_stack->pc = thread_pc[thread];
+               }
+
+             /* The following hackery is caused by a unix 7.1 feature:
+                the inferior's fixed scheduling mode is cleared when
+                it execs the shell (since the shell is not a parallel
+                program).  So, note the 5.4 trap we get when
+                the shell does its exec, then catch the 5.0 trap 
+                that occurs when the debuggee starts, and set fixed
+                scheduling mode properly.  */
+
+             if (ps.pi_osigno == 5 && ps.pi_osigcode == 4)
+               exec_trap_timer = 1;
+             else
+               exec_trap_timer--;
+             
+             if (ps.pi_osigno == 5 && exec_trap_timer == 0)
+               set_fixed_scheduling (pid, parallel == 2);
+           }
+       }
+
+      if (signal_stack_is_empty ())
+       error ("no active threads?!");
+    }
+
+  /* Select the thread that stopped, and return *w saying why.  */
+
+  select_thread (signal_stack->thread);
+
+  stop_signal = signal_stack->signo;
+  stop_sigcode = signal_stack->subsig;
+
+  WSETSTOP (*w, signal_stack->signo);
+  w->w_thread = signal_stack->thread;
+  return (signal_stack--)->pid;
+}
+
+/* Select thread THREAD -- its registers, stack, per-thread memory.
+   This is the only routine that may assign to inferior_thread
+   or thread_regs[].  */
+
+static void
+select_thread (thread)
+     int thread;
+{
+  if (thread == inferior_thread)
+    return;
+
+  bcopy (registers, thread_regs[inferior_thread], REGISTER_BYTES);
+  ps.pi_thread = inferior_thread = thread;
+  if (have_inferior_p ())
+    ioctl (inferior_fd, PISETRWTID, &ps);
+  bcopy (thread_regs[thread], registers, REGISTER_BYTES);
+}
+  
+/* Routine to set or clear a psw bit in the psw and also all psws
+   saved on the stack.  Quits when we get to a frame in which the
+   saved psw is correct. */
+
+static void
+scan_stack (bit, val)
+    long bit, val;
+{
+  long ps = read_register (PS_REGNUM);
+  long fp;
+  if (val ? !(ps & bit) : (ps & bit))
+    {    
+      ps ^= bit;
+      write_register (PS_REGNUM, ps);
+
+      fp = read_register (FP_REGNUM);
+      while (fp & 0x80000000)
+       {
+         ps = read_memory_integer (fp + 4, 4);
+         if (val ? (ps & bit) : !(ps & bit))
+           break;
+         ps ^= bit;
+         write_memory (fp + 4, &ps, 4);
+         fp = read_memory_integer (fp + 8, 4);
+       }
+    }
+}
+
+/* Set fixed scheduling (alliant mode) of process PID to ARG (0 or 1).  */
+
+static void
+set_fixed_scheduling (pid, arg)
+      int arg;
+{
+  struct pattributes pattr;
+  getpattr (pid, &pattr);
+  pattr.pattr_pfixed = arg;
+  setpattr (pid, &pattr);
+}
+\f
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int n;
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+  n_core = 0;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+
+      if (myread (corechan, &filehdr, sizeof filehdr) < 0)
+       perror_with_name (filename);
+
+      if (!IS_CORE_SOFF_MAGIC (filehdr.h_magic))
+       error ("%s: not a core file.\n", filename);
+
+      if (myread (corechan, &opthdr, filehdr.h_opthdr) < 0)
+       perror_with_name (filename);
+
+      /* Read through the section headers.
+        For text, data, etc, record an entry in the core file map.
+        For context and tcontext, record the file address of
+        the context blocks.  */
+
+      lseek (corechan, (long) filehdr.h_scnptr, 0);
+
+      n_threads = 0;
+      for (n = 0; n < filehdr.h_nscns; n++)
+       {
+         if (myread (corechan, &scnhdr, sizeof scnhdr) < 0)
+           perror_with_name (filename);
+         if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
+             && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
+           {
+             core_map[n_core].mem_addr = scnhdr.s_vaddr;
+             core_map[n_core].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
+             core_map[n_core].file_addr = scnhdr.s_scnptr;
+             core_map[n_core].type = scnhdr.s_flags & S_TYPMASK;
+             if (core_map[n_core].type != S_TBSS
+                 && core_map[n_core].type != S_TDATA
+                 && core_map[n_core].type != S_TTEXT)
+               core_map[n_core].thread = -1;
+             else if (n_core == 0
+                      || core_map[n_core-1].mem_addr != scnhdr.s_vaddr)
+               core_map[n_core].thread = 0;
+             else 
+               core_map[n_core].thread = core_map[n_core-1].thread + 1;
+             n_core++;
+           }
+         else if ((scnhdr.s_flags & S_TYPMASK) == S_CONTEXT)
+           context_offset = scnhdr.s_scnptr;
+         else if ((scnhdr.s_flags & S_TYPMASK) == S_TCONTEXT) 
+           tcontext_offset[n_threads++] = scnhdr.s_scnptr;
+       }
+
+      /* Read the context block, struct user, struct proc,
+        and the comm regs.  */
+
+      lseek (corechan, context_offset, 0);
+      if (myread (corechan, &c, sizeof c) < 0)
+       perror_with_name (filename);
+      lseek (corechan, c.core_user_p, 0);
+      if (myread (corechan, &u, sizeof u) < 0)
+       perror_with_name (filename);
+      lseek (corechan, c.core_proc_p, 0);
+      if (myread (corechan, &pr, sizeof pr) < 0)
+       perror_with_name (filename);
+      comm_registers = pr.p_creg;
+
+      /* Core file apparently is really there.  Make it really exist
+        for xfer_core_file so we can do read_memory on it. */
+
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       corefile = concat (current_directory, "/", filename);
+
+      printf_filtered ("Program %s ", u.u_comm);
+
+      /* Read the thread registers and fill in the thread_xxx[] data.  */
+
+      for (n = 0; n < n_threads; n++)
+       {
+         select_thread (n);
+
+         lseek (corechan, tcontext_offset[n], 0);
+         if (myread (corechan, &tc, sizeof tc) < 0)
+           perror_with_name (corefile);
+         lseek (corechan, tc.core_thread_p, 0);
+         if (myread (corechan, &th, sizeof th) < 0)
+           perror_with_name (corefile);
+
+         lseek (corechan, tc.core_syscall_context_p, 0);
+         if (myread (corechan, registers, REGISTER_BYTES) < 0)
+           perror_with_name (corefile);
+
+         thread_signal[n] = th.t_cursig;
+         thread_sigcode[n] = th.t_code;
+         thread_state[n] = th.t_state;
+         thread_pc[n] = read_pc ();
+
+         if (thread_pc[n] > STACK_END_ADDR)
+           {
+             POP_FRAME;
+             if (is_break_pc (thread_pc[n]))
+               thread_pc[n] = read_pc () - 2;
+             else
+               thread_pc[n] = read_pc ();
+             write_register (PC_REGNUM, thread_pc[n]);
+           }
+
+         printf_filtered ("thread %d received signal %d, %s\n",
+                          n, thread_signal[n],
+                          thread_signal[n] < NSIG
+                          ? sys_siglist[thread_signal[n]]
+                          : "(undocumented)");
+       }
+
+      /* Select an interesting thread -- also-rans died with SIGKILL,
+        so find one that didn't.  */
+
+      for (n = 0; n < n_threads; n++)
+       if (thread_signal[n] != 0 && thread_signal[n] != SIGKILL)
+         {
+           select_thread (n);
+           stop_signal = thread_signal[n];
+           stop_sigcode = thread_sigcode[n];
+           break;
+         }
+
+      core_aouthdr.a_magic = 0;
+
+      flush_cached_frames ();
+      set_current_frame (create_new_frame (read_register (FP_REGNUM),
+                                            read_pc ()));
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+
+      print_sel_frame (1);
+    }
+  else if (from_tty)
+    printf_filtered ("No core file now.\n");
+}
diff --git a/gdb/core.c b/gdb/core.c
new file mode 100644 (file)
index 0000000..2936e46
--- /dev/null
@@ -0,0 +1,447 @@
+/* Work with core dump and executable files, for GDB.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"  /* required by inferior.h */
+#include "inferior.h"
+#include "symtab.h"
+#include "command.h"
+#include "bfd.h"
+#include "target.h"
+#include "gdbcore.h"
+
+extern int xfer_memory ();
+extern void child_attach (), child_create_inferior ();
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+extern char *sys_siglist[];
+
+extern char registers[];
+
+/* Hook for `exec_file_command' command to call.  */
+
+void (*exec_file_display_hook) () = NULL;
+
+struct section_table *core_sections, *core_sections_end;
+
+/* Binary file diddling handle for the core file.  */
+
+bfd *core_bfd = NULL;
+
+/* Forward decl */
+extern struct target_ops core_ops;
+
+\f
+/* Discard all vestiges of any previous core file
+   and mark data and stack spaces as empty.  */
+
+void
+core_close (quitting)
+     int quitting;
+{
+  if (core_bfd) {
+    free (bfd_get_filename (core_bfd));
+    bfd_close (core_bfd);
+    core_bfd = NULL;
+  }
+}
+
+/* This routine opens and sets up the core file bfd */
+
+void
+core_open (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  char *p;
+  int siggy;
+  struct cleanup *old_chain;
+  char *temp;
+  bfd *temp_bfd;
+  int ontop;
+
+  if (!filename)
+    {
+      error (core_bfd? 
+       "No core file specified.  (Use `detach' to stop debugging a core file.)"
+     : "No core file specified.");
+    }
+
+  filename = tilde_expand (filename);
+  if (filename[0] != '/') {
+    temp = concat (current_directory, "/", filename);
+    free (filename);
+    filename = temp;
+  }
+
+  old_chain = make_cleanup (free, filename);
+  temp_bfd = bfd_openr (filename, NULL);
+  if (temp_bfd == NULL)
+    {
+      perror_with_name (filename);
+    }
+
+  if (!bfd_check_format (temp_bfd, bfd_core))
+    {
+      bfd_close (temp_bfd);
+      error ("\"%s\" does not appear to be a core dump", filename);
+    }
+
+  /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
+
+  discard_cleanups (old_chain);                /* Don't free filename any more */
+  unpush_target (&core_ops);
+  core_bfd = temp_bfd;
+  old_chain = make_cleanup (core_close, core_bfd);
+
+  validate_files ();
+
+  /* Find the data section */
+  if (build_section_table (core_bfd, &core_sections, &core_sections_end))
+    error ("Can't find sections in `%s': %s", bfd_get_filename(core_bfd),
+          bfd_errmsg (bfd_error));
+
+  ontop = !push_target (&core_ops);
+
+  p = bfd_core_file_failing_command (core_bfd);
+  if (p)
+    printf ("Core file invoked as `%s'.\n", p);
+
+  siggy = bfd_core_file_failing_signal (core_bfd);
+  if (siggy > 0)
+    printf ("Program terminated with signal %d, %s.\n", siggy,
+           siggy < NSIG ? sys_siglist[siggy] : "(undocumented)");
+
+  if (ontop) {
+    /* Fetch all registers from core file */
+    target_fetch_registers (-1);
+    set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                         read_pc ()));
+    select_frame (get_current_frame (), 0);
+    /* FIXME, handle shared library reading here.  */
+    print_sel_frame (0);       /* Print the top frame and source line */
+  } else {
+    printf (
+"Warning: you won't be able to access this core file until you terminate\n\
+your %s; do ``info files''\n", current_target->to_longname);
+  }
+
+  discard_cleanups (old_chain);
+}
+
+void
+core_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  dont_repeat ();
+  if (args)
+    error ("Too many arguments");
+  pop_target ();
+  if (from_tty)
+    printf ("No core file now.\n");
+}
+
+/* Backward compatability with old way of specifying core files.  */
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  if (!filename)
+    core_detach (filename, from_tty);
+  else
+    core_open (filename, from_tty);
+}
+
+\f
+/* Call this to specify the hook for exec_file_command to call back.
+   This is called from the x-window display code.  */
+
+void
+specify_exec_file_hook (hook)
+     void (*hook) ();
+{
+  exec_file_display_hook = hook;
+}
+
+/* The exec file must be closed before running an inferior.
+   If it is needed again after the inferior dies, it must
+   be reopened.  */
+
+void
+close_exec_file ()
+{
+#ifdef FIXME
+  if (exec_bfd)
+    bfd_tempclose (exec_bfd);
+#endif
+}
+
+void
+reopen_exec_file ()
+{
+#ifdef FIXME
+  if (exec_bfd)
+    bfd_reopen (exec_bfd);
+#endif
+}
+\f
+/* If we have both a core file and an exec file,
+   print a warning if they don't go together.
+   This should really check that the core file came
+   from that exec file, but I don't know how to do it.  */
+
+void
+validate_files ()
+{
+  if (exec_bfd && core_bfd)
+    {
+      if (core_file_matches_executable_p (core_bfd, exec_bfd))
+       printf ("Warning: core file does not match specified executable file.\n");
+      else if (bfd_get_mtime(exec_bfd) > bfd_get_mtime(core_bfd))
+       printf ("Warning: exec file is newer than core file.\n");
+    }
+}
+
+/* Return the name of the executable file as a string.
+   ERR nonzero means get error if there is none specified;
+   otherwise return 0 in that case.  */
+
+char *
+get_exec_file (err)
+     int err;
+{
+  if (exec_bfd) return bfd_get_filename(exec_bfd);
+  if (!err)     return NULL;
+
+  error ("No executable file specified.\n\
+Use the \"file\" or \"exec-file\" command.");
+  return NULL;
+}
+
+static void
+core_files_info ()
+{
+  struct section_table *p;
+
+  printf ("\tCore file `%s'.\n", bfd_get_filename(core_bfd));
+
+  for (p = core_sections; p < core_sections_end; p++)
+    printf("\tcore file  from 0x%08x to 0x%08x is %s\n",
+       p->addr, p->endaddr,
+       bfd_section_name (core_bfd, p->sec_ptr));
+}
+\f
+void
+memory_error (status, memaddr)
+     int status;
+     CORE_ADDR memaddr;
+{
+
+  if (status == EIO)
+    {
+      /* Actually, address between memaddr and memaddr + len
+        was out of bounds. */
+      error ("Cannot access memory: address 0x%x out of bounds.", memaddr);
+    }
+  else
+    {
+      if (status >= sys_nerr || status < 0)
+       error ("Error accessing memory address 0x%x: unknown error (%d).",
+              memaddr, status);
+      else
+       error ("Error accessing memory address 0x%x: %s.",
+              memaddr, sys_errlist[status]);
+    }
+}
+
+/* Same as target_read_memory, but report an error if can't read.  */
+void
+read_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int status;
+  status = target_read_memory (memaddr, myaddr, len);
+  if (status != 0)
+    memory_error (status, memaddr);
+}
+
+/* Same as target_write_memory, but report an error if can't write.  */
+void
+write_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int status;
+
+  status = target_write_memory (memaddr, myaddr, len);
+  if (status != 0)
+    memory_error (status, memaddr);
+}
+
+/* Read an integer from debugged memory, given address and number of bytes.  */
+
+long
+read_memory_integer (memaddr, len)
+     CORE_ADDR memaddr;
+     int len;
+{
+  char cbuf;
+  short sbuf;
+  int ibuf;
+  long lbuf;
+
+  if (len == sizeof (char))
+    {
+      read_memory (memaddr, &cbuf, len);
+      return cbuf;
+    }
+  if (len == sizeof (short))
+    {
+      read_memory (memaddr, (char *)&sbuf, len);
+      SWAP_TARGET_AND_HOST (&sbuf, sizeof (short));
+      return sbuf;
+    }
+  if (len == sizeof (int))
+    {
+      read_memory (memaddr, (char *)&ibuf, len);
+      SWAP_TARGET_AND_HOST (&ibuf, sizeof (int));
+      return ibuf;
+    }
+  if (len == sizeof (lbuf))
+    {
+      read_memory (memaddr, (char *)&lbuf, len);
+      SWAP_TARGET_AND_HOST (&lbuf, sizeof (lbuf));
+      return lbuf;
+    }
+  error ("Cannot handle integers of %d bytes.", len);
+  return -1;   /* for lint */
+}
+\f
+/* Read or write the core file.
+
+   Args are address within core file, address within gdb address-space,
+   length, and a flag indicating whether to read or write.
+
+   Result is a length:
+
+       0:    We cannot handle this address and length.
+       > 0:  We have handled N bytes starting at this address.
+             (If N == length, we did it all.)  We might be able
+             to handle more bytes beyond this length, but no
+             promises.
+       < 0:  We cannot handle this address, but if somebody
+             else handles (-N) bytes, we can start from there.
+
+   The actual work is done by xfer_memory in exec.c, which we share
+   in common with exec_xfer_memory().  */
+
+static int
+core_xfer_memory (memaddr, myaddr, len, write)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int write;
+{
+  return xfer_memory (memaddr, myaddr, len, write,
+                     core_bfd, core_sections, core_sections_end);
+}
+\f
+/* Get the registers out of a core file.  This is the machine-
+   independent part.  Fetch_core_registers is the machine-dependent
+   part, typically implemented in the xm-file for each architecture.  */
+
+static int
+get_core_registers (regno)
+     int regno;
+{
+  sec_ptr reg_sec;
+  unsigned size;
+  char *the_regs;
+
+  reg_sec = bfd_get_section_by_name (core_bfd, ".reg");
+  size = bfd_section_size (core_bfd, reg_sec);
+  the_regs = alloca (size);
+  if (bfd_get_section_contents (core_bfd, reg_sec, the_regs,
+                               (unsigned)0, size))
+    {
+      fetch_core_registers (the_regs, size, 0);
+    }
+  else
+    {
+      fprintf (stderr, "Couldn't fetch registers from core file: %s\n",
+              bfd_errmsg (bfd_error));
+    }
+
+  /* Now do it again for the float registers, if they exist.  */
+  reg_sec = bfd_get_section_by_name (core_bfd, ".reg2");
+  if (reg_sec) {
+    size = bfd_section_size (core_bfd, reg_sec);
+    the_regs = alloca (size);
+    if (bfd_get_section_contents (core_bfd, reg_sec, the_regs,
+                                 (unsigned)0, size))
+      {
+       fetch_core_registers (the_regs, size, 2);
+      }
+    else
+      {
+       fprintf (stderr, "Couldn't fetch register set 2 from core file: %s\n",
+                bfd_errmsg (bfd_error));
+      }
+  }
+  registers_fetched();
+  return 0;  /* FIXME, what result goes here?  */
+}
+\f
+struct target_ops core_ops = {
+       "core", "Local core dump file",
+       core_open, core_close,
+       child_attach, core_detach, 0, 0, /* resume, wait */
+       get_core_registers, 
+       0, 0, 0, 0, /* store_regs, prepare_to_store, conv_to, conv_from */
+       core_xfer_memory, core_files_info,
+       0, 0, /* core_insert_breakpoint, core_remove_breakpoint, */
+       0, 0, 0, 0, 0, /* terminal stuff */
+       0, 0, 0, 0, 0, /* kill, load, add_syms, call fn, lookup sym */
+       child_create_inferior, 0, /* mourn_inferior */
+       core_stratum, 0, /* next */
+       0, 1, 1, 1, 0,  /* all mem, mem, stack, regs, exec */
+       OPS_MAGIC,              /* Always the last thing */
+};
+
+void
+_initialize_core()
+{
+
+  add_com ("core-file", class_files, core_file_command,
+          "Use FILE as core dump for examining memory and registers.\n\
+No arg means have no core file.  This command has been superseded by the\n\
+`target core' and `detach' commands.");
+  add_target (&core_ops);
+}
diff --git a/gdb/coredep.c b/gdb/coredep.c
new file mode 100644 (file)
index 0000000..ea1c273
--- /dev/null
@@ -0,0 +1,86 @@
+/* Extract registers from a "standard" core file, for GDB.
+   Copyright (C) 1988-1991  Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* core.c is supposed to be the more machine-independent aspects of this;
+   this file is more machine-specific.  */
+
+#include "defs.h"
+#include "param.h"
+#include "gdbcore.h"
+
+/* Some of these are needed on various systems, perhaps, to expand
+   REGISTER_U_ADDR appropriately?  */
+/* #include <sys/core.h> */
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/user.h>
+
+
+/* Extract the register values out of the core file and store
+   them where `read_register' will find them.  */
+
+void
+fetch_core_registers (core_reg_sect, core_reg_size)
+     char *core_reg_sect;
+     unsigned core_reg_size;
+{
+  register int regno;
+  register unsigned int addr;
+  int bad_reg = -1;
+
+  for (regno = 0; regno < NUM_REGS; regno++)
+    {
+      addr = register_addr (regno, core_reg_size);
+      if (addr >= core_reg_size) {
+       if (bad_reg < 0)
+         bad_reg = regno;
+      } else {
+       supply_register (regno, core_reg_sect + addr);
+      }
+    }
+  if (bad_reg > 0)
+    {
+      error ("Register %s not found in core file.", reg_names[bad_reg]);
+    }
+}
+
+
+#ifdef REGISTER_U_ADDR
+
+/* Return the address in the core dump or inferior of register REGNO.
+   BLOCKEND is the address of the end of the user structure.  */
+
+unsigned int
+register_addr (regno, blockend)
+     int regno;
+     int blockend;
+{
+  int addr;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    error ("Invalid register number %d.", regno);
+
+  REGISTER_U_ADDR (addr, blockend, regno);
+
+  return addr;
+}
+
+#endif /* REGISTER_U_ADDR */
diff --git a/gdb/cplus-dem.c b/gdb/cplus-dem.c
new file mode 100644 (file)
index 0000000..48109d8
--- /dev/null
@@ -0,0 +1,1001 @@
+/* Demangler for GNU C++ 
+   Copyright (C) 1989 Free Software Foundation, Inc.
+   written by James Clark (jjc@jclark.uucp)
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is for g++ 1.36.1 (November 6 version). It will probably
+   require changes for any other version.
+
+   Modified for g++ 1.36.2 (November 18 version).  */
+
+/* This file exports one function
+
+   char *cplus_demangle (const char *name, int mode)
+   
+   If NAME is a mangled function name produced by GNU C++, then
+   a pointer to a malloced string giving a C++ representation
+   of the name will be returned; otherwise NULL will be returned.
+   It is the caller's responsibility to free the string which
+   is returned.
+
+   If MODE > 0, then ANSI qualifiers such as `const' and `void' are output.
+   Otherwise they are not.
+   If MODE >= 0, parameters are emitted; otherwise not.
+
+   For example,
+   
+   cplus_demangle ("foo__1Ai",  0)     => "A::foo(int)"
+   cplus_demangle ("foo__1Ai",  1)     => "A::foo(int)"
+   cplus_demangle ("foo__1Ai", -1)     => "A::foo"
+
+   cplus_demangle ("foo__1Afe",  0)    => "A::foo(float,...)"
+   cplus_demangle ("foo__1Afe",  1)    => "A::foo(float,...)"
+   cplus_demangle ("foo__1Afe", -1)    => "A::foo"
+
+   This file imports xmalloc and xrealloc, which are like malloc and
+   realloc except that they generate a fatal error if there is no
+   available memory. */
+
+/* define this if names don't start with _ */
+/* #define nounderscore 1 */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef USG
+#include <memory.h>
+#include <string.h>
+#else
+#include <strings.h>
+#define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
+#define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
+#define strchr index 
+#define strrchr rindex
+#endif
+
+#ifndef __STDC__
+#define const
+#endif
+
+#ifdef __STDC__
+extern char *cplus_demangle (const char *type, int mode);
+#else
+extern char *cplus_demangle ();
+#endif
+
+#ifdef __STDC__
+extern char *xmalloc (int);
+extern char *xrealloc (char *, int);
+extern void free (char *);
+#else
+extern char *xmalloc ();
+extern char *xrealloc ();
+extern void free ();
+#endif
+
+static char **typevec = 0;
+static int ntypes = 0;
+static int typevec_size = 0;
+
+static struct {
+  const char *in;
+  const char *out;
+} optable[] = {
+  "new", " new",
+  "delete", " delete",
+  "ne", "!=",
+  "eq", "==",
+  "ge", ">=",
+  "gt", ">",
+  "le", "<=",
+  "lt", "<",
+  "plus", "+",
+  "minus", "-",
+  "mult", "*",
+  "convert", "+",      /* unary + */
+  "negate", "-",       /* unary - */
+  "trunc_mod", "%",
+  "trunc_div", "/",
+  "truth_andif", "&&",
+  "truth_orif", "||",
+  "truth_not", "!",
+  "postincrement", "++",
+  "postdecrement", "--",
+  "bit_ior", "|",
+  "bit_xor", "^",
+  "bit_and", "&",
+  "bit_not", "~",
+  "call", "()",
+  "cond", "?:",
+  "alshift", "<<",
+  "arshift", ">>",
+  "component", "->",
+  "indirect", "*",
+  "method_call", "->()",
+  "addr", "&",         /* unary & */
+  "array", "[]",
+  "nop", "",                   /* for operator= */
+};
+
+/* Beware: these aren't '\0' terminated. */
+
+typedef struct {
+  char *b;                     /* pointer to start of string */
+  char *p;                     /* pointer after last character */
+  char *e;                     /* pointer after end of allocated space */
+} string;
+
+#ifdef __STDC__
+static void string_need (string *s, int n);
+static void string_delete (string *s);
+static void string_init (string *s);
+static void string_clear (string *s);
+static int string_empty (string *s);
+static void string_append (string *p, const char *s);
+static void string_appends (string *p, string *s);
+static void string_appendn (string *p, const char *s, int n);
+static void string_prepend (string *p, const char *s);
+#if 0
+static void string_prepends (string *p, string *s);
+#endif
+static void string_prependn (string *p, const char *s, int n);
+static int get_count (const char **type, int *count);
+static int do_args (const char **type, string *decl, int arg_mode);
+static int do_type (const char **type, string *result, int arg_mode);
+static int do_arg (const char **type, string *result, int arg_mode);
+static void munge_function_name (string *name, int arg_mode);
+static void remember_type (const char *type, int len);
+#else
+static void string_need ();
+static void string_delete ();
+static void string_init ();
+static void string_clear ();
+static int string_empty ();
+static void string_append ();
+static void string_appends ();
+static void string_appendn ();
+static void string_prepend ();
+#if 0
+static void string_prepends ();
+#endif
+static void string_prependn ();
+static int get_count ();
+static int do_args ();
+static int do_type ();
+static int do_arg ();
+static int do_args ();
+static void munge_function_name ();
+static void remember_type ();
+#endif
+
+char *
+cplus_demangle (type, arg_mode)
+     const char *type;
+     int arg_mode;
+{
+  string decl;
+  int n;
+  int success = 0;
+  int constructor = 0;
+  int const_flag = 0;
+  int i;
+  const char *p;
+#ifndef LONGERNAMES
+  const char *premangle;
+#endif
+
+# define print_ansi_qualifiers (arg_mode >  0)
+# define print_arg_types       (arg_mode >= 0)
+
+  if (type == NULL || *type == '\0')
+    return NULL;
+#ifndef nounderscore
+  if (*type++ != '_')
+    return NULL;
+#endif
+  p = type;
+  while (*p != '\0' && !(*p == '_' && p[1] == '_'))
+    p++;
+  if (*p == '\0')
+    {
+      /* destructor */
+      if (type[0] == '_' && type[1] == '$' && type[2] == '_')
+       {
+         int n = (strlen (type) - 3)*2 + 3 + 2 + 1;
+         char *tem = (char *) xmalloc (n);
+         strcpy (tem, type + 3);
+         strcat (tem, "::~");
+         strcat (tem, type + 3);
+         strcat (tem, "()");
+         return tem;
+       }
+      /* static data member */
+      if (*type != '_' && (p = strchr (type, '$')) != NULL)
+       {
+         int n = strlen (type) + 2;
+         char *tem = (char *) xmalloc (n);
+         memcpy (tem, type, p - type);
+         strcpy (tem + (p - type), "::");
+         strcpy (tem + (p - type) + 2, p + 1);
+         return tem;
+       }
+      /* virtual table "_vt$" */
+      if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == '$')
+       {
+         int n = strlen (type + 4) + 14 + 1;
+         char *tem = (char *) xmalloc (n);
+         strcpy (tem, type + 4);
+         strcat (tem, " virtual table");
+         return tem;
+       }
+      return NULL;
+    }
+
+  string_init (&decl);
+
+  if (p == type)
+    {
+      if (!isdigit (p[2]))
+       {
+         string_delete (&decl);
+         return NULL;
+       }
+      constructor = 1;
+    }
+  else
+    {
+      string_appendn (&decl, type, p - type);
+      munge_function_name (&decl, arg_mode);
+    }
+  p += 2;
+
+#ifndef LONGERNAMES
+  premangle = p;
+#endif
+  switch (*p)
+    {
+    case 'C':
+      /* a const member function */
+      if (!isdigit (p[1]))
+       {
+         string_delete (&decl);
+         return NULL;
+       }
+      p += 1;
+      const_flag = 1;
+      /* fall through */
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      n = 0;
+      do
+       {
+         n *= 10;
+         n += *p - '0';
+         p += 1;
+       }
+      while (isdigit (*p));
+      if (strlen (p) < n)
+       {
+         string_delete (&decl);
+         return NULL;
+       }
+      if (constructor)
+       {
+         string_appendn (&decl, p, n);
+         string_append (&decl, "::");
+         string_appendn (&decl, p, n);
+       }
+      else
+       {
+         string_prepend (&decl, "::");
+         string_prependn (&decl, p, n);
+       }
+      p += n;
+#ifndef LONGERNAMES
+      remember_type (premangle, p - premangle);
+#endif
+      success = do_args (&p, &decl, arg_mode);
+      if (const_flag && print_arg_types)
+       string_append (&decl, " const");
+      break;
+    case 'F':
+      p += 1;
+      success = do_args (&p, &decl, arg_mode);
+      break;
+    }
+
+  for (i = 0; i < ntypes; i++)
+    if (typevec[i] != NULL)
+      free (typevec[i]);
+  ntypes = 0;
+  if (typevec != NULL)
+    {
+      free ((char *)typevec);
+      typevec = NULL;
+      typevec_size = 0;
+    }
+
+  if (success)
+    {
+      string_appendn (&decl, "", 1);
+      return decl.b;
+    }
+  else
+    {
+      string_delete (&decl);
+      return NULL;
+    }
+}
+
+static int
+get_count (type, count)
+     const char **type;
+     int *count;
+{
+  if (!isdigit (**type))
+    return 0;
+  *count = **type - '0';
+  *type += 1;
+  /* see flush_repeats in cplus-method.c */
+  if (isdigit (**type))
+    {
+      const char *p = *type;
+      int n = *count;
+      do 
+       {
+         n *= 10;
+         n += *p - '0';
+         p += 1;
+       } 
+      while (isdigit (*p));
+      if (*p == '_')
+       {
+         *type = p + 1;
+         *count = n;
+       }
+    }
+  return 1;
+}
+
+/* result will be initialised here; it will be freed on failure */
+
+static int
+do_type (type, result, arg_mode)
+     const char **type;
+     string *result;
+     int arg_mode;
+{
+  int n;
+  int done;
+  int non_empty = 0;
+  int success;
+  string decl;
+  const char *remembered_type;
+
+  string_init (&decl);
+  string_init (result);
+
+  done = 0;
+  success = 1;
+  while (success && !done)
+    {
+      int member;
+      switch (**type)
+       {
+       case 'P':
+         *type += 1;
+         string_prepend (&decl, "*");
+         break;
+
+       case 'R':
+         *type += 1;
+         string_prepend (&decl, "&");
+         break;
+
+       case 'T':
+         *type += 1;
+         if (!get_count (type, &n) || n >= ntypes)
+           success = 0;
+         else
+           {
+             remembered_type = typevec[n];
+             type = &remembered_type;
+           }
+         break;
+
+       case 'F':
+         *type += 1;
+         if (!string_empty (&decl) && decl.b[0] == '*')
+           {
+             string_prepend (&decl, "(");
+             string_append (&decl, ")");
+           }
+         if (!do_args (type, &decl, arg_mode) || **type != '_')
+           success = 0;
+         else
+           *type += 1;
+         break;
+
+       case 'M':
+       case 'O':
+         {
+           int constp = 0;
+           int volatilep = 0;
+
+           member = **type == 'M';
+           *type += 1;
+           if (!isdigit (**type))
+             {
+               success = 0;
+               break;
+             }
+           n = 0;
+           do
+             {
+               n *= 10;
+               n += **type - '0';
+               *type += 1;
+             } 
+           while (isdigit (**type));
+           if (strlen (*type) < n)
+             {
+               success = 0;
+               break;
+             }
+           string_append (&decl, ")");
+           string_prepend (&decl, "::");
+           string_prependn (&decl, *type, n);
+           string_prepend (&decl, "(");
+           *type += n;
+           if (member)
+             {
+               if (**type == 'C')
+                 {
+                   *type += 1;
+                   constp = 1;
+                 }
+               if (**type == 'V')
+                 {
+                   *type += 1;
+                   volatilep = 1;
+                 }
+               if (*(*type)++ != 'F')
+                 {
+                   success = 0;
+                   break;
+                 }
+             }
+           if ((member && !do_args (type, &decl, arg_mode)) || **type != '_')
+             {
+               success = 0;
+               break;
+             }
+           *type += 1;
+           if (! print_ansi_qualifiers)
+             break;
+           if (constp)
+             {
+               if (non_empty)
+                 string_append (&decl, " ");
+               else
+                 non_empty = 1;
+               string_append (&decl, "const");
+             }
+           if (volatilep)
+             {
+               if (non_empty)
+                 string_append (&decl, " ");
+               else
+                 non_empty = 1;
+               string_append (&decl, "volatile");
+             }
+           break;
+         }
+
+       case 'C':
+         if ((*type)[1] == 'P')
+           {
+             *type += 1;
+             if (print_ansi_qualifiers)
+               {
+                 if (!string_empty (&decl))
+                   string_prepend (&decl, " ");
+                 string_prepend (&decl, "const");
+               }
+             break;
+           }
+
+         /* fall through */
+       default:
+         done = 1;
+         break;
+       }
+    }
+
+  done = 0;
+  non_empty = 0;
+  while (success && !done)
+    {
+      switch (**type)
+       {
+       case 'C':
+         *type += 1;
+         if (print_ansi_qualifiers)
+           {
+             if (non_empty)
+               string_append (result, " ");
+             else
+               non_empty = 1;
+             string_append (result, "const");
+           }
+         break;
+       case 'U':
+         *type += 1;
+         if (non_empty)
+           string_append (result, " ");
+         else
+           non_empty = 1;
+         string_append (result, "unsigned");
+         break;
+       case 'V':
+         *type += 1;
+         if (print_ansi_qualifiers)
+           {
+             if (non_empty)
+               string_append (result, " ");
+             else
+               non_empty = 1;
+             string_append (result, "volatile");
+           }
+         break;
+       default:
+         done = 1;
+         break;
+       }
+    }
+
+  if (success)
+    switch (**type)
+      {
+      case '\0':
+      case '_':
+       break;
+      case 'v':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "void");
+       break;
+      case 'x':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "long long");
+       break;
+      case 'l':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "long");
+       break;
+      case 'i':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "int");
+       break;
+      case 's':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "short");
+       break;
+      case 'c':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "char");
+       break;
+      case 'r':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "long double");
+       break;
+      case 'd':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "double");
+       break;
+      case 'f':
+       *type += 1;
+       if (non_empty)
+         string_append (result, " ");
+       string_append (result, "float");
+       break;
+      case 'G':
+       *type += 1;
+       if (!isdigit (**type))
+         {
+           success = 0;
+           break;
+         }
+       /* fall through */
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+       n = 0;
+       do
+         {
+           n *= 10;
+           n += **type - '0';
+           *type += 1;
+         }
+       while (isdigit (**type));
+       if (strlen (*type) < n)
+         {
+           success = 0;
+           break;
+         }
+       if (non_empty)
+         string_append (result, " ");
+       string_appendn (result, *type, n);
+       *type += n;
+       break;
+      default:
+       success = 0;
+       break;
+      }
+
+  if (success)
+    {
+      if (!string_empty (&decl))
+       {
+         string_append (result, " ");
+         string_appends (result, &decl);
+       }
+      string_delete (&decl);
+      return 1;
+    }
+  else
+    {
+      string_delete (&decl);
+      string_delete (result);
+      return 0;
+    }
+}
+
+/* `result' will be initialised in do_type; it will be freed on failure */
+
+static int
+do_arg (type, result, arg_mode)
+     const char **type;
+     string *result;
+     int arg_mode;
+{
+  const char *start = *type;
+
+  if (!do_type (type, result, arg_mode))
+    return 0;
+  remember_type (start, *type - start);
+  return 1;
+}
+
+static void
+remember_type (start, len)
+     const char *start;
+     int len;
+{
+  char *tem;
+
+  if (ntypes >= typevec_size)
+    {
+      if (typevec_size == 0)
+       {
+         typevec_size = 3;
+         typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
+       }
+      else
+       {
+         typevec_size *= 2;
+         typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
+       }
+    }
+  tem = (char *) xmalloc (len + 1);
+  memcpy (tem, start, len);
+  tem[len] = '\0';
+  typevec[ntypes++] = tem;
+}
+
+/* `decl' must be already initialised, usually non-empty;
+   it won't be freed on failure */
+
+static int
+do_args (type, decl, arg_mode)
+     const char **type;
+     string *decl;
+     int arg_mode;
+{
+  string arg;
+  int need_comma = 0;
+
+  if (print_arg_types)
+    string_append (decl, "(");
+
+  while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
+    {
+      if (**type == 'N')
+       {
+         int r;
+         int t;
+         *type += 1;
+         if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
+           return 0;
+         while (--r >= 0)
+           {
+             const char *tem = typevec[t];
+             if (need_comma && print_arg_types)
+               string_append (decl, ", ");
+             if (!do_arg (&tem, &arg, arg_mode))
+               return 0;
+             if (print_arg_types)
+               string_appends (decl, &arg);
+             string_delete (&arg);
+             need_comma = 1;
+           }
+       }
+      else
+       {
+         if (need_comma & print_arg_types)
+           string_append (decl, ", ");
+         if (!do_arg (type, &arg, arg_mode))
+           return 0;
+         if (print_arg_types)
+           string_appends (decl, &arg);
+         string_delete (&arg);
+         need_comma = 1;
+       }
+    }
+
+  if (**type == 'v')
+    *type += 1;
+  else if (**type == 'e')
+    {
+      *type += 1;
+      if (print_arg_types)
+       {
+         if (need_comma)
+           string_append (decl, ",");
+         string_append (decl, "...");
+       }
+    }
+
+  if (print_arg_types)
+    string_append (decl, ")");
+  return 1;
+}
+
+static void
+munge_function_name (name, arg_mode)
+     string *name;
+     int arg_mode;
+{
+  if (!string_empty (name) && name->p - name->b >= 3 
+      && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$')
+    {
+      int i;
+      /* see if it's an assignment expression */
+      if (name->p - name->b >= 10 /* op$assign_ */
+         && memcmp (name->b + 3, "assign_", 7) == 0)
+       {
+         for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
+           {
+             int len = name->p - name->b - 10;
+             if (strlen (optable[i].in) == len
+                 && memcmp (optable[i].in, name->b + 10, len) == 0)
+               {
+                 string_clear (name);
+                 string_append (name, "operator");
+                 string_append (name, optable[i].out);
+                 string_append (name, "=");
+                 return;
+               }
+           }
+       }
+      else
+       {
+         for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
+           {
+             int len = name->p - name->b - 3;
+             if (strlen (optable[i].in) == len 
+                 && memcmp (optable[i].in, name->b + 3, len) == 0)
+               {
+                 string_clear (name);
+                 string_append (name, "operator");
+                 string_append (name, optable[i].out);
+                 return;
+               }
+           }
+       }
+      return;
+    }
+  else if (!string_empty (name) && name->p - name->b >= 5
+          && memcmp (name->b, "type$", 5) == 0)
+    {
+      /* type conversion operator */
+      string type;
+      const char *tem = name->b + 5;
+      if (do_type (&tem, &type, arg_mode))
+       {
+         string_clear (name);
+         string_append (name, "operator ");
+         string_appends (name, &type);
+         string_delete (&type);
+         return;
+       }
+    }
+}
+
+/* a mini string-handling package */
+
+static void
+string_need (s, n)
+     string *s;
+     int n;
+{
+  if (s->b == NULL)
+    {
+      if (n < 32)
+       n = 32;
+      s->p = s->b = (char *) xmalloc (n);
+      s->e = s->b + n;
+    }
+  else if (s->e - s->p < n)
+    {
+      int tem = s->p - s->b;
+      n += tem;
+      n *= 2;
+      s->b = (char *) xrealloc (s->b, n);
+      s->p = s->b + tem;
+      s->e = s->b + n;
+    }
+}
+
+static void
+string_delete (s)
+     string *s;
+{
+  if (s->b != NULL)
+    {
+      free (s->b);
+      s->b = s->e = s->p = NULL;
+    }
+}
+
+static void
+string_init (s)
+     string *s;
+{
+  s->b = s->p = s->e = NULL;
+}
+
+static void 
+string_clear (s)
+     string *s;
+{
+  s->p = s->b;
+}
+
+static int
+string_empty (s)
+     string *s;
+{
+  return s->b == s->p;
+}
+
+static void
+string_append (p, s)
+     string *p;
+     const char *s;
+{
+  int n;
+  if (s == NULL || *s == '\0')
+    return;
+  n = strlen (s);
+  string_need (p, n);
+  memcpy (p->p, s, n);
+  p->p += n;
+}
+
+static void
+string_appends (p, s)
+     string *p, *s;
+{
+  int n;
+  if (s->b == s->p)
+    return;
+  n = s->p - s->b;
+  string_need (p, n);
+  memcpy (p->p, s->b, n);
+  p->p += n;
+}
+
+static void
+string_appendn (p, s, n)
+     string *p;
+     const char *s;
+     int n;
+{
+  if (n == 0)
+    return;
+  string_need (p, n);
+  memcpy (p->p, s, n);
+  p->p += n;
+}
+
+static void
+string_prepend (p, s)
+     string *p;
+     const char *s;
+{
+  if (s == NULL || *s == '\0')
+    return;
+  string_prependn (p, s, strlen (s));
+}
+
+#if 0
+static void
+string_prepends (p, s)
+     string *p, *s;
+{
+  if (s->b == s->p)
+    return;
+  string_prependn (p, s->b, s->p - s->b);
+}
+#endif
+
+static void
+string_prependn (p, s, n)
+     string *p;
+     const char *s;
+     int n;
+{
+  char *q;
+
+  if (n == 0)
+    return;
+  string_need (p, n);
+  for (q = p->p - 1; q >= p->b; q--)
+    q[n] = q[0];
+  memcpy (p->b, s, n);
+  p->p += n;
+}
diff --git a/gdb/createtags b/gdb/createtags
new file mode 100755 (executable)
index 0000000..6f02ff2
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# Here we check to see if we are compiling in a directory that contains
+# symlinks to the source files instead of the actual files.  If this is so, 
+# we setup the TAGS entries to point to the actual source directory.
+#
+filelist=""
+if test "`find main.c -type l -print `" != "" ; then
+       prefix=`ls -l main.c | awk '{print $11}' | sed 's;main.c$;;'`
+else
+       prefix=""
+fi
+
+# Replace .o at end of filename with .c
+for i in $@ ; do
+       file=`echo $i-x- | sed -e 's/\.o-x-/\.c-x-/' | sed -e 's/-x-//'`
+       filelist="$filelist $prefix$file"
+done
+
+etags $filelist
diff --git a/gdb/depend b/gdb/depend
new file mode 100755 (executable)
index 0000000..c78aa66
--- /dev/null
@@ -0,0 +1,195 @@
+altos-xdep.o : altos-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+am29k-pinsn.o : am29k-pinsn.c defs.h target.h am29k-opcode.h 
+am29k-tdep.o : am29k-tdep.c defs.h gdbcore.h $(INCLUDE_DIR)/bfd.h frame.h \
+  param.h tm.h config.status param-no-tm.h xm.h config.status value.h symtab.h inferior.h breakpoint.h 
+arm-pinsn.o : arm-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  arm-opcode.h 
+arm-tdep.o : arm-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h arm-opcode.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+arm-xdep.o : arm-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h arm-opcode.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+blockframe.o : blockframe.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  frame.h gdbcore.h $(INCLUDE_DIR)/bfd.h value.h target.h 
+breakpoint.o : breakpoint.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  frame.h breakpoint.h value.h expression.h gdbcore.h $(INCLUDE_DIR)/bfd.h \
+  gdbcmd.h command.h inferior.h target.h 
+coffread.o : coffread.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  breakpoint.h value.h $(INCLUDE_DIR)/bfd.h $(BFD_DIR)/libcoff.h symfile.h 
+command.o : command.c defs.h command.h symtab.h value.h 
+convex-pinsn.o : convex-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  symtab.h convex-opcode.h 
+convex-tdep.o : convex-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  command.h symtab.h value.h frame.h inferior.h breakpoint.h \
+  $(INCLUDE_DIR)/wait.h gdbcore.h $(INCLUDE_DIR)/bfd.h gdbcmd.h 
+convex-xdep.o : convex-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  command.h symtab.h value.h frame.h inferior.h breakpoint.h \
+  $(INCLUDE_DIR)/wait.h gdbcore.h $(INCLUDE_DIR)/bfd.h gdbcmd.h 
+core.o : core.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h inferior.h \
+  breakpoint.h value.h symtab.h command.h $(INCLUDE_DIR)/bfd.h target.h \
+  gdbcore.h 
+coredep.o : coredep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+cplus-dem.o : cplus-dem.c 
+dbxread.o : dbxread.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  $(INCLUDE_DIR)/a.out.gnu.h $(INCLUDE_DIR)/target.h $(INCLUDE_DIR)/reloc.h \
+  $(INCLUDE_DIR)/stab.gnu.h $(INCLUDE_DIR)/stab.def symtab.h breakpoint.h value.h \
+  command.h target.h gdbcore.h $(INCLUDE_DIR)/bfd.h $(BFD_DIR)/liba.out.h \
+  symfile.h 
+environ.o : environ.c environ.h 
+eval.o : eval.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h value.h \
+  expression.h target.h 
+exec.o : exec.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h inferior.h \
+  breakpoint.h value.h symtab.h target.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+expprint.o : expprint.c defs.h symtab.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  expression.h value.h 
+findvar.o : findvar.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  frame.h value.h gdbcore.h $(INCLUDE_DIR)/bfd.h inferior.h breakpoint.h \
+  target.h 
+gould-pinsn.o : gould-pinsn.c gdbcore.h $(INCLUDE_DIR)/bfd.h defs.h param.h \
+  tm.h config.status param-no-tm.h xm.h config.status symtab.h frame.h np1-opcode.h 
+gould-xdep.o : gould-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+hp300hpux-xdep.o : hp300hpux-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  frame.h inferior.h breakpoint.h value.h symtab.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+i386-pinsn.o : i386-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  frame.h inferior.h breakpoint.h value.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+i386-tdep.o : i386-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+i386-xdep.o : i386-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+i960-pinsn.o : i960-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h 
+i960-tdep.o : i960-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  value.h frame.h signame.h ieee-float.h 
+ieee-float.o : ieee-float.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  ieee-float.h 
+infcmd.o : infcmd.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h frame.h \
+  inferior.h breakpoint.h value.h environ.h gdbcmd.h command.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h target.h 
+inflow.o : inflow.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h command.h signals.h terminal.h \
+  target.h 
+infptrace.o : infptrace.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h target.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+infrun.o : infrun.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h frame.h \
+  inferior.h breakpoint.h value.h $(INCLUDE_DIR)/wait.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h signame.h command.h terminal.h target.h 
+inftarg.o : inftarg.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h target.h $(INCLUDE_DIR)/wait.h \
+  gdbcore.h $(INCLUDE_DIR)/bfd.h ieee-float.h 
+m68k-pinsn.o : m68k-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  m68k-opcode.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+m68k-tdep.o : m68k-tdep.c defs.h ieee-float.h 
+main.o : main.c defs.h gdbcmd.h command.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  symtab.h inferior.h breakpoint.h value.h frame.h signals.h target.h 
+mem-break.o : mem-break.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status 
+mips-pinsn.o : mips-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  mips-opcode.h 
+mips-tdep.o : mips-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcmd.h command.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+mips-xdep.o : mips-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+mipsread.o : mipsread.c param.h tm.h config.status param-no-tm.h xm.h config.status obstack.h defs.h \
+  symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h symfile.h $(INCLUDE_DIR)/intel-coff.h 
+news-xdep.o : news-xdep.c 
+Onindy.o : ${srcdir}/nindy-share/Onindy.c ${srcdir}/nindy-share/ttycntl.h \
+  ${srcdir}/nindy-share/block_io.h $(INCLUDE_DIR)/wait.h ${srcdir}/nindy-share/env.h \
+  /usr/include/string.h 
+nindy.o : ${srcdir}/nindy-share/nindy.c ${srcdir}/nindy-share/ttycntl.h ${srcdir}/nindy-share/block_io.h \
+  $(INCLUDE_DIR)/wait.h ${srcdir}/nindy-share/env.h /usr/include/string.h 
+ttybreak.o : ${srcdir}/nindy-share/ttybreak.c ${srcdir}/nindy-share/ttycntl.h 
+ttyflush.o : ${srcdir}/nindy-share/ttyflush.c ${srcdir}/nindy-share/ttycntl.h 
+nindy-tdep.o : nindy-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  frame.h 
+ns32k-pinsn.o : ns32k-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  symtab.h ns32k-opcode.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+printcmd.o : printcmd.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  symtab.h value.h expression.h gdbcore.h $(INCLUDE_DIR)/bfd.h gdbcmd.h \
+  command.h target.h 
+pyr-pinsn.o : pyr-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  pyr-opcode.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+pyr-tdep.o : pyr-tdep.c 
+pyr-xdep.o : pyr-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+remote-eb.o : remote-eb.c defs.h tm-29k.h param-no-tm.h xm.h config.status inferior.h \
+  breakpoint.h value.h symtab.h frame.h param.h $(INCLUDE_DIR)/wait.h \
+  terminal.h target.h 
+remote-nindy.o : remote-nindy.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  frame.h inferior.h breakpoint.h value.h symtab.h target.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h command.h ieee-float.h $(INCLUDE_DIR)/wait.h \
+  ${srcdir}/nindy-share/ttycntl.h ${srcdir}/nindy-share/demux.h ${srcdir}/nindy-share/env.h \
+  ${srcdir}/nindy-share/stop.h 
+remote-vx.o : remote-vx.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h $(INCLUDE_DIR)/wait.h target.h \
+  gdbcore.h $(INCLUDE_DIR)/bfd.h command.h symfile.h ${srcdir}/vx-share/xdr_ptrace.h \
+  ${srcdir}/vx-share/xdr_regs.h ${srcdir}/vx-share/reg.h ${srcdir}/vx-share/xdr_ld.h \
+  ${srcdir}/vx-share/xdr_rdb.h ${srcdir}/vx-share/dbgRpcLib.h 
+remote.o : remote.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h target.h $(INCLUDE_DIR)/wait.h \
+  terminal.h 
+signame.o : signame.c signame.h 
+solib.o : solib.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h command.h 
+source.o : source.c defs.h symtab.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  command.h frame.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+sparc-pinsn.o : sparc-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  symtab.h sparc-opcode.h gdbcore.h $(INCLUDE_DIR)/bfd.h /usr/include/string.h \
+  target.h 
+sparc-tdep.o : sparc-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h obstack.h signame.h target.h \
+  ieee-float.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+sparc-xdep.o : sparc-xdep.c defs.h tm-sparc.h param-no-tm.h xm.h config.status inferior.h \
+  breakpoint.h value.h symtab.h frame.h param.h target.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+stack.o : stack.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h frame.h \
+  gdbcmd.h command.h value.h gdbcore.h $(INCLUDE_DIR)/bfd.h target.h \
+  breakpoint.h 
+sun3-xdep.o : sun3-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status inferior.h \
+  breakpoint.h value.h symtab.h frame.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+sun386-xdep.o : sun386-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  frame.h inferior.h breakpoint.h value.h symtab.h signame.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+symfile.o : symfile.c defs.h symtab.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  gdbcore.h $(INCLUDE_DIR)/bfd.h frame.h target.h value.h symfile.h gdbcmd.h \
+  command.h breakpoint.h 
+symmetry-tdep.o : symmetry-tdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  frame.h inferior.h breakpoint.h value.h symtab.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+symmetry-xdep.o : symmetry-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  frame.h inferior.h breakpoint.h value.h symtab.h gdbcore.h \
+  $(INCLUDE_DIR)/bfd.h 
+symmisc.o : symmisc.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  breakpoint.h value.h command.h 
+symtab.o : symtab.c defs.h symtab.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  gdbcore.h $(INCLUDE_DIR)/bfd.h frame.h target.h value.h symfile.h gdbcmd.h \
+  command.h 
+target.o : target.c defs.h target.h gdbcmd.h command.h symtab.h inferior.h \
+  breakpoint.h value.h frame.h param.h tm.h config.status param-no-tm.h xm.h config.status \
+  $(INCLUDE_DIR)/bfd.h symfile.h 
+tdesc.o : tdesc.c 
+umax-xdep.o : umax-xdep.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status frame.h \
+  inferior.h breakpoint.h value.h symtab.h gdbcore.h $(INCLUDE_DIR)/bfd.h 
+utils.o : utils.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status signals.h gdbcmd.h \
+  command.h terminal.h $(INCLUDE_DIR)/bfd.h target.h 
+valarith.o : valarith.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status value.h \
+  symtab.h expression.h target.h 
+valops.o : valops.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h value.h \
+  frame.h inferior.h breakpoint.h gdbcore.h $(INCLUDE_DIR)/bfd.h target.h 
+valprint.o : valprint.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  value.h gdbcore.h $(INCLUDE_DIR)/bfd.h gdbcmd.h command.h target.h obstack.h 
+values.o : values.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h value.h \
+  gdbcore.h $(INCLUDE_DIR)/bfd.h frame.h command.h 
+vax-pinsn.o : vax-pinsn.c defs.h param.h tm.h config.status param-no-tm.h xm.h config.status symtab.h \
+  vax-opcode.h 
+xdr_ld.o : ${srcdir}/vx-share/xdr_ld.c ${srcdir}/vx-share/vxWorks.h ${srcdir}/vx-share/vxTypes.h \
+  /usr/include/rpc/rpc.h ${srcdir}/vx-share/xdr_ld.h 
+xdr_ptrace.o : ${srcdir}/vx-share/xdr_ptrace.c 
+xdr_rdb.o : ${srcdir}/vx-share/xdr_rdb.c ${srcdir}/vx-share/vxWorks.h ${srcdir}/vx-share/vxTypes.h \
+  ${srcdir}/vx-share/xdr_rdb.h 
+xdr_regs.o : ${srcdir}/vx-share/xdr_regs.c 
diff --git a/gdb/expread.tab.c b/gdb/expread.tab.c
new file mode 100755 (executable)
index 0000000..86fbd0f
--- /dev/null
@@ -0,0 +1,2657 @@
+
+/*  A Bison parser, made from ../expread.y  */
+
+#define        INT     258
+#define        CHAR    259
+#define        UINT    260
+#define        FLOAT   261
+#define        STRING  262
+#define        NAME    263
+#define        BLOCKNAME       264
+#define        TYPENAME        265
+#define        NAME_OR_INT     266
+#define        NAME_OR_UINT    267
+#define        STRUCT  268
+#define        UNION   269
+#define        ENUM    270
+#define        SIZEOF  271
+#define        UNSIGNED        272
+#define        COLONCOLON      273
+#define        ERROR   274
+#define        SIGNED  275
+#define        LONG    276
+#define        SHORT   277
+#define        INT_KEYWORD     278
+#define        LAST    279
+#define        REGNAME 280
+#define        VARIABLE        281
+#define        ASSIGN_MODIFY   282
+#define        THIS    283
+#define        ABOVE_COMMA     284
+#define        OR      285
+#define        AND     286
+#define        EQUAL   287
+#define        NOTEQUAL        288
+#define        LEQ     289
+#define        GEQ     290
+#define        LSH     291
+#define        RSH     292
+#define        UNARY   293
+#define        INCREMENT       294
+#define        DECREMENT       295
+#define        ARROW   296
+
+#line 29 "../expread.y"
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+#include "expression.h"
+#include "value.h"
+#include "command.h"
+
+static struct expression *expout;
+static int expout_size;
+static int expout_ptr;
+
+static int yylex ();
+static void yyerror ();
+static void write_exp_elt ();
+static void write_exp_elt_opcode ();
+static void write_exp_elt_sym ();
+static void write_exp_elt_longcst ();
+static void write_exp_elt_dblcst ();
+static void write_exp_elt_type ();
+static void write_exp_elt_intern ();
+static void write_exp_string ();
+static void start_arglist ();
+static int end_arglist ();
+static void free_funcalls ();
+static char *copy_name ();
+static int parse_number ();
+
+/* If this is nonzero, this block is used as the lexical context
+   for symbol names.  */
+
+static struct block *expression_context_block;
+
+/* The innermost context required by the stack and register variables
+   we've encountered so far. */
+struct block *innermost_block;
+
+/* The block in which the most recently discovered symbol was found. */
+struct block *block_found;
+
+/* Number of arguments seen so far in innermost function call.  */
+static int arglist_len;
+
+/* Data structure for saving values of arglist_len
+   for function calls whose arguments contain other function calls.  */
+
+struct funcall
+  {
+    struct funcall *next;
+    int arglist_len;
+  };
+
+struct funcall *funcall_chain;
+
+/* This kind of datum is used to represent the name
+   of a symbol token.  */
+
+struct stoken
+  {
+    char *ptr;
+    int length;
+  };
+
+struct ttype
+  {
+    struct stoken stoken;
+    struct type *type;
+  };
+
+struct symtoken
+  {
+    struct stoken stoken;
+    struct symbol *sym;
+    int is_a_field_of_this;
+  };
+
+/* For parsing of complicated types.
+   An array should be preceded in the list by the size of the array.  */
+enum type_pieces
+  {tp_end = -1, tp_pointer, tp_reference, tp_array, tp_function};
+static enum type_pieces *type_stack;
+static int type_stack_depth, type_stack_size;
+
+static void push_type ();
+static enum type_pieces pop_type ();
+
+/* Allow debugging of parsing.  */
+#define YYDEBUG 1
+
+#line 125 "../expread.y"
+typedef union
+  {
+    LONGEST lval;
+    unsigned LONGEST ulval;
+    double dval;
+    struct symbol *sym;
+    struct type *tval;
+    struct stoken sval;
+    struct ttype tsym;
+    struct symtoken ssym;
+    int voidval;
+    struct block *bval;
+    enum exp_opcode opcode;
+    struct internalvar *ivar;
+
+    struct type **tvec;
+    int *ivec;
+  } YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+  struct yyltype
+    {
+      int timestamp;
+      int first_line;
+      int first_column;
+      int last_line;
+      int last_column;
+      char *text;
+   }
+  yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#include <stdio.h>
+
+#ifndef __STDC__
+#define const
+#endif
+
+
+
+#define        YYFINAL         189
+#define        YYFLAG          -32768
+#define        YYNTBASE        66
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 84)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    59,     2,     2,     2,    51,    37,     2,    58,
+    62,    49,    47,    29,    48,    56,    50,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    65,     2,    40,
+    31,    41,    32,    46,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+    57,     2,    61,    36,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    63,    35,    64,    60,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+    26,    27,    28,    30,    33,    34,    38,    39,    42,    43,
+    44,    45,    52,    53,    54,    55
+};
+
+static const short yyrline[] = {     0,
+   218,   222,   223,   228,   231,   234,   238,   242,   246,   250,
+   254,   258,   262,   266,   272,   276,   282,   286,   290,   294,
+   300,   303,   307,   311,   317,   323,   329,   333,   337,   341,
+   345,   349,   353,   357,   361,   365,   369,   373,   377,   381,
+   385,   389,   393,   397,   401,   405,   409,   413,   419,   429,
+   442,   454,   467,   474,   481,   484,   490,   496,   502,   509,
+   516,   523,   540,   550,   562,   575,   621,   695,   696,   731,
+   733,   735,   738,   740,   745,   751,   753,   757,   759,   763,
+   767,   768,   770,   772,   775,   782,   784,   786,   788,   790,
+   792,   794,   796,   798,   801,   804,   807,   809,   811,   813,
+   817,   818,   824,   830,   839,   844,   851,   852,   853,   854,
+   855,   858,   859,   860,   861
+};
+
+static const char * const yytname[] = {     0,
+"error","$illegal.","INT","CHAR","UINT","FLOAT","STRING","NAME","BLOCKNAME","TYPENAME",
+"NAME_OR_INT","NAME_OR_UINT","STRUCT","UNION","ENUM","SIZEOF","UNSIGNED","COLONCOLON","ERROR","SIGNED",
+"LONG","SHORT","INT_KEYWORD","LAST","REGNAME","VARIABLE","ASSIGN_MODIFY","THIS","','","ABOVE_COMMA",
+"'='","'?'","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'",
+"'>'","LEQ","GEQ","LSH","RSH","'@'","'+'","'-'","'*'","'/'",
+"'%'","UNARY","INCREMENT","DECREMENT","ARROW","'.'","'['","'('","'!'","'~'",
+"']'","')'","'{'","'}'","':'","start"
+};
+
+static const short yyr1[] = {     0,
+    66,    67,    67,    68,    68,    68,    68,    68,    68,    68,
+    68,    68,    68,    68,    68,    68,    68,    68,    69,    68,
+    70,    70,    70,    68,    68,    68,    68,    68,    68,    68,
+    68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+    68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+    68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+    68,    71,    71,    72,    72,    72,    72,    73,    73,    74,
+    74,    74,    75,    75,    75,    75,    75,    76,    76,    77,
+    78,    78,    78,    78,    78,    79,    79,    79,    79,    79,
+    79,    79,    79,    79,    79,    79,    79,    79,    79,    79,
+    80,    80,    80,    80,    81,    81,    82,    82,    82,    82,
+    82,    83,    83,    83,    83
+};
+
+static const short yyr2[] = {     0,
+     1,     1,     3,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     3,     4,     3,     4,     4,     0,     5,
+     0,     1,     3,     4,     4,     3,     3,     3,     3,     3,
+     3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+     3,     3,     3,     3,     3,     5,     3,     3,     1,     1,
+     1,     1,     1,     1,     1,     1,     1,     1,     4,     1,
+     1,     1,     3,     3,     3,     2,     1,     1,     2,     1,
+     2,     1,     3,     2,     1,     2,     1,     2,     3,     2,
+     1,     3,     6,     8,     9,     1,     1,     1,     1,     2,
+     3,     2,     3,     2,     2,     2,     2,     1,     2,     1,
+     1,     1,     1,     1,     1,     3,     1,     1,     1,     1,
+     1,     1,     1,     1,     1
+};
+
+static const short yydefact[] = {     0,
+    49,    53,    51,    54,    60,   112,   113,    86,    50,    52,
+     0,     0,     0,     0,    98,     0,   100,    88,    89,    87,
+    56,    57,    58,    61,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     1,     2,     0,    55,     0,    67,   107,
+   108,   109,   110,   111,    94,    95,    96,     0,    13,   101,
+   103,   104,   102,    97,    66,   103,   104,    99,    90,    92,
+     5,     6,     4,     9,    10,     0,    81,     0,    68,     7,
+     8,     0,    68,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,    11,    12,     0,     0,
+     0,    19,     0,     0,     0,    91,    93,    26,     0,     0,
+     0,    70,     0,     0,    69,    72,    75,    77,     0,     0,
+     3,    48,    47,     0,    45,    44,    43,    42,    41,    35,
+    36,    39,    40,    37,    38,    33,    34,    27,    31,    32,
+    28,    29,    30,     0,    14,     0,    16,     0,    21,    64,
+    65,    59,     0,    25,    82,    71,     0,    78,    80,     0,
+     0,    74,    76,    24,     0,    15,    17,    18,    22,     0,
+     0,    79,    73,    46,     0,    20,     0,    23,    83,     0,
+    84,   105,     0,     0,    85,   106,     0,     0,     0
+};
+
+static const short yydefgoto[] = {   187,
+    66,    35,   149,   170,    36,    37,    67,   115,   116,   117,
+   118,    68,    38,    54,   183,   151,    39
+};
+
+static const short yypact[] = {   159,
+-32768,-32768,-32768,-32768,-32768,-32768,   -13,-32768,-32768,-32768,
+    21,    21,    21,   220,   121,    21,   124,   -15,     3,-32768,
+-32768,-32768,-32768,-32768,   159,   159,   159,   159,   159,   159,
+   159,   159,   272,    80,   306,    32,-32768,    99,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,   159,   508,-32768,
+   100,   101,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+   508,   508,   508,   508,   508,    -4,-32768,   -52,    79,   508,
+   508,   -55,    92,   159,   159,   159,   159,   159,   159,   159,
+   159,   159,   159,   159,   159,   159,   159,   159,   159,   159,
+   159,   159,   159,   159,   159,   159,-32768,-32768,    90,   104,
+   159,-32768,    21,    21,   -35,-32768,-32768,-32768,   272,   159,
+   110,   157,    25,   209,-32768,    30,-32768,-32768,   159,    84,
+   306,   306,   306,   271,   358,   382,   405,   427,   448,   467,
+   467,   144,   144,   144,   144,   480,   480,   492,   502,   502,
+   508,   508,   508,   159,-32768,   159,-32768,    66,   159,   111,
+-32768,    31,   122,   508,-32768,-32768,    94,-32768,-32768,    95,
+    98,-32768,-32768,   508,   159,   508,   508,-32768,   306,    63,
+   107,-32768,-32768,   333,   159,-32768,   116,   306,   128,   239,
+-32768,   145,    64,   272,-32768,   145,   204,   205,-32768
+};
+
+static const short yypgoto[] = {-32768,
+     2,   -14,-32768,-32768,-32768,-32768,-32768,    -8,-32768,    93,
+   105,   -32,   -26,   193,-32768,     8,-32768
+};
+
+
+#define        YYLAST          566
+
+
+static const short yytable[] = {    49,
+    72,    34,   109,    69,   -62,   109,    73,    59,   119,   110,
+    61,    62,    63,    64,    65,   105,    70,    71,    45,    46,
+    47,    69,   109,    55,    74,    60,   152,   157,    40,    41,
+    42,    43,    44,     1,     2,     3,     4,     5,     6,     7,
+     8,     9,    10,    11,    12,    13,    14,    15,    16,   103,
+    17,    18,    19,    20,    21,    22,    23,   108,    24,   121,
+   122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
+   132,   133,   134,   135,   136,   137,   138,   139,   140,   141,
+   142,   143,   153,    28,    29,   158,   113,   161,    30,    31,
+    32,   175,   184,    33,    74,   154,   111,    40,    41,    42,
+    43,    44,   148,   156,   164,   160,   145,   147,    74,   120,
+   150,    40,    41,    42,    43,    44,   104,    40,    41,    42,
+    43,    44,   106,   107,   176,   185,   168,   112,   -63,   166,
+    50,   167,   155,    50,   169,   113,   114,   154,   144,   171,
+   112,    51,    52,    53,    56,    57,    53,   182,   113,   114,
+   174,   186,   146,    73,   172,   177,   173,    73,   155,   159,
+   178,     1,     2,     3,     4,     5,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,   179,    17,    18,
+    19,    20,    21,    22,    23,   180,    24,    89,    90,    91,
+    92,    93,    94,    95,    96,    25,    97,    98,    99,   100,
+   101,   102,   109,   188,   189,   112,    26,    27,   162,    58,
+     0,    28,    29,   113,   114,     0,    30,    31,    32,     0,
+   163,    33,     1,     2,     3,     4,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,     0,    17,
+    18,    19,    20,    21,    22,    23,     0,    24,     8,     0,
+     0,    11,    12,    13,     0,    15,    25,   112,    17,    18,
+    19,    20,     0,     0,     0,   113,   114,    26,    27,     0,
+   159,     0,    28,    29,     0,     0,     0,    48,    31,    32,
+     0,     8,    33,     0,    11,    12,    13,     0,    15,     0,
+     0,    17,    18,    19,    20,     0,     0,    75,     0,     0,
+   181,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+    85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+    95,    96,     0,    97,    98,    99,   100,   101,   102,     0,
+     0,     0,    75,     0,     0,   165,    76,    77,    78,    79,
+    80,    81,    82,    83,    84,    85,    86,    87,    88,    89,
+    90,    91,    92,    93,    94,    95,    96,     0,    97,    98,
+    99,   100,   101,   102,    77,    78,    79,    80,    81,    82,
+    83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
+    93,    94,    95,    96,     0,    97,    98,    99,   100,   101,
+   102,    79,    80,    81,    82,    83,    84,    85,    86,    87,
+    88,    89,    90,    91,    92,    93,    94,    95,    96,     0,
+    97,    98,    99,   100,   101,   102,    80,    81,    82,    83,
+    84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
+    94,    95,    96,     0,    97,    98,    99,   100,   101,   102,
+    81,    82,    83,    84,    85,    86,    87,    88,    89,    90,
+    91,    92,    93,    94,    95,    96,     0,    97,    98,    99,
+   100,   101,   102,    82,    83,    84,    85,    86,    87,    88,
+    89,    90,    91,    92,    93,    94,    95,    96,     0,    97,
+    98,    99,   100,   101,   102,    83,    84,    85,    86,    87,
+    88,    89,    90,    91,    92,    93,    94,    95,    96,     0,
+    97,    98,    99,   100,   101,   102,    85,    86,    87,    88,
+    89,    90,    91,    92,    93,    94,    95,    96,     0,    97,
+    98,    99,   100,   101,   102,    91,    92,    93,    94,    95,
+    96,     0,    97,    98,    99,   100,   101,   102,    92,    93,
+    94,    95,    96,     0,    97,    98,    99,   100,   101,   102,
+    94,    95,    96,     0,    97,    98,    99,   100,   101,   102,
+    97,    98,    99,   100,   101,   102
+};
+
+static const short yycheck[] = {    14,
+    33,     0,    58,    30,    18,    58,    33,    23,    64,    62,
+    25,    26,    27,    28,    29,    48,    31,    32,    11,    12,
+    13,    48,    58,    16,    29,    23,    62,     3,     8,     9,
+    10,    11,    12,     3,     4,     5,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,    17,    18,    18,
+    20,    21,    22,    23,    24,    25,    26,    62,    28,    74,
+    75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+    85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+    95,    96,   109,    53,    54,    61,    57,    58,    58,    59,
+    60,    29,    29,    63,    29,   110,    18,     8,     9,    10,
+    11,    12,   101,   112,   119,   114,    99,   100,    29,    18,
+   103,     8,     9,    10,    11,    12,    18,     8,     9,    10,
+    11,    12,    23,    23,    62,    62,    61,    49,    18,   144,
+    10,   146,    49,    10,   149,    57,    58,   152,    49,    18,
+    49,    21,    22,    23,    21,    22,    23,   180,    57,    58,
+   165,   184,    49,   180,    61,    49,    62,   184,    49,    62,
+   175,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+    12,    13,    14,    15,    16,    17,    18,    62,    20,    21,
+    22,    23,    24,    25,    26,    58,    28,    44,    45,    46,
+    47,    48,    49,    50,    51,    37,    53,    54,    55,    56,
+    57,    58,    58,     0,     0,    49,    48,    49,   116,    17,
+    -1,    53,    54,    57,    58,    -1,    58,    59,    60,    -1,
+   116,    63,     3,     4,     5,     6,     7,     8,     9,    10,
+    11,    12,    13,    14,    15,    16,    17,    18,    -1,    20,
+    21,    22,    23,    24,    25,    26,    -1,    28,    10,    -1,
+    -1,    13,    14,    15,    -1,    17,    37,    49,    20,    21,
+    22,    23,    -1,    -1,    -1,    57,    58,    48,    49,    -1,
+    62,    -1,    53,    54,    -1,    -1,    -1,    58,    59,    60,
+    -1,    10,    63,    -1,    13,    14,    15,    -1,    17,    -1,
+    -1,    20,    21,    22,    23,    -1,    -1,    27,    -1,    -1,
+    62,    31,    32,    33,    34,    35,    36,    37,    38,    39,
+    40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
+    50,    51,    -1,    53,    54,    55,    56,    57,    58,    -1,
+    -1,    -1,    27,    -1,    -1,    65,    31,    32,    33,    34,
+    35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+    45,    46,    47,    48,    49,    50,    51,    -1,    53,    54,
+    55,    56,    57,    58,    32,    33,    34,    35,    36,    37,
+    38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
+    48,    49,    50,    51,    -1,    53,    54,    55,    56,    57,
+    58,    34,    35,    36,    37,    38,    39,    40,    41,    42,
+    43,    44,    45,    46,    47,    48,    49,    50,    51,    -1,
+    53,    54,    55,    56,    57,    58,    35,    36,    37,    38,
+    39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
+    49,    50,    51,    -1,    53,    54,    55,    56,    57,    58,
+    36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+    46,    47,    48,    49,    50,    51,    -1,    53,    54,    55,
+    56,    57,    58,    37,    38,    39,    40,    41,    42,    43,
+    44,    45,    46,    47,    48,    49,    50,    51,    -1,    53,
+    54,    55,    56,    57,    58,    38,    39,    40,    41,    42,
+    43,    44,    45,    46,    47,    48,    49,    50,    51,    -1,
+    53,    54,    55,    56,    57,    58,    40,    41,    42,    43,
+    44,    45,    46,    47,    48,    49,    50,    51,    -1,    53,
+    54,    55,    56,    57,    58,    46,    47,    48,    49,    50,
+    51,    -1,    53,    54,    55,    56,    57,    58,    47,    48,
+    49,    50,    51,    -1,    53,    54,    55,    56,    57,    58,
+    49,    50,    51,    -1,    53,    54,    55,    56,    57,    58,
+    53,    54,    55,    56,    57,    58
+};
+#define YYPURE 1
+
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "bison.simple"
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984 Bob Corbett and Richard Stallman
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
+#include <alloca.h>
+#endif
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                -2
+#define YYEOF          0
+#define YYFAIL         goto yyerrlab;
+#define YYACCEPT       return(0)
+#define YYABORT        return(1)
+#define YYERROR                goto yyerrlab
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+#ifndef YYIMPURE
+#define YYLEX          yylex()
+#endif
+
+#ifndef YYPURE
+#define YYLEX          yylex(&yylval, &yylloc)
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYIMPURE
+
+int    yychar;                 /*  the lookahead symbol                */
+YYSTYPE        yylval;                 /*  the semantic value of the           */
+                               /*  lookahead symbol                    */
+
+YYLTYPE yylloc;                        /*  location data for the lookahead     */
+                               /*  symbol                              */
+
+int yynerrs;                   /*  number of parse errors so far       */
+#endif  /* YYIMPURE */
+
+#if YYDEBUG != 0
+int yydebug;                   /*  nonzero means print parse trace     */
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYMAXDEPTH indicates the initial size of the parser's stacks       */
+
+#ifndef        YYMAXDEPTH
+#define YYMAXDEPTH 200
+#endif
+
+/*  YYMAXLIMIT is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#ifndef YYMAXLIMIT
+#define YYMAXLIMIT 10000
+#endif
+
+
+#line 90 "bison.simple"
+int
+yyparse()
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  YYLTYPE *yylsp;
+  int yyerrstatus;     /*  number of tokens to shift before error messages enabled */
+  int yychar1;         /*  lookahead token as an internal (translated) token number */
+
+  short        yyssa[YYMAXDEPTH];      /*  the state stack                     */
+  YYSTYPE yyvsa[YYMAXDEPTH];   /*  the semantic value stack            */
+  YYLTYPE yylsa[YYMAXDEPTH];   /*  the location stack                  */
+
+  short *yyss = yyssa;         /*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;       /*  to allow yyoverflow to reallocate them elsewhere */
+  YYLTYPE *yyls = yylsa;
+
+  int yymaxdepth = YYMAXDEPTH;
+
+#ifndef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  YYLTYPE yylloc;
+  int yynerrs;
+#endif
+
+  YYSTYPE yyval;               /*  the variable used to return         */
+                               /*  semantic values from the action     */
+                               /*  routines                            */
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+  yylsp = yyls;
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yymaxdepth - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      YYLTYPE *yyls1 = yyls;
+      short *yyss1 = yyss;
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+        the data in use in that stack, in bytes.  */
+      yyoverflow("parser stack overflow",
+                &yyss1, size * sizeof (*yyssp),
+                &yyvs1, size * sizeof (*yyvsp),
+                &yyls1, size * sizeof (*yylsp),
+                &yymaxdepth);
+
+      yyss = yyss1; yyvs = yyvs1; yyls = yyls1;
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yymaxdepth >= YYMAXLIMIT)
+       yyerror("parser stack overflow");
+      yymaxdepth *= 2;
+      if (yymaxdepth > YYMAXLIMIT)
+       yymaxdepth = YYMAXLIMIT;
+      yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp));
+      bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+      yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp));
+      bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp));
+      bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
+#endif
+
+      if (yyssp >= yyss + yymaxdepth - 1)
+       YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+yyresume:
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)             /* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;          /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      if (yylen == 1)
+       fprintf (stderr, "Reducing 1 value via line %d, ",
+                yyrline[yyn]);
+      else
+       fprintf (stderr, "Reducing %d values via line %d, ",
+                yylen, yyrline[yyn]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 3:
+#line 224 "../expread.y"
+{ write_exp_elt_opcode (BINOP_COMMA); ;
+    break;}
+case 4:
+#line 229 "../expread.y"
+{ write_exp_elt_opcode (UNOP_IND); ;
+    break;}
+case 5:
+#line 232 "../expread.y"
+{ write_exp_elt_opcode (UNOP_ADDR); ;
+    break;}
+case 6:
+#line 235 "../expread.y"
+{ write_exp_elt_opcode (UNOP_NEG); ;
+    break;}
+case 7:
+#line 239 "../expread.y"
+{ write_exp_elt_opcode (UNOP_ZEROP); ;
+    break;}
+case 8:
+#line 243 "../expread.y"
+{ write_exp_elt_opcode (UNOP_LOGNOT); ;
+    break;}
+case 9:
+#line 247 "../expread.y"
+{ write_exp_elt_opcode (UNOP_PREINCREMENT); ;
+    break;}
+case 10:
+#line 251 "../expread.y"
+{ write_exp_elt_opcode (UNOP_PREDECREMENT); ;
+    break;}
+case 11:
+#line 255 "../expread.y"
+{ write_exp_elt_opcode (UNOP_POSTINCREMENT); ;
+    break;}
+case 12:
+#line 259 "../expread.y"
+{ write_exp_elt_opcode (UNOP_POSTDECREMENT); ;
+    break;}
+case 13:
+#line 263 "../expread.y"
+{ write_exp_elt_opcode (UNOP_SIZEOF); ;
+    break;}
+case 14:
+#line 267 "../expread.y"
+{ write_exp_elt_opcode (STRUCTOP_PTR);
+                         write_exp_string (yyvsp[0].sval);
+                         write_exp_elt_opcode (STRUCTOP_PTR); ;
+    break;}
+case 15:
+#line 273 "../expread.y"
+{ write_exp_elt_opcode (STRUCTOP_MPTR); ;
+    break;}
+case 16:
+#line 277 "../expread.y"
+{ write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         write_exp_string (yyvsp[0].sval);
+                         write_exp_elt_opcode (STRUCTOP_STRUCT); ;
+    break;}
+case 17:
+#line 283 "../expread.y"
+{ write_exp_elt_opcode (STRUCTOP_MEMBER); ;
+    break;}
+case 18:
+#line 287 "../expread.y"
+{ write_exp_elt_opcode (BINOP_SUBSCRIPT); ;
+    break;}
+case 19:
+#line 293 "../expread.y"
+{ start_arglist (); ;
+    break;}
+case 20:
+#line 295 "../expread.y"
+{ write_exp_elt_opcode (OP_FUNCALL);
+                         write_exp_elt_longcst ((LONGEST) end_arglist ());
+                         write_exp_elt_opcode (OP_FUNCALL); ;
+    break;}
+case 22:
+#line 304 "../expread.y"
+{ arglist_len = 1; ;
+    break;}
+case 23:
+#line 308 "../expread.y"
+{ arglist_len++; ;
+    break;}
+case 24:
+#line 312 "../expread.y"
+{ write_exp_elt_opcode (UNOP_MEMVAL);
+                         write_exp_elt_type (yyvsp[-2].tval);
+                         write_exp_elt_opcode (UNOP_MEMVAL); ;
+    break;}
+case 25:
+#line 318 "../expread.y"
+{ write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type (yyvsp[-2].tval);
+                         write_exp_elt_opcode (UNOP_CAST); ;
+    break;}
+case 26:
+#line 324 "../expread.y"
+{ ;
+    break;}
+case 27:
+#line 330 "../expread.y"
+{ write_exp_elt_opcode (BINOP_REPEAT); ;
+    break;}
+case 28:
+#line 334 "../expread.y"
+{ write_exp_elt_opcode (BINOP_MUL); ;
+    break;}
+case 29:
+#line 338 "../expread.y"
+{ write_exp_elt_opcode (BINOP_DIV); ;
+    break;}
+case 30:
+#line 342 "../expread.y"
+{ write_exp_elt_opcode (BINOP_REM); ;
+    break;}
+case 31:
+#line 346 "../expread.y"
+{ write_exp_elt_opcode (BINOP_ADD); ;
+    break;}
+case 32:
+#line 350 "../expread.y"
+{ write_exp_elt_opcode (BINOP_SUB); ;
+    break;}
+case 33:
+#line 354 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LSH); ;
+    break;}
+case 34:
+#line 358 "../expread.y"
+{ write_exp_elt_opcode (BINOP_RSH); ;
+    break;}
+case 35:
+#line 362 "../expread.y"
+{ write_exp_elt_opcode (BINOP_EQUAL); ;
+    break;}
+case 36:
+#line 366 "../expread.y"
+{ write_exp_elt_opcode (BINOP_NOTEQUAL); ;
+    break;}
+case 37:
+#line 370 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LEQ); ;
+    break;}
+case 38:
+#line 374 "../expread.y"
+{ write_exp_elt_opcode (BINOP_GEQ); ;
+    break;}
+case 39:
+#line 378 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LESS); ;
+    break;}
+case 40:
+#line 382 "../expread.y"
+{ write_exp_elt_opcode (BINOP_GTR); ;
+    break;}
+case 41:
+#line 386 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LOGAND); ;
+    break;}
+case 42:
+#line 390 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LOGXOR); ;
+    break;}
+case 43:
+#line 394 "../expread.y"
+{ write_exp_elt_opcode (BINOP_LOGIOR); ;
+    break;}
+case 44:
+#line 398 "../expread.y"
+{ write_exp_elt_opcode (BINOP_AND); ;
+    break;}
+case 45:
+#line 402 "../expread.y"
+{ write_exp_elt_opcode (BINOP_OR); ;
+    break;}
+case 46:
+#line 406 "../expread.y"
+{ write_exp_elt_opcode (TERNOP_COND); ;
+    break;}
+case 47:
+#line 410 "../expread.y"
+{ write_exp_elt_opcode (BINOP_ASSIGN); ;
+    break;}
+case 48:
+#line 414 "../expread.y"
+{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+                         write_exp_elt_opcode (yyvsp[-1].opcode);
+                         write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); ;
+    break;}
+case 49:
+#line 420 "../expread.y"
+{ write_exp_elt_opcode (OP_LONG);
+                         if (yyvsp[0].lval == (int) yyvsp[0].lval || yyvsp[0].lval == (unsigned int) yyvsp[0].lval)
+                           write_exp_elt_type (builtin_type_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_LONGEST);
+                         write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+                         write_exp_elt_opcode (OP_LONG); ;
+    break;}
+case 50:
+#line 430 "../expread.y"
+{ YYSTYPE val;
+                         parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val);
+                         write_exp_elt_opcode (OP_LONG);
+                         if (val.lval == (int) val.lval ||
+                             val.lval == (unsigned int) val.lval)
+                           write_exp_elt_type (builtin_type_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_LONGEST);
+                         write_exp_elt_longcst (val.lval);
+                         write_exp_elt_opcode (OP_LONG); ;
+    break;}
+case 51:
+#line 443 "../expread.y"
+{
+                         write_exp_elt_opcode (OP_LONG);
+                         if (yyvsp[0].ulval == (unsigned int) yyvsp[0].ulval)
+                           write_exp_elt_type (builtin_type_unsigned_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
+                         write_exp_elt_longcst ((LONGEST) yyvsp[0].ulval);
+                         write_exp_elt_opcode (OP_LONG);
+                       ;
+    break;}
+case 52:
+#line 455 "../expread.y"
+{ YYSTYPE val;
+                         parse_number (yyvsp[0].ssym.stoken.ptr, yyvsp[0].ssym.stoken.length, 0, &val);
+                         write_exp_elt_opcode (OP_LONG);
+                         if (val.ulval == (unsigned int) val.ulval)
+                           write_exp_elt_type (builtin_type_unsigned_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
+                         write_exp_elt_longcst ((LONGEST)val.ulval);
+                         write_exp_elt_opcode (OP_LONG);
+                       ;
+    break;}
+case 53:
+#line 468 "../expread.y"
+{ write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_char);
+                         write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+                         write_exp_elt_opcode (OP_LONG); ;
+    break;}
+case 54:
+#line 475 "../expread.y"
+{ write_exp_elt_opcode (OP_DOUBLE);
+                         write_exp_elt_type (builtin_type_double);
+                         write_exp_elt_dblcst (yyvsp[0].dval);
+                         write_exp_elt_opcode (OP_DOUBLE); ;
+    break;}
+case 56:
+#line 485 "../expread.y"
+{ write_exp_elt_opcode (OP_LAST);
+                         write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+                         write_exp_elt_opcode (OP_LAST); ;
+    break;}
+case 57:
+#line 491 "../expread.y"
+{ write_exp_elt_opcode (OP_REGISTER);
+                         write_exp_elt_longcst ((LONGEST) yyvsp[0].lval);
+                         write_exp_elt_opcode (OP_REGISTER); ;
+    break;}
+case 58:
+#line 497 "../expread.y"
+{ write_exp_elt_opcode (OP_INTERNALVAR);
+                         write_exp_elt_intern (yyvsp[0].ivar);
+                         write_exp_elt_opcode (OP_INTERNALVAR); ;
+    break;}
+case 59:
+#line 503 "../expread.y"
+{ write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH (yyvsp[-1].tval));
+                         write_exp_elt_opcode (OP_LONG); ;
+    break;}
+case 60:
+#line 510 "../expread.y"
+{ write_exp_elt_opcode (OP_STRING);
+                         write_exp_string (yyvsp[0].sval);
+                         write_exp_elt_opcode (OP_STRING); ;
+    break;}
+case 61:
+#line 517 "../expread.y"
+{ write_exp_elt_opcode (OP_THIS);
+                         write_exp_elt_opcode (OP_THIS); ;
+    break;}
+case 62:
+#line 524 "../expread.y"
+{
+                         if (yyvsp[0].ssym.sym != 0)
+                             yyval.bval = SYMBOL_BLOCK_VALUE (yyvsp[0].ssym.sym);
+                         else
+                           {
+                             struct symtab *tem =
+                                 lookup_symtab (copy_name (yyvsp[0].ssym.stoken));
+                             if (tem)
+                               yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), 1);
+                             else
+                               error ("No file or function \"%s\".",
+                                      copy_name (yyvsp[0].ssym.stoken));
+                           }
+                       ;
+    break;}
+case 63:
+#line 541 "../expread.y"
+{ struct symbol *tem
+                           = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
+                                            VAR_NAMESPACE, 0, NULL);
+                         if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+                           error ("No function \"%s\" in specified context.",
+                                  copy_name (yyvsp[0].sval));
+                         yyval.bval = SYMBOL_BLOCK_VALUE (tem); ;
+    break;}
+case 64:
+#line 551 "../expread.y"
+{ struct symbol *sym;
+                         sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval,
+                                              VAR_NAMESPACE, 0, NULL);
+                         if (sym == 0)
+                           error ("No symbol \"%s\" in specified context.",
+                                  copy_name (yyvsp[0].sval));
+                         write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_sym (sym);
+                         write_exp_elt_opcode (OP_VAR_VALUE); ;
+    break;}
+case 65:
+#line 563 "../expread.y"
+{
+                         struct type *type = yyvsp[-2].tval;
+                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+                             && TYPE_CODE (type) != TYPE_CODE_UNION)
+                           error ("`%s' is not defined as an aggregate type.",
+                                  TYPE_NAME (type));
+
+                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_type (type);
+                         write_exp_string (yyvsp[0].sval);
+                         write_exp_elt_opcode (OP_SCOPE);
+                       ;
+    break;}
+case 66:
+#line 576 "../expread.y"
+{
+                         char *name = copy_name (yyvsp[0].sval);
+                         struct symbol *sym;
+                         int i;
+
+                         sym =
+                           lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+                         if (sym)
+                           {
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             break;
+                           }
+                         for (i = 0; i < misc_function_count; i++)
+                           if (!strcmp (misc_function_vector[i].name, name))
+                             break;
+
+                         if (i < misc_function_count)
+                           {
+                             enum misc_function_type mft =
+                                 misc_function_vector[i].type;
+                             
+                             write_exp_elt_opcode (OP_LONG);
+                             write_exp_elt_type (builtin_type_int);
+                             write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
+                             write_exp_elt_opcode (OP_LONG);
+                             write_exp_elt_opcode (UNOP_MEMVAL);
+                             if (mft == mf_data || mft == mf_bss)
+                               write_exp_elt_type (builtin_type_int);
+                             else if (mft == mf_text)
+                               write_exp_elt_type (lookup_function_type (builtin_type_int));
+                             else
+                               write_exp_elt_type (builtin_type_char);
+                             write_exp_elt_opcode (UNOP_MEMVAL);
+                           }
+                         else
+                           if (symtab_list == 0
+                               && partial_symtab_list == 0)
+                             error ("No symbol table is loaded.  Use the \"file\" command.");
+                           else
+                             error ("No symbol \"%s\" in current context.", name);
+                       ;
+    break;}
+case 67:
+#line 622 "../expread.y"
+{ struct symbol *sym = yyvsp[0].ssym.sym;
+
+                         if (sym)
+                           {
+                             switch (sym->class)
+                               {
+                               case LOC_REGISTER:
+                               case LOC_ARG:
+                               case LOC_LOCAL:
+                               case LOC_LOCAL_ARG:
+                                 if (innermost_block == 0 ||
+                                     contained_in (block_found, 
+                                                   innermost_block))
+                                   innermost_block = block_found;
+                               }
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                           }
+                         else if (yyvsp[0].ssym.is_a_field_of_this)
+                           {
+                             /* C++: it hangs off of `this'.  Must
+                                not inadvertently convert from a method call
+                                to data ref.  */
+                             if (innermost_block == 0 || 
+                                 contained_in (block_found, innermost_block))
+                               innermost_block = block_found;
+                             write_exp_elt_opcode (OP_THIS);
+                             write_exp_elt_opcode (OP_THIS);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                             write_exp_string (yyvsp[0].ssym.stoken);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                           }
+                         else
+                           {
+                             register int i;
+                             register char *arg = copy_name (yyvsp[0].ssym.stoken);
+
+                               /* FIXME, this search is linear!  At least
+                                  optimize the strcmp with a 1-char cmp... */
+                             for (i = 0; i < misc_function_count; i++)
+                               if (!strcmp (misc_function_vector[i].name, arg))
+                                 break;
+
+                             if (i < misc_function_count)
+                               {
+                                 enum misc_function_type mft =
+                                     misc_function_vector[i].type;
+                                 
+                                 write_exp_elt_opcode (OP_LONG);
+                                 write_exp_elt_type (builtin_type_int);
+                                 write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
+                                 write_exp_elt_opcode (OP_LONG);
+                                 write_exp_elt_opcode (UNOP_MEMVAL);
+                                 if (mft == mf_data || mft == mf_bss)
+                                   write_exp_elt_type (builtin_type_int);
+                                 else if (mft == mf_text)
+                                   write_exp_elt_type (lookup_function_type (builtin_type_int));
+                                 else
+                                   write_exp_elt_type (builtin_type_char);
+                                 write_exp_elt_opcode (UNOP_MEMVAL);
+                               }
+                             else if (symtab_list == 0
+                                      && partial_symtab_list == 0)
+                               error ("No symbol table is loaded.  Use the \"file\" command.");
+                             else
+                               error ("No symbol \"%s\" in current context.",
+                                      copy_name (yyvsp[0].ssym.stoken));
+                           }
+                       ;
+    break;}
+case 69:
+#line 697 "../expread.y"
+{
+                 /* This is where the interesting stuff happens.  */
+                 int done = 0;
+                 int array_size;
+                 struct type *follow_type = yyvsp[-1].tval;
+                 
+                 while (!done)
+                   switch (pop_type ())
+                     {
+                     case tp_end:
+                       done = 1;
+                       break;
+                     case tp_pointer:
+                       follow_type = lookup_pointer_type (follow_type);
+                       break;
+                     case tp_reference:
+                       follow_type = lookup_reference_type (follow_type);
+                       break;
+                     case tp_array:
+                       array_size = (int) pop_type ();
+                       if (array_size != -1)
+                         follow_type = create_array_type (follow_type,
+                                                          array_size);
+                       else
+                         follow_type = lookup_pointer_type (follow_type);
+                       break;
+                     case tp_function:
+                       follow_type = lookup_function_type (follow_type);
+                       break;
+                     }
+                 yyval.tval = follow_type;
+               ;
+    break;}
+case 70:
+#line 732 "../expread.y"
+{ push_type (tp_pointer); yyval.voidval = 0; ;
+    break;}
+case 71:
+#line 734 "../expread.y"
+{ push_type (tp_pointer); yyval.voidval = yyvsp[0].voidval; ;
+    break;}
+case 73:
+#line 739 "../expread.y"
+{ yyval.voidval = yyvsp[-1].voidval; ;
+    break;}
+case 74:
+#line 741 "../expread.y"
+{
+                         push_type ((enum type_pieces) yyvsp[0].lval);
+                         push_type (tp_array);
+                       ;
+    break;}
+case 75:
+#line 746 "../expread.y"
+{
+                         push_type ((enum type_pieces) yyvsp[0].lval);
+                         push_type (tp_array);
+                         yyval.voidval = 0;
+                       ;
+    break;}
+case 76:
+#line 752 "../expread.y"
+{ push_type (tp_function); ;
+    break;}
+case 77:
+#line 754 "../expread.y"
+{ push_type (tp_function); ;
+    break;}
+case 78:
+#line 758 "../expread.y"
+{ yyval.lval = -1; ;
+    break;}
+case 79:
+#line 760 "../expread.y"
+{ yyval.lval = yyvsp[-1].lval; ;
+    break;}
+case 80:
+#line 764 "../expread.y"
+{ yyval.voidval = 0; ;
+    break;}
+case 82:
+#line 769 "../expread.y"
+{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ;
+    break;}
+case 83:
+#line 771 "../expread.y"
+{ yyval.tval = lookup_member_type (yyvsp[-5].tval, yyvsp[-3].tval); ;
+    break;}
+case 84:
+#line 773 "../expread.y"
+{ yyval.tval = lookup_member_type
+                           (lookup_function_type (yyvsp[-7].tval), yyvsp[-5].tval); ;
+    break;}
+case 85:
+#line 776 "../expread.y"
+{ yyval.tval = lookup_member_type
+                           (lookup_function_type (yyvsp[-8].tval), yyvsp[-6].tval);
+                         free (yyvsp[-1].tvec); ;
+    break;}
+case 86:
+#line 783 "../expread.y"
+{ yyval.tval = yyvsp[0].tsym.type; ;
+    break;}
+case 87:
+#line 785 "../expread.y"
+{ yyval.tval = builtin_type_int; ;
+    break;}
+case 88:
+#line 787 "../expread.y"
+{ yyval.tval = builtin_type_long; ;
+    break;}
+case 89:
+#line 789 "../expread.y"
+{ yyval.tval = builtin_type_short; ;
+    break;}
+case 90:
+#line 791 "../expread.y"
+{ yyval.tval = builtin_type_long; ;
+    break;}
+case 91:
+#line 793 "../expread.y"
+{ yyval.tval = builtin_type_unsigned_long; ;
+    break;}
+case 92:
+#line 795 "../expread.y"
+{ yyval.tval = builtin_type_short; ;
+    break;}
+case 93:
+#line 797 "../expread.y"
+{ yyval.tval = builtin_type_unsigned_short; ;
+    break;}
+case 94:
+#line 799 "../expread.y"
+{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval),
+                                             expression_context_block); ;
+    break;}
+case 95:
+#line 802 "../expread.y"
+{ yyval.tval = lookup_union (copy_name (yyvsp[0].sval),
+                                            expression_context_block); ;
+    break;}
+case 96:
+#line 805 "../expread.y"
+{ yyval.tval = lookup_enum (copy_name (yyvsp[0].sval),
+                                           expression_context_block); ;
+    break;}
+case 97:
+#line 808 "../expread.y"
+{ yyval.tval = lookup_unsigned_typename (TYPE_NAME(yyvsp[0].tsym.type)); ;
+    break;}
+case 98:
+#line 810 "../expread.y"
+{ yyval.tval = builtin_type_unsigned_int; ;
+    break;}
+case 99:
+#line 812 "../expread.y"
+{ yyval.tval = yyvsp[0].tsym.type; ;
+    break;}
+case 100:
+#line 814 "../expread.y"
+{ yyval.tval = builtin_type_int; ;
+    break;}
+case 102:
+#line 819 "../expread.y"
+{
+                 yyval.tsym.stoken.ptr = "int";
+                 yyval.tsym.stoken.length = 3;
+                 yyval.tsym.type = builtin_type_int;
+               ;
+    break;}
+case 103:
+#line 825 "../expread.y"
+{
+                 yyval.tsym.stoken.ptr = "long";
+                 yyval.tsym.stoken.length = 4;
+                 yyval.tsym.type = builtin_type_long;
+               ;
+    break;}
+case 104:
+#line 831 "../expread.y"
+{
+                 yyval.tsym.stoken.ptr = "short";
+                 yyval.tsym.stoken.length = 5;
+                 yyval.tsym.type = builtin_type_short;
+               ;
+    break;}
+case 105:
+#line 840 "../expread.y"
+{ yyval.tvec = (struct type **)xmalloc (sizeof (struct type *) * 2);
+                 yyval.tvec[0] = (struct type *)0;
+                 yyval.tvec[1] = yyvsp[0].tval;
+               ;
+    break;}
+case 106:
+#line 845 "../expread.y"
+{ int len = sizeof (struct type *) * ++(yyvsp[-2].ivec[0]);
+                 yyval.tvec = (struct type **)xrealloc (yyvsp[-2].tvec, len);
+                 yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval;
+               ;
+    break;}
+case 107:
+#line 851 "../expread.y"
+{ yyval.sval = yyvsp[0].ssym.stoken; ;
+    break;}
+case 108:
+#line 852 "../expread.y"
+{ yyval.sval = yyvsp[0].ssym.stoken; ;
+    break;}
+case 109:
+#line 853 "../expread.y"
+{ yyval.sval = yyvsp[0].tsym.stoken; ;
+    break;}
+case 110:
+#line 854 "../expread.y"
+{ yyval.sval = yyvsp[0].ssym.stoken; ;
+    break;}
+case 111:
+#line 855 "../expread.y"
+{ yyval.sval = yyvsp[0].ssym.stoken; ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 327 "bison.simple"
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+      yyerror("parse error");
+    }
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+       YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+       fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;             /* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+       fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+}
+#line 864 "../expread.y"
+
+\f
+/* Begin counting arguments for a function call,
+   saving the data about any containing call.  */
+
+static void
+start_arglist ()
+{
+  register struct funcall *new = (struct funcall *) xmalloc (sizeof (struct funcall));
+
+  new->next = funcall_chain;
+  new->arglist_len = arglist_len;
+  arglist_len = 0;
+  funcall_chain = new;
+}
+
+/* Return the number of arguments in a function call just terminated,
+   and restore the data for the containing function call.  */
+
+static int
+end_arglist ()
+{
+  register int val = arglist_len;
+  register struct funcall *call = funcall_chain;
+  funcall_chain = call->next;
+  arglist_len = call->arglist_len;
+  free (call);
+  return val;
+}
+
+/* Free everything in the funcall chain.
+   Used when there is an error inside parsing.  */
+
+static void
+free_funcalls ()
+{
+  register struct funcall *call, *next;
+
+  for (call = funcall_chain; call; call = next)
+    {
+      next = call->next;
+      free (call);
+    }
+}
+\f
+/* This page contains the functions for adding data to the  struct expression
+   being constructed.  */
+
+/* Add one element to the end of the expression.  */
+
+/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into
+   a register through here */
+
+static void
+write_exp_elt (expelt)
+     union exp_element expelt;
+{
+  if (expout_ptr >= expout_size)
+    {
+      expout_size *= 2;
+      expout = (struct expression *) xrealloc (expout,
+                                              sizeof (struct expression)
+                                              + expout_size * sizeof (union exp_element));
+    }
+  expout->elts[expout_ptr++] = expelt;
+}
+
+static void
+write_exp_elt_opcode (expelt)
+     enum exp_opcode expelt;
+{
+  union exp_element tmp;
+
+  tmp.opcode = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_sym (expelt)
+     struct symbol *expelt;
+{
+  union exp_element tmp;
+
+  tmp.symbol = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_longcst (expelt)
+     LONGEST expelt;
+{
+  union exp_element tmp;
+
+  tmp.longconst = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_dblcst (expelt)
+     double expelt;
+{
+  union exp_element tmp;
+
+  tmp.doubleconst = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_type (expelt)
+     struct type *expelt;
+{
+  union exp_element tmp;
+
+  tmp.type = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_intern (expelt)
+     struct internalvar *expelt;
+{
+  union exp_element tmp;
+
+  tmp.internalvar = expelt;
+
+  write_exp_elt (tmp);
+}
+
+/* Add a string constant to the end of the expression.
+   Follow it by its length in bytes, as a separate exp_element.  */
+
+static void
+write_exp_string (str)
+     struct stoken str;
+{
+  register int len = str.length;
+  register int lenelt
+    = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+
+  expout_ptr += lenelt;
+
+  if (expout_ptr >= expout_size)
+    {
+      expout_size = max (expout_size * 2, expout_ptr + 10);
+      expout = (struct expression *)
+       xrealloc (expout, (sizeof (struct expression)
+                          + (expout_size * sizeof (union exp_element))));
+    }
+  bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len);
+  ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+  write_exp_elt_longcst ((LONGEST) len);
+}
+\f
+/* During parsing of a C expression, the pointer to the next character
+   is in this variable.  */
+
+static char *lexptr;
+
+/* Tokens that refer to names do so with explicit pointer and length,
+   so they can share the storage that lexptr is parsing.
+
+   When it is necessary to pass a name to a function that expects
+   a null-terminated string, the substring is copied out
+   into a block of storage that namecopy points to.
+
+   namecopy is allocated once, guaranteed big enough, for each parsing.  */
+
+static char *namecopy;
+
+/* Current depth in parentheses within the expression.  */
+
+static int paren_depth;
+
+/* Nonzero means stop parsing on first comma (if not within parentheses).  */
+
+static int comma_terminates;
+
+/* Take care of parsing a number (anything that starts with a digit).
+   Set yylval and return the token type; update lexptr.
+   LEN is the number of characters in it.  */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+     register char *p;
+     register int len;
+     int parsed_float;
+     YYSTYPE *putithere;
+{
+  register LONGEST n = 0;
+  register int i;
+  register int c;
+  register int base = input_radix;
+  int unsigned_p = 0;
+
+  extern double atof ();
+
+  if (parsed_float)
+    {
+      /* It's a float since it contains a point or an exponent.  */
+      putithere->dval = atof (p);
+      return FLOAT;
+    }
+
+  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+  if (p[0] == '0')
+    switch (p[1])
+      {
+      case 'x':
+      case 'X':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 16;
+           len -= 2;
+         }
+       break;
+
+      case 't':
+      case 'T':
+      case 'd':
+      case 'D':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 10;
+           len -= 2;
+         }
+       break;
+
+      default:
+       base = 8;
+       break;
+      }
+
+  while (len-- > 0)
+    {
+      c = *p++;
+      if (c >= 'A' && c <= 'Z')
+       c += 'a' - 'A';
+      if (c != 'l' && c != 'u')
+       n *= base;
+      if (c >= '0' && c <= '9')
+       n += i = c - '0';
+      else
+       {
+         if (base > 10 && c >= 'a' && c <= 'f')
+           n += i = c - 'a' + 10;
+         else if (len == 0 && c == 'l')
+           ;
+         else if (len == 0 && c == 'u')
+           unsigned_p = 1;
+         else
+           return ERROR;       /* Char not a digit */
+       }
+      if (i >= base)
+       return ERROR;           /* Invalid digit in this base */
+    }
+
+  if (unsigned_p)
+    {
+      putithere->ulval = n;
+      return UINT;
+    }
+  else
+    {
+      putithere->lval = n;
+      return INT;
+    }
+}
+
+struct token
+{
+  char *operator;
+  int token;
+  enum exp_opcode opcode;
+};
+
+static struct token tokentab3[] =
+  {
+    {">>=", ASSIGN_MODIFY, BINOP_RSH},
+    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+  };
+
+static struct token tokentab2[] =
+  {
+    {"+=", ASSIGN_MODIFY, BINOP_ADD},
+    {"-=", ASSIGN_MODIFY, BINOP_SUB},
+    {"*=", ASSIGN_MODIFY, BINOP_MUL},
+    {"/=", ASSIGN_MODIFY, BINOP_DIV},
+    {"%=", ASSIGN_MODIFY, BINOP_REM},
+    {"|=", ASSIGN_MODIFY, BINOP_LOGIOR},
+    {"&=", ASSIGN_MODIFY, BINOP_LOGAND},
+    {"^=", ASSIGN_MODIFY, BINOP_LOGXOR},
+    {"++", INCREMENT, BINOP_END},
+    {"--", DECREMENT, BINOP_END},
+    {"->", ARROW, BINOP_END},
+    {"&&", AND, BINOP_END},
+    {"||", OR, BINOP_END},
+    {"::", COLONCOLON, BINOP_END},
+    {"<<", LSH, BINOP_END},
+    {">>", RSH, BINOP_END},
+    {"==", EQUAL, BINOP_END},
+    {"!=", NOTEQUAL, BINOP_END},
+    {"<=", LEQ, BINOP_END},
+    {">=", GEQ, BINOP_END}
+  };
+
+/* assign machine-independent names to certain registers 
+ * (unless overridden by the REGISTER_NAMES table)
+ */
+struct std_regs {
+       char *name;
+       int regnum;
+} std_regs[] = {
+#ifdef PC_REGNUM
+       { "pc", PC_REGNUM },
+#endif
+#ifdef FP_REGNUM
+       { "fp", FP_REGNUM },
+#endif
+#ifdef SP_REGNUM
+       { "sp", SP_REGNUM },
+#endif
+#ifdef PS_REGNUM
+       { "ps", PS_REGNUM },
+#endif
+};
+
+#define NUM_STD_REGS (sizeof std_regs / sizeof std_regs[0])
+
+/* Read one token, getting characters through lexptr.  */
+
+static int
+yylex ()
+{
+  register int c;
+  register int namelen;
+  register unsigned i;
+  register char *tokstart;
+
+ retry:
+
+  tokstart = lexptr;
+  /* See if it is a special token of length 3.  */
+  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+    if (!strncmp (tokstart, tokentab3[i].operator, 3))
+      {
+       lexptr += 3;
+       yylval.opcode = tokentab3[i].opcode;
+       return tokentab3[i].token;
+      }
+
+  /* See if it is a special token of length 2.  */
+  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+    if (!strncmp (tokstart, tokentab2[i].operator, 2))
+      {
+       lexptr += 2;
+       yylval.opcode = tokentab2[i].opcode;
+       return tokentab2[i].token;
+      }
+
+  switch (c = *tokstart)
+    {
+    case 0:
+      return 0;
+
+    case ' ':
+    case '\t':
+    case '\n':
+      lexptr++;
+      goto retry;
+
+    case '\'':
+      lexptr++;
+      c = *lexptr++;
+      if (c == '\\')
+       c = parse_escape (&lexptr);
+      yylval.lval = c;
+      c = *lexptr++;
+      if (c != '\'')
+       error ("Invalid character constant.");
+      return CHAR;
+
+    case '(':
+      paren_depth++;
+      lexptr++;
+      return c;
+
+    case ')':
+      if (paren_depth == 0)
+       return 0;
+      paren_depth--;
+      lexptr++;
+      return c;
+
+    case ',':
+      if (comma_terminates && paren_depth == 0)
+       return 0;
+      lexptr++;
+      return c;
+
+    case '.':
+      /* Might be a floating point number.  */
+      if (lexptr[1] < '0' || lexptr[1] > '9')
+       goto symbol;            /* Nope, must be a symbol. */
+      /* FALL THRU into number case.  */
+
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      {
+       /* It's a number.  */
+       int got_dot = 0, got_e = 0, toktype;
+       register char *p = tokstart;
+       int hex = input_radix > 10;
+
+       if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+         {
+           p += 2;
+           hex = 1;
+         }
+       else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+         {
+           p += 2;
+           hex = 0;
+         }
+
+       for (;; ++p)
+         {
+           if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+             got_dot = got_e = 1;
+           else if (!hex && !got_dot && *p == '.')
+             got_dot = 1;
+           else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+                    && (*p == '-' || *p == '+'))
+             /* This is the sign of the exponent, not the end of the
+                number.  */
+             continue;
+           /* We will take any letters or digits.  parse_number will
+              complain if past the radix, or if L or U are not final.  */
+           else if ((*p < '0' || *p > '9')
+                    && ((*p < 'a' || *p > 'z')
+                                 && (*p < 'A' || *p > 'Z')))
+             break;
+         }
+       toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+        if (toktype == ERROR)
+         {
+           char *err_copy = (char *) alloca (p - tokstart + 1);
+
+           bcopy (tokstart, err_copy, p - tokstart);
+           err_copy[p - tokstart] = 0;
+           error ("Invalid number \"%s\".", err_copy);
+         }
+       lexptr = p;
+       return toktype;
+      }
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '%':
+    case '|':
+    case '&':
+    case '^':
+    case '~':
+    case '!':
+    case '@':
+    case '<':
+    case '>':
+    case '[':
+    case ']':
+    case '?':
+    case ':':
+    case '=':
+    case '{':
+    case '}':
+    symbol:
+      lexptr++;
+      return c;
+
+    case '"':
+      for (namelen = 1; (c = tokstart[namelen]) != '"'; namelen++)
+       if (c == '\\')
+         {
+           c = tokstart[++namelen];
+           if (c >= '0' && c <= '9')
+             {
+               c = tokstart[++namelen];
+               if (c >= '0' && c <= '9')
+                 c = tokstart[++namelen];
+             }
+         }
+      yylval.sval.ptr = tokstart + 1;
+      yylval.sval.length = namelen - 1;
+      lexptr += namelen + 1;
+      return STRING;
+    }
+
+  if (!(c == '_' || c == '$'
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+    /* We must have come across a bad character (e.g. ';').  */
+    error ("Invalid character '%c' in expression.", c);
+
+  /* It's a name.  See how long it is.  */
+  namelen = 0;
+  for (c = tokstart[namelen];
+       (c == '_' || c == '$' || (c >= '0' && c <= '9')
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+       c = tokstart[++namelen])
+    ;
+
+  /* The token "if" terminates the expression and is NOT 
+     removed from the input stream.  */
+  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+    {
+      return 0;
+    }
+
+  lexptr += namelen;
+
+  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+     and $$digits (equivalent to $<-digits> if you could type that).
+     Make token type LAST, and put the number (the digits) in yylval.  */
+
+  if (*tokstart == '$')
+    {
+      register int negate = 0;
+      c = 1;
+      /* Double dollar means negate the number and add -1 as well.
+        Thus $$ alone means -1.  */
+      if (namelen >= 2 && tokstart[1] == '$')
+       {
+         negate = 1;
+         c = 2;
+       }
+      if (c == namelen)
+       {
+         /* Just dollars (one or two) */
+         yylval.lval = - negate;
+         return LAST;
+       }
+      /* Is the rest of the token digits?  */
+      for (; c < namelen; c++)
+       if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
+         break;
+      if (c == namelen)
+       {
+         yylval.lval = atoi (tokstart + 1 + negate);
+         if (negate)
+           yylval.lval = - yylval.lval;
+         return LAST;
+       }
+    }
+
+  /* Handle tokens that refer to machine registers:
+     $ followed by a register name.  */
+
+  if (*tokstart == '$') {
+    for (c = 0; c < NUM_REGS; c++)
+      if (namelen - 1 == strlen (reg_names[c])
+         && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
+       {
+         yylval.lval = c;
+         return REGNAME;
+       }
+    for (c = 0; c < NUM_STD_REGS; c++)
+     if (namelen - 1 == strlen (std_regs[c].name)
+        && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
+       {
+        yylval.lval = std_regs[c].regnum;
+        return REGNAME;
+       }
+  }
+  /* Catch specific keywords.  Should be done with a data structure.  */
+  switch (namelen)
+    {
+    case 8:
+      if (!strncmp (tokstart, "unsigned", 8))
+       return UNSIGNED;
+      break;
+    case 6:
+      if (!strncmp (tokstart, "struct", 6))
+       return STRUCT;
+      if (!strncmp (tokstart, "signed", 6))
+       return SIGNED;
+      if (!strncmp (tokstart, "sizeof", 6))      
+       return SIZEOF;
+      break;
+    case 5:
+      if (!strncmp (tokstart, "union", 5))
+       return UNION;
+      if (!strncmp (tokstart, "short", 5))
+       return SHORT;
+      break;
+    case 4:
+      if (!strncmp (tokstart, "enum", 4))
+       return ENUM;
+      if (!strncmp (tokstart, "long", 4))
+       return LONG;
+      if (!strncmp (tokstart, "this", 4))
+       {
+         static const char this_name[] =
+                                { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+         if (lookup_symbol (this_name, expression_context_block,
+                            VAR_NAMESPACE, 0, NULL))
+           return THIS;
+       }
+      break;
+    case 3:
+      if (!strncmp (tokstart, "int", 3))
+       return INT_KEYWORD;
+      break;
+    default:
+      break;
+    }
+
+  yylval.sval.ptr = tokstart;
+  yylval.sval.length = namelen;
+
+  /* Any other names starting in $ are debugger internal variables.  */
+
+  if (*tokstart == '$')
+    {
+      yylval.ivar =  lookup_internalvar (copy_name (yylval.sval) + 1);
+      return VARIABLE;
+    }
+
+  /* Use token-type BLOCKNAME for symbols that happen to be defined as
+     functions or symtabs.  If this is not so, then ...
+     Use token-type TYPENAME for symbols that happen to be defined
+     currently as names of types; NAME for other symbols.
+     The caller is not constrained to care about the distinction.  */
+  {
+    char *tmp = copy_name (yylval.sval);
+    struct symbol *sym;
+    int is_a_field_of_this = 0;
+    int hextype;
+
+    sym = lookup_symbol (tmp, expression_context_block,
+                        VAR_NAMESPACE, &is_a_field_of_this, NULL);
+    if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
+        lookup_partial_symtab (tmp))
+      {
+       yylval.ssym.sym = sym;
+       yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+       return BLOCKNAME;
+      }
+    if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+        {
+         yylval.tsym.type = SYMBOL_TYPE (sym);
+         return TYPENAME;
+        }
+    if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+       return TYPENAME;
+
+    /* Input names that aren't symbols but ARE valid hex numbers,
+       when the input radix permits them, can be names or numbers
+       depending on the parse.  Note we support radixes > 16 here.  */
+    if (!sym && 
+        ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+         (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+      {
+       YYSTYPE newlval;        /* Its value is ignored.  */
+       hextype = parse_number (tokstart, namelen, 0, &newlval);
+       if (hextype == INT)
+         {
+           yylval.ssym.sym = sym;
+           yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+           return NAME_OR_INT;
+         }
+       if (hextype == UINT)
+         {
+           yylval.ssym.sym = sym;
+           yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+           return NAME_OR_UINT;
+         }
+      }
+
+    /* Any other kind of symbol */
+    yylval.ssym.sym = sym;
+    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+    return NAME;
+  }
+}
+
+static void
+yyerror (msg)
+     char *msg;
+{
+  error ("Invalid syntax in expression.");
+}
+
+/* Return a null-terminated temporary copy of the name
+   of a string token.  */
+
+static char *
+copy_name (token)
+     struct stoken token;
+{
+  bcopy (token.ptr, namecopy, token.length);
+  namecopy[token.length] = 0;
+  return namecopy;
+}
+\f
+/* Reverse an expression from suffix form (in which it is constructed)
+   to prefix form (in which we can conveniently print or execute it).  */
+
+static void prefixify_subexp ();
+
+static void
+prefixify_expression (expr)
+     register struct expression *expr;
+{
+  register int len = sizeof (struct expression) +
+                                   expr->nelts * sizeof (union exp_element);
+  register struct expression *temp;
+  register int inpos = expr->nelts, outpos = 0;
+
+  temp = (struct expression *) alloca (len);
+
+  /* Copy the original expression into temp.  */
+  bcopy (expr, temp, len);
+
+  prefixify_subexp (temp, expr, inpos, outpos);
+}
+
+/* Return the number of exp_elements in the subexpression of EXPR
+   whose last exp_element is at index ENDPOS - 1 in EXPR.  */
+
+static int
+length_of_subexp (expr, endpos)
+     register struct expression *expr;
+     register int endpos;
+{
+  register int oplen = 1;
+  register int args = 0;
+  register int i;
+
+  if (endpos < 0)
+    error ("?error in length_of_subexp");
+
+  i = (int) expr->elts[endpos - 1].opcode;
+
+  switch (i)
+    {
+      /* C++  */
+    case OP_SCOPE:
+      oplen = 4 + ((expr->elts[endpos - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case OP_LONG:
+    case OP_DOUBLE:
+      oplen = 4;
+      break;
+
+    case OP_VAR_VALUE:
+    case OP_LAST:
+    case OP_REGISTER:
+    case OP_INTERNALVAR:
+      oplen = 3;
+      break;
+
+    case OP_FUNCALL:
+      oplen = 3;
+      args = 1 + expr->elts[endpos - 2].longconst;
+      break;
+
+    case UNOP_CAST:
+    case UNOP_MEMVAL:
+      oplen = 3;
+      args = 1;
+      break;
+
+    case STRUCTOP_STRUCT:
+    case STRUCTOP_PTR:
+      args = 1;
+    case OP_STRING:
+      oplen = 3 + ((expr->elts[endpos - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case TERNOP_COND:
+      args = 3;
+      break;
+
+    case BINOP_ASSIGN_MODIFY:
+      oplen = 3;
+      args = 2;
+      break;
+
+      /* C++ */
+    case OP_THIS:
+      oplen = 2;
+      break;
+
+    default:
+      args = 1 + (i < (int) BINOP_END);
+    }
+
+  while (args > 0)
+    {
+      oplen += length_of_subexp (expr, endpos - oplen);
+      args--;
+    }
+
+  return oplen;
+}
+
+/* Copy the subexpression ending just before index INEND in INEXPR
+   into OUTEXPR, starting at index OUTBEG.
+   In the process, convert it from suffix to prefix form.  */
+
+static void
+prefixify_subexp (inexpr, outexpr, inend, outbeg)
+     register struct expression *inexpr;
+     struct expression *outexpr;
+     register int inend;
+     int outbeg;
+{
+  register int oplen = 1;
+  register int args = 0;
+  register int i;
+  int *arglens;
+  enum exp_opcode opcode;
+
+  /* Compute how long the last operation is (in OPLEN),
+     and also how many preceding subexpressions serve as
+     arguments for it (in ARGS).  */
+
+  opcode = inexpr->elts[inend - 1].opcode;
+  switch (opcode)
+    {
+      /* C++  */
+    case OP_SCOPE:
+      oplen = 4 + ((inexpr->elts[inend - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case OP_LONG:
+    case OP_DOUBLE:
+      oplen = 4;
+      break;
+
+    case OP_VAR_VALUE:
+    case OP_LAST:
+    case OP_REGISTER:
+    case OP_INTERNALVAR:
+      oplen = 3;
+      break;
+
+    case OP_FUNCALL:
+      oplen = 3;
+      args = 1 + inexpr->elts[inend - 2].longconst;
+      break;
+
+    case UNOP_CAST:
+    case UNOP_MEMVAL:
+      oplen = 3;
+      args = 1;
+      break;
+
+    case STRUCTOP_STRUCT:
+    case STRUCTOP_PTR:
+      args = 1;
+    case OP_STRING:
+      oplen = 3 + ((inexpr->elts[inend - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+                  
+      break;
+
+    case TERNOP_COND:
+      args = 3;
+      break;
+
+    case BINOP_ASSIGN_MODIFY:
+      oplen = 3;
+      args = 2;
+      break;
+
+      /* C++ */
+    case OP_THIS:
+      oplen = 2;
+      break;
+
+    default:
+      args = 1 + ((int) opcode < (int) BINOP_END);
+    }
+
+  /* Copy the final operator itself, from the end of the input
+     to the beginning of the output.  */
+  inend -= oplen;
+  bcopy (&inexpr->elts[inend], &outexpr->elts[outbeg],
+        oplen * sizeof (union exp_element));
+  outbeg += oplen;
+
+  /* Find the lengths of the arg subexpressions.  */
+  arglens = (int *) alloca (args * sizeof (int));
+  for (i = args - 1; i >= 0; i--)
+    {
+      oplen = length_of_subexp (inexpr, inend);
+      arglens[i] = oplen;
+      inend -= oplen;
+    }
+
+  /* Now copy each subexpression, preserving the order of
+     the subexpressions, but prefixifying each one.
+     In this loop, inend starts at the beginning of
+     the expression this level is working on
+     and marches forward over the arguments.
+     outbeg does similarly in the output.  */
+  for (i = 0; i < args; i++)
+    {
+      oplen = arglens[i];
+      inend += oplen;
+      prefixify_subexp (inexpr, outexpr, inend, outbeg);
+      outbeg += oplen;
+    }
+}
+\f
+/* This page contains the two entry points to this file.  */
+
+/* Read a C expression from the string *STRINGPTR points to,
+   parse it, and return a pointer to a  struct expression  that we malloc.
+   Use block BLOCK as the lexical context for variable names;
+   if BLOCK is zero, use the block of the selected stack frame.
+   Meanwhile, advance *STRINGPTR to point after the expression,
+   at the first nonwhite character that is not part of the expression
+   (possibly a null character).
+
+   If COMMA is nonzero, stop if a comma is reached.  */
+
+struct expression *
+parse_c_1 (stringptr, block, comma)
+     char **stringptr;
+     struct block *block;
+     int comma;
+{
+  struct cleanup *old_chain;
+
+  lexptr = *stringptr;
+
+  paren_depth = 0;
+  type_stack_depth = 0;
+
+  comma_terminates = comma;
+
+  if (lexptr == 0 || *lexptr == 0)
+    error_no_arg ("expression to compute");
+
+  old_chain = make_cleanup (free_funcalls, 0);
+  funcall_chain = 0;
+
+  expression_context_block = block ? block : get_selected_block ();
+
+  namecopy = (char *) alloca (strlen (lexptr) + 1);
+  expout_size = 10;
+  expout_ptr = 0;
+  expout = (struct expression *)
+    xmalloc (sizeof (struct expression)
+            + expout_size * sizeof (union exp_element));
+  make_cleanup (free_current_contents, &expout);
+  if (yyparse ())
+    yyerror (NULL);
+  discard_cleanups (old_chain);
+  expout->nelts = expout_ptr;
+  expout = (struct expression *)
+    xrealloc (expout,
+             sizeof (struct expression)
+             + expout_ptr * sizeof (union exp_element));
+  prefixify_expression (expout);
+  *stringptr = lexptr;
+  return expout;
+}
+
+/* Parse STRING as an expression, and complain if this fails
+   to use up all of the contents of STRING.  */
+
+struct expression *
+parse_c_expression (string)
+     char *string;
+{
+  register struct expression *exp;
+  exp = parse_c_1 (&string, 0, 0);
+  if (*string)
+    error ("Junk after end of expression.");
+  return exp;
+}
+
+static void 
+push_type (tp)
+     enum type_pieces tp;
+{
+  if (type_stack_depth == type_stack_size)
+    {
+      type_stack_size *= 2;
+      type_stack = (enum type_pieces *)
+       xrealloc (type_stack, type_stack_size * sizeof (enum type_pieces));
+    }
+  type_stack[type_stack_depth++] = tp;
+}
+
+static enum type_pieces 
+pop_type ()
+{
+  if (type_stack_depth)
+    return type_stack[--type_stack_depth];
+  return tp_end;
+}
+
+void
+_initialize_expread ()
+{
+  type_stack_size = 80;
+  type_stack_depth = 0;
+  type_stack = (enum type_pieces *)
+    xmalloc (type_stack_size * sizeof (enum type_pieces));
+}
diff --git a/gdb/expread.y b/gdb/expread.y
new file mode 100755 (executable)
index 0000000..3b19750
--- /dev/null
@@ -0,0 +1,1902 @@
+/* Parse C expressions for GDB.
+   Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+/* Parse a C expression from text in a string,
+   and return the result as a  struct expression  pointer.
+   That structure contains arithmetic operations in reverse polish,
+   with constants represented by operations that are followed by special data.
+   See expression.h for the details of the format.
+   What is important here is that it can be built up sequentially
+   during the process of parsing; the lower levels of the tree always
+   come first in the result.  */
+   
+%{
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+#include "expression.h"
+#include "value.h"
+#include "command.h"
+
+static struct expression *expout;
+static int expout_size;
+static int expout_ptr;
+
+static int yylex ();
+static void yyerror ();
+static void write_exp_elt ();
+static void write_exp_elt_opcode ();
+static void write_exp_elt_sym ();
+static void write_exp_elt_longcst ();
+static void write_exp_elt_dblcst ();
+static void write_exp_elt_type ();
+static void write_exp_elt_intern ();
+static void write_exp_string ();
+static void start_arglist ();
+static int end_arglist ();
+static void free_funcalls ();
+static char *copy_name ();
+static int parse_number ();
+
+/* If this is nonzero, this block is used as the lexical context
+   for symbol names.  */
+
+static struct block *expression_context_block;
+
+/* The innermost context required by the stack and register variables
+   we've encountered so far. */
+struct block *innermost_block;
+
+/* The block in which the most recently discovered symbol was found. */
+struct block *block_found;
+
+/* Number of arguments seen so far in innermost function call.  */
+static int arglist_len;
+
+/* Data structure for saving values of arglist_len
+   for function calls whose arguments contain other function calls.  */
+
+struct funcall
+  {
+    struct funcall *next;
+    int arglist_len;
+  };
+
+struct funcall *funcall_chain;
+
+/* This kind of datum is used to represent the name
+   of a symbol token.  */
+
+struct stoken
+  {
+    char *ptr;
+    int length;
+  };
+
+struct ttype
+  {
+    struct stoken stoken;
+    struct type *type;
+  };
+
+struct symtoken
+  {
+    struct stoken stoken;
+    struct symbol *sym;
+    int is_a_field_of_this;
+  };
+
+/* For parsing of complicated types.
+   An array should be preceded in the list by the size of the array.  */
+enum type_pieces
+  {tp_end = -1, tp_pointer, tp_reference, tp_array, tp_function};
+static enum type_pieces *type_stack;
+static int type_stack_depth, type_stack_size;
+
+static void push_type ();
+static enum type_pieces pop_type ();
+
+/* Allow debugging of parsing.  */
+#define YYDEBUG 1
+%}
+
+/* Although the yacc "value" of an expression is not used,
+   since the result is stored in the structure being created,
+   other node types do have values.  */
+
+%union
+  {
+    LONGEST lval;
+    unsigned LONGEST ulval;
+    double dval;
+    struct symbol *sym;
+    struct type *tval;
+    struct stoken sval;
+    struct ttype tsym;
+    struct symtoken ssym;
+    int voidval;
+    struct block *bval;
+    enum exp_opcode opcode;
+    struct internalvar *ivar;
+
+    struct type **tvec;
+    int *ivec;
+  }
+
+%type <voidval> exp exp1 start variable
+%type <tval> type typebase
+%type <tvec> nonempty_typelist
+%type <bval> block
+
+/* Fancy type parsing.  */
+%type <voidval> func_mod direct_abs_decl abs_decl
+%type <tval> ptype
+%type <lval> array_mod
+
+%token <lval> INT CHAR
+%token <ulval> UINT
+%token <dval> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input,
+   and both convey their data as strings.
+   But a TYPENAME is a string that happens to be defined as a typedef
+   or builtin type name (such as int or char)
+   and a NAME is any other symbol.
+
+   Contexts where this distinction is not important can use the
+   nonterminal "name", which matches either NAME or TYPENAME.  */
+
+%token <sval> STRING
+%token <ssym> NAME BLOCKNAME
+%token <tsym> TYPENAME
+%type <sval> name
+%type <ssym> name_not_typename
+%type <tsym> typename
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+   but which would parse as a valid number in the current input radix.
+   E.g. "c" when input_radix==16.  Depending on the parse, it will be
+   turned into a name or into a number.  NAME_OR_UINT ditto.  */
+
+%token <ssym> NAME_OR_INT NAME_OR_UINT
+
+%token STRUCT UNION ENUM SIZEOF UNSIGNED COLONCOLON
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish different
+   legal basetypes.  */
+%token SIGNED LONG SHORT INT_KEYWORD
+
+%token <lval> LAST REGNAME
+
+%token <ivar> VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+/* C++ */
+%token THIS
+
+%left ','
+%left ABOVE_COMMA
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OR
+%left AND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '@'
+%left '+' '-'
+%left '*' '/' '%'
+%right UNARY INCREMENT DECREMENT
+%right ARROW '.' '[' '('
+%left COLONCOLON
+\f
+%%
+
+start   :      exp1
+       ;
+
+/* Expressions, including the comma operator.  */
+exp1   :       exp
+       |       exp1 ',' exp
+                       { write_exp_elt_opcode (BINOP_COMMA); }
+       ;
+
+/* Expressions, not including the comma operator.  */
+exp    :       '*' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_IND); }
+
+exp    :       '&' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_ADDR); }
+
+exp    :       '-' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_NEG); }
+       ;
+
+exp    :       '!' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_ZEROP); }
+       ;
+
+exp    :       '~' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_LOGNOT); }
+       ;
+
+exp    :       INCREMENT exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+       ;
+
+exp    :       DECREMENT exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+       ;
+
+exp    :       exp INCREMENT    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+       ;
+
+exp    :       exp DECREMENT    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+       ;
+
+exp    :       SIZEOF exp       %prec UNARY
+                       { write_exp_elt_opcode (UNOP_SIZEOF); }
+       ;
+
+exp    :       exp ARROW name
+                       { write_exp_elt_opcode (STRUCTOP_PTR);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (STRUCTOP_PTR); }
+       ;
+
+exp    :       exp ARROW '*' exp
+                       { write_exp_elt_opcode (STRUCTOP_MPTR); }
+       ;
+
+exp    :       exp '.' name
+                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+       ;
+
+exp    :       exp '.' '*' exp
+                       { write_exp_elt_opcode (STRUCTOP_MEMBER); }
+       ;
+
+exp    :       exp '[' exp1 ']'
+                       { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+       ;
+
+exp    :       exp '(' 
+                       /* This is to save the value of arglist_len
+                          being accumulated by an outer function call.  */
+                       { start_arglist (); }
+               arglist ')'     %prec ARROW
+                       { write_exp_elt_opcode (OP_FUNCALL);
+                         write_exp_elt_longcst ((LONGEST) end_arglist ());
+                         write_exp_elt_opcode (OP_FUNCALL); }
+       ;
+
+arglist        :
+       ;
+
+arglist        :       exp
+                       { arglist_len = 1; }
+       ;
+
+arglist        :       arglist ',' exp   %prec ABOVE_COMMA
+                       { arglist_len++; }
+       ;
+
+exp    :       '{' type '}' exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_MEMVAL);
+                         write_exp_elt_type ($2);
+                         write_exp_elt_opcode (UNOP_MEMVAL); }
+       ;
+
+exp    :       '(' type ')' exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type ($2);
+                         write_exp_elt_opcode (UNOP_CAST); }
+       ;
+
+exp    :       '(' exp1 ')'
+                       { }
+       ;
+
+/* Binary operators in order of decreasing precedence.  */
+
+exp    :       exp '@' exp
+                       { write_exp_elt_opcode (BINOP_REPEAT); }
+       ;
+
+exp    :       exp '*' exp
+                       { write_exp_elt_opcode (BINOP_MUL); }
+       ;
+
+exp    :       exp '/' exp
+                       { write_exp_elt_opcode (BINOP_DIV); }
+       ;
+
+exp    :       exp '%' exp
+                       { write_exp_elt_opcode (BINOP_REM); }
+       ;
+
+exp    :       exp '+' exp
+                       { write_exp_elt_opcode (BINOP_ADD); }
+       ;
+
+exp    :       exp '-' exp
+                       { write_exp_elt_opcode (BINOP_SUB); }
+       ;
+
+exp    :       exp LSH exp
+                       { write_exp_elt_opcode (BINOP_LSH); }
+       ;
+
+exp    :       exp RSH exp
+                       { write_exp_elt_opcode (BINOP_RSH); }
+       ;
+
+exp    :       exp EQUAL exp
+                       { write_exp_elt_opcode (BINOP_EQUAL); }
+       ;
+
+exp    :       exp NOTEQUAL exp
+                       { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+       ;
+
+exp    :       exp LEQ exp
+                       { write_exp_elt_opcode (BINOP_LEQ); }
+       ;
+
+exp    :       exp GEQ exp
+                       { write_exp_elt_opcode (BINOP_GEQ); }
+       ;
+
+exp    :       exp '<' exp
+                       { write_exp_elt_opcode (BINOP_LESS); }
+       ;
+
+exp    :       exp '>' exp
+                       { write_exp_elt_opcode (BINOP_GTR); }
+       ;
+
+exp    :       exp '&' exp
+                       { write_exp_elt_opcode (BINOP_LOGAND); }
+       ;
+
+exp    :       exp '^' exp
+                       { write_exp_elt_opcode (BINOP_LOGXOR); }
+       ;
+
+exp    :       exp '|' exp
+                       { write_exp_elt_opcode (BINOP_LOGIOR); }
+       ;
+
+exp    :       exp AND exp
+                       { write_exp_elt_opcode (BINOP_AND); }
+       ;
+
+exp    :       exp OR exp
+                       { write_exp_elt_opcode (BINOP_OR); }
+       ;
+
+exp    :       exp '?' exp ':' exp     %prec '?'
+                       { write_exp_elt_opcode (TERNOP_COND); }
+       ;
+                         
+exp    :       exp '=' exp
+                       { write_exp_elt_opcode (BINOP_ASSIGN); }
+       ;
+
+exp    :       exp ASSIGN_MODIFY exp
+                       { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+                         write_exp_elt_opcode ($2);
+                         write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+       ;
+
+exp    :       INT
+                       { write_exp_elt_opcode (OP_LONG);
+                         if ($1 == (int) $1 || $1 == (unsigned int) $1)
+                           write_exp_elt_type (builtin_type_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_LONGEST);
+                         write_exp_elt_longcst ((LONGEST) $1);
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       NAME_OR_INT
+                       { YYSTYPE val;
+                         parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+                         write_exp_elt_opcode (OP_LONG);
+                         if (val.lval == (int) val.lval ||
+                             val.lval == (unsigned int) val.lval)
+                           write_exp_elt_type (builtin_type_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_LONGEST);
+                         write_exp_elt_longcst (val.lval);
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       UINT
+                       {
+                         write_exp_elt_opcode (OP_LONG);
+                         if ($1 == (unsigned int) $1)
+                           write_exp_elt_type (builtin_type_unsigned_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
+                         write_exp_elt_longcst ((LONGEST) $1);
+                         write_exp_elt_opcode (OP_LONG);
+                       }
+       ;
+
+exp    :       NAME_OR_UINT
+                       { YYSTYPE val;
+                         parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+                         write_exp_elt_opcode (OP_LONG);
+                         if (val.ulval == (unsigned int) val.ulval)
+                           write_exp_elt_type (builtin_type_unsigned_int);
+                         else
+                           write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
+                         write_exp_elt_longcst ((LONGEST)val.ulval);
+                         write_exp_elt_opcode (OP_LONG);
+                       }
+       ;
+
+exp    :       CHAR
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_char);
+                         write_exp_elt_longcst ((LONGEST) $1);
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       FLOAT
+                       { write_exp_elt_opcode (OP_DOUBLE);
+                         write_exp_elt_type (builtin_type_double);
+                         write_exp_elt_dblcst ($1);
+                         write_exp_elt_opcode (OP_DOUBLE); }
+       ;
+
+exp    :       variable
+       ;
+
+exp    :       LAST
+                       { write_exp_elt_opcode (OP_LAST);
+                         write_exp_elt_longcst ((LONGEST) $1);
+                         write_exp_elt_opcode (OP_LAST); }
+       ;
+
+exp    :       REGNAME
+                       { write_exp_elt_opcode (OP_REGISTER);
+                         write_exp_elt_longcst ((LONGEST) $1);
+                         write_exp_elt_opcode (OP_REGISTER); }
+       ;
+
+exp    :       VARIABLE
+                       { write_exp_elt_opcode (OP_INTERNALVAR);
+                         write_exp_elt_intern ($1);
+                         write_exp_elt_opcode (OP_INTERNALVAR); }
+       ;
+
+exp    :       SIZEOF '(' type ')'     %prec UNARY
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       STRING
+                       { write_exp_elt_opcode (OP_STRING);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_STRING); }
+       ;
+
+/* C++.  */
+exp    :       THIS
+                       { write_exp_elt_opcode (OP_THIS);
+                         write_exp_elt_opcode (OP_THIS); }
+       ;
+
+/* end of C++.  */
+
+block  :       BLOCKNAME
+                       {
+                         if ($1.sym != 0)
+                             $$ = SYMBOL_BLOCK_VALUE ($1.sym);
+                         else
+                           {
+                             struct symtab *tem =
+                                 lookup_symtab (copy_name ($1.stoken));
+                             if (tem)
+                               $$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), 1);
+                             else
+                               error ("No file or function \"%s\".",
+                                      copy_name ($1.stoken));
+                           }
+                       }
+       ;
+
+block  :       block COLONCOLON name
+                       { struct symbol *tem
+                           = lookup_symbol (copy_name ($3), $1,
+                                            VAR_NAMESPACE, 0, NULL);
+                         if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+                           error ("No function \"%s\" in specified context.",
+                                  copy_name ($3));
+                         $$ = SYMBOL_BLOCK_VALUE (tem); }
+       ;
+
+variable:      block COLONCOLON name
+                       { struct symbol *sym;
+                         sym = lookup_symbol (copy_name ($3), $1,
+                                              VAR_NAMESPACE, 0, NULL);
+                         if (sym == 0)
+                           error ("No symbol \"%s\" in specified context.",
+                                  copy_name ($3));
+                         write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_sym (sym);
+                         write_exp_elt_opcode (OP_VAR_VALUE); }
+       ;
+
+variable:      typebase COLONCOLON name
+                       {
+                         struct type *type = $1;
+                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+                             && TYPE_CODE (type) != TYPE_CODE_UNION)
+                           error ("`%s' is not defined as an aggregate type.",
+                                  TYPE_NAME (type));
+
+                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_type (type);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (OP_SCOPE);
+                       }
+       |       COLONCOLON name
+                       {
+                         char *name = copy_name ($2);
+                         struct symbol *sym;
+                         int i;
+
+                         sym =
+                           lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+                         if (sym)
+                           {
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             break;
+                           }
+                         for (i = 0; i < misc_function_count; i++)
+                           if (!strcmp (misc_function_vector[i].name, name))
+                             break;
+
+                         if (i < misc_function_count)
+                           {
+                             enum misc_function_type mft =
+                                 misc_function_vector[i].type;
+                             
+                             write_exp_elt_opcode (OP_LONG);
+                             write_exp_elt_type (builtin_type_int);
+                             write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
+                             write_exp_elt_opcode (OP_LONG);
+                             write_exp_elt_opcode (UNOP_MEMVAL);
+                             if (mft == mf_data || mft == mf_bss)
+                               write_exp_elt_type (builtin_type_int);
+                             else if (mft == mf_text)
+                               write_exp_elt_type (lookup_function_type (builtin_type_int));
+                             else
+                               write_exp_elt_type (builtin_type_char);
+                             write_exp_elt_opcode (UNOP_MEMVAL);
+                           }
+                         else
+                           if (symtab_list == 0
+                               && partial_symtab_list == 0)
+                             error ("No symbol table is loaded.  Use the \"file\" command.");
+                           else
+                             error ("No symbol \"%s\" in current context.", name);
+                       }
+       ;
+
+variable:      name_not_typename
+                       { struct symbol *sym = $1.sym;
+
+                         if (sym)
+                           {
+                             switch (sym->class)
+                               {
+                               case LOC_REGISTER:
+                               case LOC_ARG:
+                               case LOC_LOCAL:
+                               case LOC_LOCAL_ARG:
+                                 if (innermost_block == 0 ||
+                                     contained_in (block_found, 
+                                                   innermost_block))
+                                   innermost_block = block_found;
+                               }
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                           }
+                         else if ($1.is_a_field_of_this)
+                           {
+                             /* C++: it hangs off of `this'.  Must
+                                not inadvertently convert from a method call
+                                to data ref.  */
+                             if (innermost_block == 0 || 
+                                 contained_in (block_found, innermost_block))
+                               innermost_block = block_found;
+                             write_exp_elt_opcode (OP_THIS);
+                             write_exp_elt_opcode (OP_THIS);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                             write_exp_string ($1.stoken);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                           }
+                         else
+                           {
+                             register int i;
+                             register char *arg = copy_name ($1.stoken);
+
+                               /* FIXME, this search is linear!  At least
+                                  optimize the strcmp with a 1-char cmp... */
+                             for (i = 0; i < misc_function_count; i++)
+                               if (!strcmp (misc_function_vector[i].name, arg))
+                                 break;
+
+                             if (i < misc_function_count)
+                               {
+                                 enum misc_function_type mft =
+                                     misc_function_vector[i].type;
+                                 
+                                 write_exp_elt_opcode (OP_LONG);
+                                 write_exp_elt_type (builtin_type_int);
+                                 write_exp_elt_longcst ((LONGEST) misc_function_vector[i].address);
+                                 write_exp_elt_opcode (OP_LONG);
+                                 write_exp_elt_opcode (UNOP_MEMVAL);
+                                 if (mft == mf_data || mft == mf_bss)
+                                   write_exp_elt_type (builtin_type_int);
+                                 else if (mft == mf_text)
+                                   write_exp_elt_type (lookup_function_type (builtin_type_int));
+                                 else
+                                   write_exp_elt_type (builtin_type_char);
+                                 write_exp_elt_opcode (UNOP_MEMVAL);
+                               }
+                             else if (symtab_list == 0
+                                      && partial_symtab_list == 0)
+                               error ("No symbol table is loaded.  Use the \"file\" command.");
+                             else
+                               error ("No symbol \"%s\" in current context.",
+                                      copy_name ($1.stoken));
+                           }
+                       }
+       ;
+
+
+ptype  :       typebase
+       |       typebase abs_decl
+               {
+                 /* This is where the interesting stuff happens.  */
+                 int done = 0;
+                 int array_size;
+                 struct type *follow_type = $1;
+                 
+                 while (!done)
+                   switch (pop_type ())
+                     {
+                     case tp_end:
+                       done = 1;
+                       break;
+                     case tp_pointer:
+                       follow_type = lookup_pointer_type (follow_type);
+                       break;
+                     case tp_reference:
+                       follow_type = lookup_reference_type (follow_type);
+                       break;
+                     case tp_array:
+                       array_size = (int) pop_type ();
+                       if (array_size != -1)
+                         follow_type = create_array_type (follow_type,
+                                                          array_size);
+                       else
+                         follow_type = lookup_pointer_type (follow_type);
+                       break;
+                     case tp_function:
+                       follow_type = lookup_function_type (follow_type);
+                       break;
+                     }
+                 $$ = follow_type;
+               }
+       ;
+
+abs_decl:      '*'
+                       { push_type (tp_pointer); $$ = 0; }
+       |       '*' abs_decl
+                       { push_type (tp_pointer); $$ = $2; }
+       |       direct_abs_decl
+       ;
+
+direct_abs_decl: '(' abs_decl ')'
+                       { $$ = $2; }
+       |       direct_abs_decl array_mod
+                       {
+                         push_type ((enum type_pieces) $2);
+                         push_type (tp_array);
+                       }
+       |       array_mod
+                       {
+                         push_type ((enum type_pieces) $1);
+                         push_type (tp_array);
+                         $$ = 0;
+                       }
+       |       direct_abs_decl func_mod
+                       { push_type (tp_function); }
+       |       func_mod
+                       { push_type (tp_function); }
+       ;
+
+array_mod:     '[' ']'
+                       { $$ = -1; }
+       |       '[' INT ']'
+                       { $$ = $2; }
+       ;
+
+func_mod:      '(' ')'
+                       { $$ = 0; }
+       ;
+
+type   :       ptype
+       |       typebase COLONCOLON '*'
+                       { $$ = lookup_member_type (builtin_type_int, $1); }
+       |       type '(' typebase COLONCOLON '*' ')'
+                       { $$ = lookup_member_type ($1, $3); }
+       |       type '(' typebase COLONCOLON '*' ')' '(' ')'
+                       { $$ = lookup_member_type
+                           (lookup_function_type ($1), $3); }
+       |       type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'
+                       { $$ = lookup_member_type
+                           (lookup_function_type ($1), $3);
+                         free ($8); }
+       ;
+
+typebase
+       :       TYPENAME
+                       { $$ = $1.type; }
+       |       INT_KEYWORD
+                       { $$ = builtin_type_int; }
+       |       LONG
+                       { $$ = builtin_type_long; }
+       |       SHORT
+                       { $$ = builtin_type_short; }
+       |       LONG INT_KEYWORD
+                       { $$ = builtin_type_long; }
+       |       UNSIGNED LONG INT_KEYWORD
+                       { $$ = builtin_type_unsigned_long; }
+       |       SHORT INT_KEYWORD
+                       { $$ = builtin_type_short; }
+       |       UNSIGNED SHORT INT_KEYWORD
+                       { $$ = builtin_type_unsigned_short; }
+       |       STRUCT name
+                       { $$ = lookup_struct (copy_name ($2),
+                                             expression_context_block); }
+       |       UNION name
+                       { $$ = lookup_union (copy_name ($2),
+                                            expression_context_block); }
+       |       ENUM name
+                       { $$ = lookup_enum (copy_name ($2),
+                                           expression_context_block); }
+       |       UNSIGNED typename
+                       { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
+       |       UNSIGNED
+                       { $$ = builtin_type_unsigned_int; }
+       |       SIGNED typename
+                       { $$ = $2.type; }
+       |       SIGNED
+                       { $$ = builtin_type_int; }
+       ;
+
+typename:      TYPENAME
+       |       INT_KEYWORD
+               {
+                 $$.stoken.ptr = "int";
+                 $$.stoken.length = 3;
+                 $$.type = builtin_type_int;
+               }
+       |       LONG
+               {
+                 $$.stoken.ptr = "long";
+                 $$.stoken.length = 4;
+                 $$.type = builtin_type_long;
+               }
+       |       SHORT
+               {
+                 $$.stoken.ptr = "short";
+                 $$.stoken.length = 5;
+                 $$.type = builtin_type_short;
+               }
+       ;
+
+nonempty_typelist
+       :       type
+               { $$ = (struct type **)xmalloc (sizeof (struct type *) * 2);
+                 $$[0] = (struct type *)0;
+                 $$[1] = $1;
+               }
+       |       nonempty_typelist ',' type
+               { int len = sizeof (struct type *) * ++($<ivec>1[0]);
+                 $$ = (struct type **)xrealloc ($1, len);
+                 $$[$<ivec>$[0]] = $3;
+               }
+       ;
+
+name   :       NAME { $$ = $1.stoken; }
+       |       BLOCKNAME { $$ = $1.stoken; }
+       |       TYPENAME { $$ = $1.stoken; }
+       |       NAME_OR_INT  { $$ = $1.stoken; }
+       |       NAME_OR_UINT  { $$ = $1.stoken; }
+       ;
+
+name_not_typename :    NAME
+       |       BLOCKNAME
+       |       NAME_OR_INT
+       |       NAME_OR_UINT
+       ;
+
+%%
+\f
+/* Begin counting arguments for a function call,
+   saving the data about any containing call.  */
+
+static void
+start_arglist ()
+{
+  register struct funcall *new = (struct funcall *) xmalloc (sizeof (struct funcall));
+
+  new->next = funcall_chain;
+  new->arglist_len = arglist_len;
+  arglist_len = 0;
+  funcall_chain = new;
+}
+
+/* Return the number of arguments in a function call just terminated,
+   and restore the data for the containing function call.  */
+
+static int
+end_arglist ()
+{
+  register int val = arglist_len;
+  register struct funcall *call = funcall_chain;
+  funcall_chain = call->next;
+  arglist_len = call->arglist_len;
+  free (call);
+  return val;
+}
+
+/* Free everything in the funcall chain.
+   Used when there is an error inside parsing.  */
+
+static void
+free_funcalls ()
+{
+  register struct funcall *call, *next;
+
+  for (call = funcall_chain; call; call = next)
+    {
+      next = call->next;
+      free (call);
+    }
+}
+\f
+/* This page contains the functions for adding data to the  struct expression
+   being constructed.  */
+
+/* Add one element to the end of the expression.  */
+
+/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into
+   a register through here */
+
+static void
+write_exp_elt (expelt)
+     union exp_element expelt;
+{
+  if (expout_ptr >= expout_size)
+    {
+      expout_size *= 2;
+      expout = (struct expression *) xrealloc (expout,
+                                              sizeof (struct expression)
+                                              + expout_size * sizeof (union exp_element));
+    }
+  expout->elts[expout_ptr++] = expelt;
+}
+
+static void
+write_exp_elt_opcode (expelt)
+     enum exp_opcode expelt;
+{
+  union exp_element tmp;
+
+  tmp.opcode = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_sym (expelt)
+     struct symbol *expelt;
+{
+  union exp_element tmp;
+
+  tmp.symbol = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_longcst (expelt)
+     LONGEST expelt;
+{
+  union exp_element tmp;
+
+  tmp.longconst = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_dblcst (expelt)
+     double expelt;
+{
+  union exp_element tmp;
+
+  tmp.doubleconst = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_type (expelt)
+     struct type *expelt;
+{
+  union exp_element tmp;
+
+  tmp.type = expelt;
+
+  write_exp_elt (tmp);
+}
+
+static void
+write_exp_elt_intern (expelt)
+     struct internalvar *expelt;
+{
+  union exp_element tmp;
+
+  tmp.internalvar = expelt;
+
+  write_exp_elt (tmp);
+}
+
+/* Add a string constant to the end of the expression.
+   Follow it by its length in bytes, as a separate exp_element.  */
+
+static void
+write_exp_string (str)
+     struct stoken str;
+{
+  register int len = str.length;
+  register int lenelt
+    = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+
+  expout_ptr += lenelt;
+
+  if (expout_ptr >= expout_size)
+    {
+      expout_size = max (expout_size * 2, expout_ptr + 10);
+      expout = (struct expression *)
+       xrealloc (expout, (sizeof (struct expression)
+                          + (expout_size * sizeof (union exp_element))));
+    }
+  bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len);
+  ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+  write_exp_elt_longcst ((LONGEST) len);
+}
+\f
+/* During parsing of a C expression, the pointer to the next character
+   is in this variable.  */
+
+static char *lexptr;
+
+/* Tokens that refer to names do so with explicit pointer and length,
+   so they can share the storage that lexptr is parsing.
+
+   When it is necessary to pass a name to a function that expects
+   a null-terminated string, the substring is copied out
+   into a block of storage that namecopy points to.
+
+   namecopy is allocated once, guaranteed big enough, for each parsing.  */
+
+static char *namecopy;
+
+/* Current depth in parentheses within the expression.  */
+
+static int paren_depth;
+
+/* Nonzero means stop parsing on first comma (if not within parentheses).  */
+
+static int comma_terminates;
+
+/* Take care of parsing a number (anything that starts with a digit).
+   Set yylval and return the token type; update lexptr.
+   LEN is the number of characters in it.  */
+
+/*** Needs some error checking for the float case ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+     register char *p;
+     register int len;
+     int parsed_float;
+     YYSTYPE *putithere;
+{
+  register LONGEST n = 0;
+  register int i;
+  register int c;
+  register int base = input_radix;
+  int unsigned_p = 0;
+
+  extern double atof ();
+
+  if (parsed_float)
+    {
+      /* It's a float since it contains a point or an exponent.  */
+      putithere->dval = atof (p);
+      return FLOAT;
+    }
+
+  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
+  if (p[0] == '0')
+    switch (p[1])
+      {
+      case 'x':
+      case 'X':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 16;
+           len -= 2;
+         }
+       break;
+
+      case 't':
+      case 'T':
+      case 'd':
+      case 'D':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 10;
+           len -= 2;
+         }
+       break;
+
+      default:
+       base = 8;
+       break;
+      }
+
+  while (len-- > 0)
+    {
+      c = *p++;
+      if (c >= 'A' && c <= 'Z')
+       c += 'a' - 'A';
+      if (c != 'l' && c != 'u')
+       n *= base;
+      if (c >= '0' && c <= '9')
+       n += i = c - '0';
+      else
+       {
+         if (base > 10 && c >= 'a' && c <= 'f')
+           n += i = c - 'a' + 10;
+         else if (len == 0 && c == 'l')
+           ;
+         else if (len == 0 && c == 'u')
+           unsigned_p = 1;
+         else
+           return ERROR;       /* Char not a digit */
+       }
+      if (i >= base)
+       return ERROR;           /* Invalid digit in this base */
+    }
+
+  if (unsigned_p)
+    {
+      putithere->ulval = n;
+      return UINT;
+    }
+  else
+    {
+      putithere->lval = n;
+      return INT;
+    }
+}
+
+struct token
+{
+  char *operator;
+  int token;
+  enum exp_opcode opcode;
+};
+
+static struct token tokentab3[] =
+  {
+    {">>=", ASSIGN_MODIFY, BINOP_RSH},
+    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+  };
+
+static struct token tokentab2[] =
+  {
+    {"+=", ASSIGN_MODIFY, BINOP_ADD},
+    {"-=", ASSIGN_MODIFY, BINOP_SUB},
+    {"*=", ASSIGN_MODIFY, BINOP_MUL},
+    {"/=", ASSIGN_MODIFY, BINOP_DIV},
+    {"%=", ASSIGN_MODIFY, BINOP_REM},
+    {"|=", ASSIGN_MODIFY, BINOP_LOGIOR},
+    {"&=", ASSIGN_MODIFY, BINOP_LOGAND},
+    {"^=", ASSIGN_MODIFY, BINOP_LOGXOR},
+    {"++", INCREMENT, BINOP_END},
+    {"--", DECREMENT, BINOP_END},
+    {"->", ARROW, BINOP_END},
+    {"&&", AND, BINOP_END},
+    {"||", OR, BINOP_END},
+    {"::", COLONCOLON, BINOP_END},
+    {"<<", LSH, BINOP_END},
+    {">>", RSH, BINOP_END},
+    {"==", EQUAL, BINOP_END},
+    {"!=", NOTEQUAL, BINOP_END},
+    {"<=", LEQ, BINOP_END},
+    {">=", GEQ, BINOP_END}
+  };
+
+/* assign machine-independent names to certain registers 
+ * (unless overridden by the REGISTER_NAMES table)
+ */
+struct std_regs {
+       char *name;
+       int regnum;
+} std_regs[] = {
+#ifdef PC_REGNUM
+       { "pc", PC_REGNUM },
+#endif
+#ifdef FP_REGNUM
+       { "fp", FP_REGNUM },
+#endif
+#ifdef SP_REGNUM
+       { "sp", SP_REGNUM },
+#endif
+#ifdef PS_REGNUM
+       { "ps", PS_REGNUM },
+#endif
+};
+
+#define NUM_STD_REGS (sizeof std_regs / sizeof std_regs[0])
+
+/* Read one token, getting characters through lexptr.  */
+
+static int
+yylex ()
+{
+  register int c;
+  register int namelen;
+  register unsigned i;
+  register char *tokstart;
+
+ retry:
+
+  tokstart = lexptr;
+  /* See if it is a special token of length 3.  */
+  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+    if (!strncmp (tokstart, tokentab3[i].operator, 3))
+      {
+       lexptr += 3;
+       yylval.opcode = tokentab3[i].opcode;
+       return tokentab3[i].token;
+      }
+
+  /* See if it is a special token of length 2.  */
+  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+    if (!strncmp (tokstart, tokentab2[i].operator, 2))
+      {
+       lexptr += 2;
+       yylval.opcode = tokentab2[i].opcode;
+       return tokentab2[i].token;
+      }
+
+  switch (c = *tokstart)
+    {
+    case 0:
+      return 0;
+
+    case ' ':
+    case '\t':
+    case '\n':
+      lexptr++;
+      goto retry;
+
+    case '\'':
+      lexptr++;
+      c = *lexptr++;
+      if (c == '\\')
+       c = parse_escape (&lexptr);
+      yylval.lval = c;
+      c = *lexptr++;
+      if (c != '\'')
+       error ("Invalid character constant.");
+      return CHAR;
+
+    case '(':
+      paren_depth++;
+      lexptr++;
+      return c;
+
+    case ')':
+      if (paren_depth == 0)
+       return 0;
+      paren_depth--;
+      lexptr++;
+      return c;
+
+    case ',':
+      if (comma_terminates && paren_depth == 0)
+       return 0;
+      lexptr++;
+      return c;
+
+    case '.':
+      /* Might be a floating point number.  */
+      if (lexptr[1] < '0' || lexptr[1] > '9')
+       goto symbol;            /* Nope, must be a symbol. */
+      /* FALL THRU into number case.  */
+
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      {
+       /* It's a number.  */
+       int got_dot = 0, got_e = 0, toktype;
+       register char *p = tokstart;
+       int hex = input_radix > 10;
+
+       if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
+         {
+           p += 2;
+           hex = 1;
+         }
+       else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+         {
+           p += 2;
+           hex = 0;
+         }
+
+       for (;; ++p)
+         {
+           if (!hex && !got_e && (*p == 'e' || *p == 'E'))
+             got_dot = got_e = 1;
+           else if (!hex && !got_dot && *p == '.')
+             got_dot = 1;
+           else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
+                    && (*p == '-' || *p == '+'))
+             /* This is the sign of the exponent, not the end of the
+                number.  */
+             continue;
+           /* We will take any letters or digits.  parse_number will
+              complain if past the radix, or if L or U are not final.  */
+           else if ((*p < '0' || *p > '9')
+                    && ((*p < 'a' || *p > 'z')
+                                 && (*p < 'A' || *p > 'Z')))
+             break;
+         }
+       toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+        if (toktype == ERROR)
+         {
+           char *err_copy = (char *) alloca (p - tokstart + 1);
+
+           bcopy (tokstart, err_copy, p - tokstart);
+           err_copy[p - tokstart] = 0;
+           error ("Invalid number \"%s\".", err_copy);
+         }
+       lexptr = p;
+       return toktype;
+      }
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '%':
+    case '|':
+    case '&':
+    case '^':
+    case '~':
+    case '!':
+    case '@':
+    case '<':
+    case '>':
+    case '[':
+    case ']':
+    case '?':
+    case ':':
+    case '=':
+    case '{':
+    case '}':
+    symbol:
+      lexptr++;
+      return c;
+
+    case '"':
+      for (namelen = 1; (c = tokstart[namelen]) != '"'; namelen++)
+       if (c == '\\')
+         {
+           c = tokstart[++namelen];
+           if (c >= '0' && c <= '9')
+             {
+               c = tokstart[++namelen];
+               if (c >= '0' && c <= '9')
+                 c = tokstart[++namelen];
+             }
+         }
+      yylval.sval.ptr = tokstart + 1;
+      yylval.sval.length = namelen - 1;
+      lexptr += namelen + 1;
+      return STRING;
+    }
+
+  if (!(c == '_' || c == '$'
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
+    /* We must have come across a bad character (e.g. ';').  */
+    error ("Invalid character '%c' in expression.", c);
+
+  /* It's a name.  See how long it is.  */
+  namelen = 0;
+  for (c = tokstart[namelen];
+       (c == '_' || c == '$' || (c >= '0' && c <= '9')
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+       c = tokstart[++namelen])
+    ;
+
+  /* The token "if" terminates the expression and is NOT 
+     removed from the input stream.  */
+  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+    {
+      return 0;
+    }
+
+  lexptr += namelen;
+
+  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+     and $$digits (equivalent to $<-digits> if you could type that).
+     Make token type LAST, and put the number (the digits) in yylval.  */
+
+  if (*tokstart == '$')
+    {
+      register int negate = 0;
+      c = 1;
+      /* Double dollar means negate the number and add -1 as well.
+        Thus $$ alone means -1.  */
+      if (namelen >= 2 && tokstart[1] == '$')
+       {
+         negate = 1;
+         c = 2;
+       }
+      if (c == namelen)
+       {
+         /* Just dollars (one or two) */
+         yylval.lval = - negate;
+         return LAST;
+       }
+      /* Is the rest of the token digits?  */
+      for (; c < namelen; c++)
+       if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
+         break;
+      if (c == namelen)
+       {
+         yylval.lval = atoi (tokstart + 1 + negate);
+         if (negate)
+           yylval.lval = - yylval.lval;
+         return LAST;
+       }
+    }
+
+  /* Handle tokens that refer to machine registers:
+     $ followed by a register name.  */
+
+  if (*tokstart == '$') {
+    for (c = 0; c < NUM_REGS; c++)
+      if (namelen - 1 == strlen (reg_names[c])
+         && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
+       {
+         yylval.lval = c;
+         return REGNAME;
+       }
+    for (c = 0; c < NUM_STD_REGS; c++)
+     if (namelen - 1 == strlen (std_regs[c].name)
+        && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
+       {
+        yylval.lval = std_regs[c].regnum;
+        return REGNAME;
+       }
+  }
+  /* Catch specific keywords.  Should be done with a data structure.  */
+  switch (namelen)
+    {
+    case 8:
+      if (!strncmp (tokstart, "unsigned", 8))
+       return UNSIGNED;
+      break;
+    case 6:
+      if (!strncmp (tokstart, "struct", 6))
+       return STRUCT;
+      if (!strncmp (tokstart, "signed", 6))
+       return SIGNED;
+      if (!strncmp (tokstart, "sizeof", 6))      
+       return SIZEOF;
+      break;
+    case 5:
+      if (!strncmp (tokstart, "union", 5))
+       return UNION;
+      if (!strncmp (tokstart, "short", 5))
+       return SHORT;
+      break;
+    case 4:
+      if (!strncmp (tokstart, "enum", 4))
+       return ENUM;
+      if (!strncmp (tokstart, "long", 4))
+       return LONG;
+      if (!strncmp (tokstart, "this", 4))
+       {
+         static const char this_name[] =
+                                { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
+
+         if (lookup_symbol (this_name, expression_context_block,
+                            VAR_NAMESPACE, 0, NULL))
+           return THIS;
+       }
+      break;
+    case 3:
+      if (!strncmp (tokstart, "int", 3))
+       return INT_KEYWORD;
+      break;
+    default:
+      break;
+    }
+
+  yylval.sval.ptr = tokstart;
+  yylval.sval.length = namelen;
+
+  /* Any other names starting in $ are debugger internal variables.  */
+
+  if (*tokstart == '$')
+    {
+      yylval.ivar =  lookup_internalvar (copy_name (yylval.sval) + 1);
+      return VARIABLE;
+    }
+
+  /* Use token-type BLOCKNAME for symbols that happen to be defined as
+     functions or symtabs.  If this is not so, then ...
+     Use token-type TYPENAME for symbols that happen to be defined
+     currently as names of types; NAME for other symbols.
+     The caller is not constrained to care about the distinction.  */
+  {
+    char *tmp = copy_name (yylval.sval);
+    struct symbol *sym;
+    int is_a_field_of_this = 0;
+    int hextype;
+
+    sym = lookup_symbol (tmp, expression_context_block,
+                        VAR_NAMESPACE, &is_a_field_of_this, NULL);
+    if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
+        lookup_partial_symtab (tmp))
+      {
+       yylval.ssym.sym = sym;
+       yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+       return BLOCKNAME;
+      }
+    if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+        {
+         yylval.tsym.type = SYMBOL_TYPE (sym);
+         return TYPENAME;
+        }
+    if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+       return TYPENAME;
+
+    /* Input names that aren't symbols but ARE valid hex numbers,
+       when the input radix permits them, can be names or numbers
+       depending on the parse.  Note we support radixes > 16 here.  */
+    if (!sym && 
+        ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+         (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+      {
+       YYSTYPE newlval;        /* Its value is ignored.  */
+       hextype = parse_number (tokstart, namelen, 0, &newlval);
+       if (hextype == INT)
+         {
+           yylval.ssym.sym = sym;
+           yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+           return NAME_OR_INT;
+         }
+       if (hextype == UINT)
+         {
+           yylval.ssym.sym = sym;
+           yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+           return NAME_OR_UINT;
+         }
+      }
+
+    /* Any other kind of symbol */
+    yylval.ssym.sym = sym;
+    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+    return NAME;
+  }
+}
+
+static void
+yyerror (msg)
+     char *msg;
+{
+  error ("Invalid syntax in expression.");
+}
+
+/* Return a null-terminated temporary copy of the name
+   of a string token.  */
+
+static char *
+copy_name (token)
+     struct stoken token;
+{
+  bcopy (token.ptr, namecopy, token.length);
+  namecopy[token.length] = 0;
+  return namecopy;
+}
+\f
+/* Reverse an expression from suffix form (in which it is constructed)
+   to prefix form (in which we can conveniently print or execute it).  */
+
+static void prefixify_subexp ();
+
+static void
+prefixify_expression (expr)
+     register struct expression *expr;
+{
+  register int len = sizeof (struct expression) +
+                                   expr->nelts * sizeof (union exp_element);
+  register struct expression *temp;
+  register int inpos = expr->nelts, outpos = 0;
+
+  temp = (struct expression *) alloca (len);
+
+  /* Copy the original expression into temp.  */
+  bcopy (expr, temp, len);
+
+  prefixify_subexp (temp, expr, inpos, outpos);
+}
+
+/* Return the number of exp_elements in the subexpression of EXPR
+   whose last exp_element is at index ENDPOS - 1 in EXPR.  */
+
+static int
+length_of_subexp (expr, endpos)
+     register struct expression *expr;
+     register int endpos;
+{
+  register int oplen = 1;
+  register int args = 0;
+  register int i;
+
+  if (endpos < 0)
+    error ("?error in length_of_subexp");
+
+  i = (int) expr->elts[endpos - 1].opcode;
+
+  switch (i)
+    {
+      /* C++  */
+    case OP_SCOPE:
+      oplen = 4 + ((expr->elts[endpos - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case OP_LONG:
+    case OP_DOUBLE:
+      oplen = 4;
+      break;
+
+    case OP_VAR_VALUE:
+    case OP_LAST:
+    case OP_REGISTER:
+    case OP_INTERNALVAR:
+      oplen = 3;
+      break;
+
+    case OP_FUNCALL:
+      oplen = 3;
+      args = 1 + expr->elts[endpos - 2].longconst;
+      break;
+
+    case UNOP_CAST:
+    case UNOP_MEMVAL:
+      oplen = 3;
+      args = 1;
+      break;
+
+    case STRUCTOP_STRUCT:
+    case STRUCTOP_PTR:
+      args = 1;
+    case OP_STRING:
+      oplen = 3 + ((expr->elts[endpos - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case TERNOP_COND:
+      args = 3;
+      break;
+
+    case BINOP_ASSIGN_MODIFY:
+      oplen = 3;
+      args = 2;
+      break;
+
+      /* C++ */
+    case OP_THIS:
+      oplen = 2;
+      break;
+
+    default:
+      args = 1 + (i < (int) BINOP_END);
+    }
+
+  while (args > 0)
+    {
+      oplen += length_of_subexp (expr, endpos - oplen);
+      args--;
+    }
+
+  return oplen;
+}
+
+/* Copy the subexpression ending just before index INEND in INEXPR
+   into OUTEXPR, starting at index OUTBEG.
+   In the process, convert it from suffix to prefix form.  */
+
+static void
+prefixify_subexp (inexpr, outexpr, inend, outbeg)
+     register struct expression *inexpr;
+     struct expression *outexpr;
+     register int inend;
+     int outbeg;
+{
+  register int oplen = 1;
+  register int args = 0;
+  register int i;
+  int *arglens;
+  enum exp_opcode opcode;
+
+  /* Compute how long the last operation is (in OPLEN),
+     and also how many preceding subexpressions serve as
+     arguments for it (in ARGS).  */
+
+  opcode = inexpr->elts[inend - 1].opcode;
+  switch (opcode)
+    {
+      /* C++  */
+    case OP_SCOPE:
+      oplen = 4 + ((inexpr->elts[inend - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+      break;
+
+    case OP_LONG:
+    case OP_DOUBLE:
+      oplen = 4;
+      break;
+
+    case OP_VAR_VALUE:
+    case OP_LAST:
+    case OP_REGISTER:
+    case OP_INTERNALVAR:
+      oplen = 3;
+      break;
+
+    case OP_FUNCALL:
+      oplen = 3;
+      args = 1 + inexpr->elts[inend - 2].longconst;
+      break;
+
+    case UNOP_CAST:
+    case UNOP_MEMVAL:
+      oplen = 3;
+      args = 1;
+      break;
+
+    case STRUCTOP_STRUCT:
+    case STRUCTOP_PTR:
+      args = 1;
+    case OP_STRING:
+      oplen = 3 + ((inexpr->elts[inend - 2].longconst
+                   + sizeof (union exp_element))
+                  / sizeof (union exp_element));
+                  
+      break;
+
+    case TERNOP_COND:
+      args = 3;
+      break;
+
+    case BINOP_ASSIGN_MODIFY:
+      oplen = 3;
+      args = 2;
+      break;
+
+      /* C++ */
+    case OP_THIS:
+      oplen = 2;
+      break;
+
+    default:
+      args = 1 + ((int) opcode < (int) BINOP_END);
+    }
+
+  /* Copy the final operator itself, from the end of the input
+     to the beginning of the output.  */
+  inend -= oplen;
+  bcopy (&inexpr->elts[inend], &outexpr->elts[outbeg],
+        oplen * sizeof (union exp_element));
+  outbeg += oplen;
+
+  /* Find the lengths of the arg subexpressions.  */
+  arglens = (int *) alloca (args * sizeof (int));
+  for (i = args - 1; i >= 0; i--)
+    {
+      oplen = length_of_subexp (inexpr, inend);
+      arglens[i] = oplen;
+      inend -= oplen;
+    }
+
+  /* Now copy each subexpression, preserving the order of
+     the subexpressions, but prefixifying each one.
+     In this loop, inend starts at the beginning of
+     the expression this level is working on
+     and marches forward over the arguments.
+     outbeg does similarly in the output.  */
+  for (i = 0; i < args; i++)
+    {
+      oplen = arglens[i];
+      inend += oplen;
+      prefixify_subexp (inexpr, outexpr, inend, outbeg);
+      outbeg += oplen;
+    }
+}
+\f
+/* This page contains the two entry points to this file.  */
+
+/* Read a C expression from the string *STRINGPTR points to,
+   parse it, and return a pointer to a  struct expression  that we malloc.
+   Use block BLOCK as the lexical context for variable names;
+   if BLOCK is zero, use the block of the selected stack frame.
+   Meanwhile, advance *STRINGPTR to point after the expression,
+   at the first nonwhite character that is not part of the expression
+   (possibly a null character).
+
+   If COMMA is nonzero, stop if a comma is reached.  */
+
+struct expression *
+parse_c_1 (stringptr, block, comma)
+     char **stringptr;
+     struct block *block;
+     int comma;
+{
+  struct cleanup *old_chain;
+
+  lexptr = *stringptr;
+
+  paren_depth = 0;
+  type_stack_depth = 0;
+
+  comma_terminates = comma;
+
+  if (lexptr == 0 || *lexptr == 0)
+    error_no_arg ("expression to compute");
+
+  old_chain = make_cleanup (free_funcalls, 0);
+  funcall_chain = 0;
+
+  expression_context_block = block ? block : get_selected_block ();
+
+  namecopy = (char *) alloca (strlen (lexptr) + 1);
+  expout_size = 10;
+  expout_ptr = 0;
+  expout = (struct expression *)
+    xmalloc (sizeof (struct expression)
+            + expout_size * sizeof (union exp_element));
+  make_cleanup (free_current_contents, &expout);
+  if (yyparse ())
+    yyerror (NULL);
+  discard_cleanups (old_chain);
+  expout->nelts = expout_ptr;
+  expout = (struct expression *)
+    xrealloc (expout,
+             sizeof (struct expression)
+             + expout_ptr * sizeof (union exp_element));
+  prefixify_expression (expout);
+  *stringptr = lexptr;
+  return expout;
+}
+
+/* Parse STRING as an expression, and complain if this fails
+   to use up all of the contents of STRING.  */
+
+struct expression *
+parse_c_expression (string)
+     char *string;
+{
+  register struct expression *exp;
+  exp = parse_c_1 (&string, 0, 0);
+  if (*string)
+    error ("Junk after end of expression.");
+  return exp;
+}
+
+static void 
+push_type (tp)
+     enum type_pieces tp;
+{
+  if (type_stack_depth == type_stack_size)
+    {
+      type_stack_size *= 2;
+      type_stack = (enum type_pieces *)
+       xrealloc (type_stack, type_stack_size * sizeof (enum type_pieces));
+    }
+  type_stack[type_stack_depth++] = tp;
+}
+
+static enum type_pieces 
+pop_type ()
+{
+  if (type_stack_depth)
+    return type_stack[--type_stack_depth];
+  return tp_end;
+}
+
+void
+_initialize_expread ()
+{
+  type_stack_size = 80;
+  type_stack_depth = 0;
+  type_stack = (enum type_pieces *)
+    xmalloc (type_stack_size * sizeof (enum type_pieces));
+}
diff --git a/gdb/getpagesize.h b/gdb/getpagesize.h
new file mode 100755 (executable)
index 0000000..32adae6
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BSD
+#ifndef BSD4_1
+#define HAVE_GETPAGESIZE
+#endif
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+
+#include <sys/param.h>
+
+#ifdef EXEC_PAGESIZE
+#define getpagesize() EXEC_PAGESIZE
+#else
+#ifdef NBPG
+#define getpagesize() NBPG * CLSIZE
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* no CLSIZE */
+#else /* no NBPG */
+#define getpagesize() NBPC
+#endif /* no NBPG */
+#endif /* no EXEC_PAGESIZE */
+
+#endif /* not HAVE_GETPAGESIZE */
+
diff --git a/gdb/gmalloc.c b/gdb/gmalloc.c
new file mode 100755 (executable)
index 0000000..0468551
--- /dev/null
@@ -0,0 +1,1116 @@
+
+/* gmalloc.c - THIS FILE IS AUTOMAGICALLY GENERATED SO DON'T EDIT IT. */
+
+/* Single-file skeleton for GNU malloc.
+   Copyright 1989 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#define __ONEFILE
+
+/* DO NOT DELETE THIS LINE -- ansidecl.h INSERTED HERE. */
+/* Copyright (C) 1989 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the GNU C Library; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+       Macros
+               PTR             - Generic pointer type
+               LONG_DOUBLE     - `long double' type
+               CONST           - `const' keyword
+               VOLATILE        - `volatile' keyword
+               SIGNED          - `signed' keyword
+               PTRCONST        - Generic const pointer (void *const)
+
+       EXFUN(name, prototype)          - declare external function NAME
+                                         with prototype PROTOTYPE
+       DEFUN(name, arglist, args)      - define function NAME with
+                                         args ARGLIST of types in ARGS
+       DEFUN_VOID(name)                - define function NAME with no args
+       AND                             - argument separator for ARGS
+       NOARGS                          - null arglist
+       DOTS                            - `...' in args
+
+    For example:
+       extern int EXFUN(printf, (CONST char *format DOTS));
+       int DEFUN(fprintf, (stream, format),
+                 FILE *stream AND CONST char *format DOTS) { ... }
+       void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef        _ANSIDECL_H
+
+#define        _ANSIDECL_H     1
+
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+
+#ifdef __STDC__
+
+#define        PTR             void *
+#define        PTRCONST        void *CONST
+#define        LONG_DOUBLE     long double
+
+#define        AND             ,
+#define        NOARGS          void
+#define        CONST           const
+#define        VOLATILE        volatile
+#define        SIGNED          signed
+#define        DOTS            , ...
+
+#define        EXFUN(name, proto)              name proto
+#define        DEFUN(name, arglist, args)      name(args)
+#define        DEFUN_VOID(name)                name(NOARGS)
+
+#else  /* Not ANSI C.  */
+
+#define        PTR             char *
+#define        PTRCONST        PTR
+#define        LONG_DOUBLE     double
+
+#define        AND             ;
+#define        NOARGS
+#define        CONST
+#define        VOLATILE
+#define        SIGNED
+#define        DOTS
+
+#define        EXFUN(name, proto)              name()
+#define        DEFUN(name, arglist, args)      name arglist args;
+#define        DEFUN_VOID(name)                name()
+
+#endif /* ANSI C.  */
+
+
+#endif /* ansidecl.h   */
+
+#ifdef __STDC__
+#include <limits.h>
+#else
+/* DO NOT DELETE THIS LINE -- limits.h INSERTED HERE. */
+/* Number of bits in a `char'.  */
+#define CHAR_BIT 8
+
+/* No multibyte characters supported yet.  */
+#define MB_LEN_MAX 1
+
+/* Minimum and maximum values a `signed char' can hold.  */
+#define SCHAR_MIN -128
+#define SCHAR_MAX 127
+
+/* Maximum value an `unsigned char' can hold.  (Minimum is 0).  */
+#define UCHAR_MAX 255U
+
+/* Minimum and maximum values a `char' can hold.  */
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN 0
+#define CHAR_MAX 255U
+#else
+#define CHAR_MIN -128
+#define CHAR_MAX 127
+#endif
+
+/* Minimum and maximum values a `signed short int' can hold.  */
+#define SHRT_MIN -32768
+#define SHRT_MAX 32767
+
+/* Maximum value an `unsigned short int' can hold.  (Minimum is 0).  */
+#define USHRT_MAX 65535U
+
+/* Minimum and maximum values a `signed int' can hold.  */
+#define INT_MIN -2147483648
+#define INT_MAX 2147483647
+
+/* Maximum value an `unsigned int' can hold.  (Minimum is 0).  */
+#define UINT_MAX 4294967295U
+
+/* Minimum and maximum values a `signed long int' can hold.
+   (Same as `int').  */
+#define LONG_MIN (-LONG_MAX-1)
+#define LONG_MAX 2147483647
+
+/* Maximum value an `unsigned long int' can hold.  (Minimum is 0).  */
+#define ULONG_MAX 4294967295U
+#endif
+
+#ifdef __STDC__
+#include <stddef.h>
+#else
+/* DO NOT DELETE THIS LINE -- stddef.h INSERTED HERE. */
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+/* Signed type of difference of two pointers.  */
+
+typedef long ptrdiff_t;
+
+/* Unsigned type of `sizeof' something.  */
+
+#ifndef _SIZE_T        /* in case <sys/types.h> has defined it. */
+#define _SIZE_T
+typedef unsigned long size_t;
+#endif /* _SIZE_T */
+
+/* A null pointer constant.  */
+
+#undef NULL            /* in case <stdio.h> has defined it. */
+#define NULL 0
+
+/* Offset of member MEMBER in a struct of type TYPE.  */
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif /* _STDDEF_H */
+#endif
+
+/* DO NOT DELETE THIS LINE -- stdlib.h INSERTED HERE. */
+/* Fake stdlib.h supplying the stuff needed by malloc. */
+
+#ifndef __ONEFILE
+#include <stddef.h>
+#endif
+
+extern void EXFUN(abort, (void));
+extern void EXFUN(free, (PTR));
+extern PTR EXFUN(malloc, (size_t));
+extern PTR EXFUN(realloc, (PTR, size_t));
+
+/* DO NOT DELETE THIS LINE -- string.h INSERTED HERE. */
+/* Fake string.h supplying stuff used by malloc. */
+#ifndef __ONEFILE
+#include <stddef.h>
+#endif
+
+extern PTR EXFUN(memcpy, (PTR, PTR, size_t));
+extern PTR EXFUN(memset, (PTR, int, size_t));
+#define memmove memcpy
+
+#define _MALLOC_INTERNAL
+/* DO NOT DELETE THIS LINE -- malloc.h INSERTED HERE. */
+/* Declarations for `malloc' and friends.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef _MALLOC_H
+
+#define _MALLOC_H      1
+
+#ifndef __ONEFILE
+#define        __need_NULL
+#define        __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+#endif
+
+#ifdef _MALLOC_INTERNAL
+
+#ifndef __ONEFILE
+#include <limits.h>
+#endif
+
+/* The allocator divides the heap into blocks of fixed size; large
+   requests receive one or more whole blocks, and small requests
+   receive a fragment of a block.  Fragment sizes are powers of two,
+   and all fragments of a block are the same size.  When all the
+   fragments in a block have been freed, the block itself is freed.  */
+#define INT_BIT                (CHAR_BIT * sizeof(int))
+#define BLOCKLOG       (INT_BIT > 16 ? 12 : 9)
+#define BLOCKSIZE      (1 << BLOCKLOG)
+#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
+
+/* Determine the amount of memory spanned by the initial heap table
+   (not an absolute limit).  */
+#define HEAP           (INT_BIT > 16 ? 4194304 : 65536)
+
+/* Number of contiguous free blocks allowed to build up at the end of
+   memory before they will be returned to the system.  */
+#define FINAL_FREE_BLOCKS      8
+
+/* Where to start searching the free list when looking for new memory.
+   The two possible values are 0 and _heapindex.  Starting at 0 seems
+   to reduce total memory usage, while starting at _heapindex seems to
+   run faster.  */
+#define MALLOC_SEARCH_START    _heapindex
+
+/* Data structure giving per-block information.  */
+typedef union
+  {
+    /* Heap information for a busy block.  */
+    struct
+      {
+       /* Zero for a large block, or positive giving the
+          logarithm to the base two of the fragment size.  */
+       int type;
+       union
+         {
+           struct
+             {
+               size_t nfree;   /* Free fragments in a fragmented block.  */
+               size_t first;   /* First free fragment of the block.  */
+             } frag;
+           /* Size (in blocks) of a large cluster.  */
+           size_t size;
+         } info;
+      } busy;
+    /* Heap information for a free block (that may be the first of
+       a free cluster).  */
+    struct
+      {
+       size_t size;            /* Size (in blocks) of a free cluster.  */
+       size_t next;            /* Index of next free cluster.  */
+       size_t prev;            /* Index of previous free cluster.  */
+      } free;
+  } malloc_info;
+
+/* Pointer to first block of the heap.  */
+extern char *_heapbase;
+
+/* Table indexed by block number giving per-block information.  */
+extern malloc_info *_heapinfo;
+
+/* Address to block number and vice versa.  */
+#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
+#define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
+
+/* Current search index for the heap table.  */
+extern size_t _heapindex;
+
+/* Limit of valid info table indices.  */
+extern size_t _heaplimit;
+
+/* Doubly linked lists of free fragments.  */
+struct list
+  {
+    struct list *next;
+    struct list *prev;
+  };
+
+/* Free list headers for each fragment size.  */
+extern struct list _fraghead[];
+
+/* Instrumentation.  */
+extern size_t _chunks_used;
+extern size_t _bytes_used;
+extern size_t _chunks_free;
+extern size_t _bytes_free;
+
+/* Internal version of free() used in morecore(). */
+extern void EXFUN(__free, (PTR __ptr));
+
+#endif  /* _MALLOC_INTERNAL.  */
+
+/* Underlying allocation function; successive calls should
+   return contiguous pieces of memory.  */
+extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
+
+/* Default value of previous.  */
+extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
+
+/* Flag whether malloc has been called.  */
+extern int __malloc_initialized;
+
+/* Hooks for debugging versions.  */
+extern void EXFUN((*__free_hook), (PTR __ptr));
+extern PTR EXFUN((*__malloc_hook), (size_t __size));
+extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
+
+/* Activate a standard collection of debugging hooks.  */
+extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
+
+/* Statistics available to the user.  */
+struct mstats
+  {
+    size_t bytes_total;                /* Total size of the heap. */
+    size_t chunks_used;                /* Chunks allocated by the user. */
+    size_t bytes_used;         /* Byte total of user-allocated chunks. */
+    size_t chunks_free;                /* Chunks in the free list. */
+    size_t bytes_free;         /* Byte total of chunks in the free list. */
+  };
+
+/* Pick up the current statistics. */
+extern struct mstats EXFUN(mstats, (NOARGS));
+
+#endif /* malloc.h  */
+
+/* DO NOT DELETE THIS LINE -- free.c INSERTED HERE. */
+/* Free a block of memory allocated by `malloc'.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef __ONEFILE
+#include "ansidecl.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+#define _MALLOC_INTERNAL
+#include "malloc.h"
+#endif /* __ONEFILE */
+
+/* Debugging hook for free.  */
+void EXFUN((*__free_hook), (PTR __ptr));
+
+/* Return memory to the heap.  Like free() but don't call a __free_hook
+   if there is one.  */
+void
+DEFUN(__free, (ptr), PTR ptr)
+{
+  int type;
+  size_t block, blocks;
+  register size_t i;
+  struct list *prev, *next;
+
+  block = BLOCK(ptr);
+
+  type = _heapinfo[block].busy.type;
+  switch (type)
+    {
+    case 0:
+      /* Get as many statistics as early as we can.  */
+      --_chunks_used;
+      _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
+      _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
+
+      /* Find the free cluster previous to this one in the free list.
+        Start searching at the last block referenced; this may benefit
+        programs with locality of allocation.  */
+      i = _heapindex;
+      if (i > block)
+       while (i > block)
+         i = _heapinfo[i].free.prev;
+      else
+       {
+         do
+           i = _heapinfo[i].free.next;
+         while (i > 0 && i < block);
+         i = _heapinfo[i].free.prev;
+       }
+
+      /* Determine how to link this block into the free list.  */
+      if (block == i + _heapinfo[i].free.size)
+       {
+         /* Coalesce this block with its predecessor.  */
+         _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
+         block = i;
+       }
+      else
+       {
+         /* Really link this block back into the free list.  */
+         _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
+         _heapinfo[block].free.next = _heapinfo[i].free.next;
+         _heapinfo[block].free.prev = i;
+         _heapinfo[i].free.next = block;
+         _heapinfo[_heapinfo[block].free.next].free.prev = block;
+         ++_chunks_free;
+       }
+
+      /* Now that the block is linked in, see if we can coalesce it
+        with its successor (by deleting its successor from the list
+        and adding in its size).  */
+      if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
+       {
+         _heapinfo[block].free.size
+           += _heapinfo[_heapinfo[block].free.next].free.size;
+         _heapinfo[block].free.next
+           = _heapinfo[_heapinfo[block].free.next].free.next;
+         _heapinfo[_heapinfo[block].free.next].free.prev = block;
+         --_chunks_free;
+       }
+
+      /* Now see if we can return stuff to the system.  */
+      blocks = _heapinfo[block].free.size;
+      if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
+         && (*__morecore)(0) == ADDRESS(block + blocks))
+       {
+         register size_t bytes = blocks * BLOCKSIZE;
+         _heaplimit -= blocks;
+         (*__morecore)(- bytes);
+         _heapinfo[_heapinfo[block].free.prev].free.next
+           = _heapinfo[block].free.next;
+         _heapinfo[_heapinfo[block].free.next].free.prev
+           = _heapinfo[block].free.prev;
+         block = _heapinfo[block].free.prev;
+         --_chunks_free;
+         _bytes_free -= bytes;
+       }
+
+      /* Set the next search to begin at this block.  */
+      _heapindex = block;
+      break;
+
+    default:
+      /* Do some of the statistics.  */
+      --_chunks_used;
+      _bytes_used -= 1 << type;
+      ++_chunks_free;
+      _bytes_free += 1 << type;
+
+      /* Get the address of the first free fragment in this block.  */
+      prev = (struct list *) ((char *) ADDRESS(block) +
+                             (_heapinfo[block].busy.info.frag.first << type));
+
+      if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
+       {
+         /* If all fragments of this block are free, remove them
+            from the fragment list and free the whole block.  */
+         next = prev;
+         for (i = 1; i < BLOCKSIZE >> type; ++i)
+           next = next->next;
+         prev->prev->next = next;
+         if (next != NULL)
+           next->prev = prev->prev;
+         _heapinfo[block].busy.type = 0;
+         _heapinfo[block].busy.info.size = 1;
+
+         /* Keep the statistics accurate.  */
+         ++_chunks_used;
+         _bytes_used += BLOCKSIZE;
+         _chunks_free -= BLOCKSIZE >> type;
+         _bytes_free -= BLOCKSIZE;
+
+         free(ADDRESS(block));
+       }
+      else if (_heapinfo[block].busy.info.frag.nfree != 0)
+       {
+         /* If some fragments of this block are free, link this
+            fragment into the fragment list after the first free
+            fragment of this block. */
+         next = (struct list *) ptr;
+         next->next = prev->next;
+         next->prev = prev;
+         prev->next = next;
+         if (next->next != NULL)
+           next->next->prev = next;
+         ++_heapinfo[block].busy.info.frag.nfree;
+       }
+      else
+       {
+         /* No fragments of this block are free, so link this
+            fragment into the fragment list and announce that
+            it is the first free fragment of this block. */
+         prev = (struct list *) ptr;
+         _heapinfo[block].busy.info.frag.nfree = 1;
+         _heapinfo[block].busy.info.frag.first = (unsigned int)
+           (((char *) ptr - (char *) NULL) % BLOCKSIZE >> type);
+         prev->next = _fraghead[type].next;
+         prev->prev = &_fraghead[type];
+         prev->prev->next = prev;
+         if (prev->next != NULL)
+           prev->next->prev = prev;
+       }
+      break;
+    }
+}
+
+/* Return memory to the heap.  */
+void
+DEFUN(free, (ptr), PTR ptr)
+{
+  if (ptr == NULL)
+    return;
+
+  if (__free_hook != NULL)
+    (*__free_hook)(ptr);
+  else
+    __free (ptr);
+}
+
+/* DO NOT DELETE THIS LINE -- malloc.c INSERTED HERE. */
+/* Memory allocator `malloc'.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef __ONEFILE
+#include "ansidecl.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define _MALLOC_INTERNAL
+#include "malloc.h"
+#endif /* __ONEFILE */
+
+/* How to really get more memory.  */
+PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
+
+/* Debugging hook for `malloc'.  */
+PTR EXFUN((*__malloc_hook), (size_t __size));
+
+/* Pointer to the base of the first block.  */
+char *_heapbase;
+
+/* Block information table.  Allocated with align/__free (not malloc/free).  */
+malloc_info *_heapinfo;
+
+/* Number of info entries.  */
+static size_t heapsize;
+
+/* Search index in the info table.  */
+size_t _heapindex;
+
+/* Limit of valid info table indices.  */
+size_t _heaplimit;
+
+/* Free lists for each fragment size.  */
+struct list _fraghead[BLOCKLOG];
+
+/* Instrumentation.  */
+size_t _chunks_used;
+size_t _bytes_used;
+size_t _chunks_free;
+size_t _bytes_free;
+
+/* Are you experienced?  */
+int __malloc_initialized;
+
+/* Aligned allocation.  */
+static PTR
+DEFUN(align, (size), size_t size)
+{
+  PTR result;
+  unsigned int adj;
+
+  result = (*__morecore)(size);
+  adj = (unsigned int) ((char *) result - (char *) NULL) % BLOCKSIZE;
+  if (adj != 0)
+    {
+      adj = BLOCKSIZE - adj;
+      (void) (*__morecore)(adj);
+      result = (char *) result + adj;
+    }
+  return result;
+}
+
+/* Set everything up and remember that we have.  */
+static int
+DEFUN_VOID(initialize)
+{
+  heapsize = HEAP / BLOCKSIZE;
+  _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info));
+  if (_heapinfo == NULL)
+    return 0;
+  memset(_heapinfo, 0, heapsize * sizeof(malloc_info));
+  _heapinfo[0].free.size = 0;
+  _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
+  _heapindex = 0;
+  _heapbase = (char *) _heapinfo;
+  __malloc_initialized = 1;
+  return 1;
+}
+
+/* Get neatly aligned memory, initializing or
+   growing the heap info table as necessary. */
+static PTR
+DEFUN(morecore, (size), size_t size)
+{
+  PTR result;
+  malloc_info *newinfo, *oldinfo;
+  size_t newsize;
+
+  result = align(size);
+  if (result == NULL)
+    return NULL;
+
+  /* Check if we need to grow the info table.  */
+  if (BLOCK((char *) result + size) > heapsize)
+    {
+      newsize = heapsize;
+      while (BLOCK((char *) result + size) > newsize)
+       newsize *= 2;
+      newinfo = (malloc_info *) align(newsize * sizeof(malloc_info));
+      if (newinfo == NULL)
+       {
+         (*__morecore)(- size);
+         return NULL;
+       }
+      memset(newinfo, 0, newsize * sizeof(malloc_info));
+      memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info));
+      oldinfo = _heapinfo;
+      newinfo[BLOCK(oldinfo)].busy.type = 0;
+      newinfo[BLOCK(oldinfo)].busy.info.size
+       = BLOCKIFY(heapsize * sizeof(malloc_info));
+      _heapinfo = newinfo;
+      __free(oldinfo);
+      heapsize = newsize;
+    }
+
+  _heaplimit = BLOCK((char *) result + size);
+  return result;
+}
+
+/* Allocate memory from the heap.  */
+PTR
+DEFUN(malloc, (size), size_t size)
+{
+  PTR result;
+  size_t block, blocks, lastblocks, start;
+  register size_t i;
+  struct list *next;
+
+  if (size == 0)
+    return NULL;
+
+  if (__malloc_hook != NULL)
+    return (*__malloc_hook)(size);
+
+  if (!__malloc_initialized)
+    if (!initialize())
+      return NULL;
+
+  if (size < sizeof(struct list))
+    size = sizeof(struct list);
+
+  /* Determine the allocation policy based on the request size.  */
+  if (size <= BLOCKSIZE / 2)
+    {
+      /* Small allocation to receive a fragment of a block.
+        Determine the logarithm to base two of the fragment size. */
+      register size_t log = 1;
+      --size;
+      while ((size /= 2) != 0)
+       ++log;
+
+      /* Look in the fragment lists for a
+        free fragment of the desired size. */
+      next = _fraghead[log].next;
+      if (next != NULL)
+       {
+         /* There are free fragments of this size.
+            Pop a fragment out of the fragment list and return it.
+            Update the block's nfree and first counters. */
+         result = (PTR) next;
+         next->prev->next = next->next;
+         if (next->next != NULL)
+           next->next->prev = next->prev;
+         block = BLOCK(result);
+         if (--_heapinfo[block].busy.info.frag.nfree != 0)
+           _heapinfo[block].busy.info.frag.first = (unsigned int)
+             (((char *) next->next - (char *) NULL) % BLOCKSIZE) >> log;
+
+         /* Update the statistics.  */
+         ++_chunks_used;
+         _bytes_used += 1 << log;
+         --_chunks_free;
+         _bytes_free -= 1 << log;
+       }
+      else
+       {
+         /* No free fragments of the desired size, so get a new block
+            and break it into fragments, returning the first.  */
+         result = malloc(BLOCKSIZE);
+         if (result == NULL)
+           return NULL;
+
+         /* Link all fragments but the first into the free list.  */
+         for (i = 1; i < BLOCKSIZE >> log; ++i)
+           {
+             next = (struct list *) ((char *) result + (i << log));
+             next->next = _fraghead[log].next;
+             next->prev = &_fraghead[log];
+             next->prev->next = next;
+             if (next->next != NULL)
+               next->next->prev = next;
+           }
+
+         /* Initialize the nfree and first counters for this block.  */
+         block = BLOCK(result);
+         _heapinfo[block].busy.type = log;
+         _heapinfo[block].busy.info.frag.nfree = i - 1;
+         _heapinfo[block].busy.info.frag.first = i - 1;
+
+         _chunks_free += (BLOCKSIZE >> log) - 1;
+         _bytes_free += BLOCKSIZE - (1 << log);
+       }
+    }
+  else
+    {
+      /* Large allocation to receive one or more blocks.
+        Search the free list in a circle starting at the last place visited.
+        If we loop completely around without finding a large enough
+        space we will have to get more memory from the system.  */
+      blocks = BLOCKIFY(size);
+      start = block = MALLOC_SEARCH_START;
+      while (_heapinfo[block].free.size < blocks)
+       {
+         block = _heapinfo[block].free.next;
+         if (block == start)
+           {
+             /* Need to get more from the system.  Check to see if
+                the new core will be contiguous with the final free
+                block; if so we don't need to get as much.  */
+             block = _heapinfo[0].free.prev;
+             lastblocks = _heapinfo[block].free.size;
+             if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
+                 (*__morecore)(0) == ADDRESS(block + lastblocks) &&
+                 (morecore((blocks - lastblocks) * BLOCKSIZE)) != NULL)
+               {
+                 _heapinfo[block].free.size = blocks;
+                 _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
+                 continue;
+               }
+             result = morecore(blocks * BLOCKSIZE);
+             if (result == NULL)
+               return NULL;
+             block = BLOCK(result);
+             _heapinfo[block].busy.type = 0;
+             _heapinfo[block].busy.info.size = blocks;
+             ++_chunks_used;
+             _bytes_used += blocks * BLOCKSIZE;
+             return result;
+           }
+       }
+
+      /* At this point we have found a suitable free list entry.
+        Figure out how to remove what we need from the list. */
+      result = ADDRESS(block);
+      if (_heapinfo[block].free.size > blocks)
+       {
+         /* The block we found has a bit left over,
+            so relink the tail end back into the free list. */
+         _heapinfo[block + blocks].free.size
+           = _heapinfo[block].free.size - blocks;
+         _heapinfo[block + blocks].free.next
+           = _heapinfo[block].free.next;
+         _heapinfo[block + blocks].free.prev
+           = _heapinfo[block].free.prev;
+         _heapinfo[_heapinfo[block].free.prev].free.next
+           = _heapinfo[_heapinfo[block].free.next].free.prev
+             = _heapindex = block + blocks;
+       }
+      else
+       {
+         /* The block exactly matches our requirements,
+            so just remove it from the list. */
+         _heapinfo[_heapinfo[block].free.next].free.prev
+           = _heapinfo[block].free.prev;
+         _heapinfo[_heapinfo[block].free.prev].free.next
+           = _heapindex = _heapinfo[block].free.next;
+         --_chunks_free;
+       }
+
+      _heapinfo[block].busy.type = 0;
+      _heapinfo[block].busy.info.size = blocks;
+      ++_chunks_used;
+      _bytes_used += blocks * BLOCKSIZE;
+      _bytes_free -= blocks * BLOCKSIZE;
+    }
+
+  return result;
+}
+
+/* DO NOT DELETE THIS LINE -- realloc.c INSERTED HERE. */
+/* Change the size of a block allocated by `malloc'.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef __ONEFILE
+#include "ansidecl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define _MALLOC_INTERNAL
+#include "malloc.h"
+#endif /* __ONEFILE */
+
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+
+/* Debugging hook for realloc.  */
+PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
+
+/* Resize the given region to the new size, returning a pointer
+   to the (possibly moved) region.  This is optimized for speed;
+   some benchmarks seem to indicate that greater compactness is
+   achieved by unconditionally allocating and copying to a
+   new region.  This module has incestuous knowledge of the
+   internals of both free and malloc. */
+PTR
+DEFUN(realloc, (ptr, size), PTR ptr AND size_t size)
+{
+  PTR result;
+  int type;
+  size_t block, blocks, oldlimit;
+
+  if (size == 0)
+    {
+      free(ptr);
+      return NULL;
+    }
+  else if (ptr == NULL)
+    return malloc(size);
+
+  if (__realloc_hook != NULL)
+    return (*__realloc_hook)(ptr, size);
+
+  block = BLOCK(ptr);
+
+  type = _heapinfo[block].busy.type;
+  switch (type)
+    {
+    case 0:
+      /* Maybe reallocate a large block to a small fragment.  */
+      if (size <= BLOCKSIZE / 2)
+       {
+         result = malloc(size);
+         if (result != NULL)
+           {
+             memcpy(result, ptr, size);
+             free(ptr);
+             return result;
+           }
+       }
+
+      /* The new size is a large allocation as well;
+        see if we can hold it in place. */
+      blocks = BLOCKIFY(size);
+      if (blocks < _heapinfo[block].busy.info.size)
+       {
+         /* The new size is smaller; return
+            excess memory to the free list. */
+         _heapinfo[block + blocks].busy.type = 0;
+         _heapinfo[block + blocks].busy.info.size
+           = _heapinfo[block].busy.info.size - blocks;
+         _heapinfo[block].busy.info.size = blocks;
+         free(ADDRESS(block + blocks));
+         result = ptr;
+       }
+      else if (blocks == _heapinfo[block].busy.info.size)
+       /* No size change necessary.  */
+       result = ptr;
+      else
+       {
+         /* Won't fit, so allocate a new region that will.
+            Free the old region first in case there is sufficient
+            adjacent free space to grow without moving. */
+         blocks = _heapinfo[block].busy.info.size;
+         /* Prevent free from actually returning memory to the system.  */
+         oldlimit = _heaplimit;
+         _heaplimit = 0;
+         free(ptr);
+         _heaplimit = oldlimit;
+         result = malloc(size);
+         if (result == NULL)
+           {
+             (void) malloc(blocks * BLOCKSIZE);
+             return NULL;
+           }
+         if (ptr != result)
+           memmove(result, ptr, blocks * BLOCKSIZE);
+       }
+      break;
+
+    default:
+      /* Old size is a fragment; type is logarithm
+        to base two of the fragment size.  */
+      if (size > 1 << (type - 1) && size <= 1 << type)
+       /* The new size is the same kind of fragment.  */
+       result = ptr;
+      else
+       {
+         /* The new size is different; allocate a new space,
+            and copy the lesser of the new size and the old. */
+         result = malloc(size);
+         if (result == NULL)
+           return NULL;
+         memcpy(result, ptr, MIN(size, 1 << type));
+         free(ptr);
+       }
+      break;
+    }
+
+  return result;
+}
+
+/* DO NOT DELETE THIS LINE -- unix.c INSERTED HERE. */
+/* unix.c - get more memory with a UNIX system call.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef __ONEFILE
+#include "ansidecl.h"
+#include <stddef.h>
+
+#define _MALLOC_INTERNAL
+#include "malloc.h"
+#endif /* __ONEFILE */
+
+extern PTR EXFUN(sbrk, (ptrdiff_t size));
+
+PTR
+DEFUN(__default_morecore, (size), ptrdiff_t size)
+{
+  PTR result;
+
+  result = sbrk(size);
+  if (result == (PTR) -1)
+    return NULL;
+  return result;
+}
+
+#define __getpagesize getpagesize
+/* DO NOT DELETE THIS LINE -- valloc.c INSERTED HERE. */
+/* Allocate memory on a page boundary.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef __ONEFILE
+#include "ansidecl.h"
+#include <stdlib.h>
+#endif /* __ONEFILE */
+
+extern size_t EXFUN(__getpagesize, (NOARGS));
+
+static size_t pagesize;
+
+PTR
+DEFUN(valloc, (size), size_t size)
+{
+  PTR result;
+  unsigned int adj;
+
+  if (pagesize == 0)
+    pagesize = __getpagesize();
+
+  result = malloc(size + pagesize);
+  if (result == NULL)
+    return NULL;
+  adj = (unsigned int) ((char *) result - (char *) NULL) % pagesize;
+  if (adj != 0)
+    result = (char *) result + pagesize - adj;
+  return result;
+}
diff --git a/gdb/gmalloc.h b/gdb/gmalloc.h
new file mode 100755 (executable)
index 0000000..8718e80
--- /dev/null
@@ -0,0 +1,161 @@
+/* Declarations for `malloc' and friends.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef _MALLOC_H
+
+#define _MALLOC_H      1
+
+#ifndef __ONEFILE
+#define        __need_NULL
+#define        __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+#endif
+
+#ifdef _MALLOC_INTERNAL
+
+#ifndef __ONEFILE
+#include <limits.h>
+#endif
+
+/* The allocator divides the heap into blocks of fixed size; large
+   requests receive one or more whole blocks, and small requests
+   receive a fragment of a block.  Fragment sizes are powers of two,
+   and all fragments of a block are the same size.  When all the
+   fragments in a block have been freed, the block itself is freed.  */
+#define INT_BIT                (CHAR_BIT * sizeof(int))
+#define BLOCKLOG       (INT_BIT > 16 ? 12 : 9)
+#define BLOCKSIZE      (1 << BLOCKLOG)
+#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
+
+/* Determine the amount of memory spanned by the initial heap table
+   (not an absolute limit).  */
+#define HEAP           (INT_BIT > 16 ? 4194304 : 65536)
+
+/* Number of contiguous free blocks allowed to build up at the end of
+   memory before they will be returned to the system.  */
+#define FINAL_FREE_BLOCKS      8
+
+/* Where to start searching the free list when looking for new memory.
+   The two possible values are 0 and _heapindex.  Starting at 0 seems
+   to reduce total memory usage, while starting at _heapindex seems to
+   run faster.  */
+#define MALLOC_SEARCH_START    _heapindex
+
+/* Data structure giving per-block information.  */
+typedef union
+  {
+    /* Heap information for a busy block.  */
+    struct
+      {
+       /* Zero for a large block, or positive giving the
+          logarithm to the base two of the fragment size.  */
+       int type;
+       union
+         {
+           struct
+             {
+               size_t nfree;   /* Free fragments in a fragmented block.  */
+               size_t first;   /* First free fragment of the block.  */
+             } frag;
+           /* Size (in blocks) of a large cluster.  */
+           size_t size;
+         } info;
+      } busy;
+    /* Heap information for a free block (that may be the first of
+       a free cluster).  */
+    struct
+      {
+       size_t size;            /* Size (in blocks) of a free cluster.  */
+       size_t next;            /* Index of next free cluster.  */
+       size_t prev;            /* Index of previous free cluster.  */
+      } free;
+  } malloc_info;
+
+/* Pointer to first block of the heap.  */
+extern char *_heapbase;
+
+/* Table indexed by block number giving per-block information.  */
+extern malloc_info *_heapinfo;
+
+/* Address to block number and vice versa.  */
+#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
+#define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
+
+/* Current search index for the heap table.  */
+extern size_t _heapindex;
+
+/* Limit of valid info table indices.  */
+extern size_t _heaplimit;
+
+/* Doubly linked lists of free fragments.  */
+struct list
+  {
+    struct list *next;
+    struct list *prev;
+  };
+
+/* Free list headers for each fragment size.  */
+extern struct list _fraghead[];
+
+/* Instrumentation.  */
+extern size_t _chunks_used;
+extern size_t _bytes_used;
+extern size_t _chunks_free;
+extern size_t _bytes_free;
+
+/* Internal version of free() used in morecore(). */
+extern void EXFUN(__free, (PTR __ptr));
+
+#endif  /* _MALLOC_INTERNAL.  */
+
+/* Underlying allocation function; successive calls should
+   return contiguous pieces of memory.  */
+extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
+
+/* Default value of previous.  */
+extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
+
+/* Flag whether malloc has been called.  */
+extern int __malloc_initialized;
+
+/* Hooks for debugging versions.  */
+extern void EXFUN((*__free_hook), (PTR __ptr));
+extern PTR EXFUN((*__malloc_hook), (size_t __size));
+extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
+
+/* Activate a standard collection of debugging hooks.  */
+extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
+
+/* Statistics available to the user.  */
+struct mstats
+  {
+    size_t bytes_total;                /* Total size of the heap. */
+    size_t chunks_used;                /* Chunks allocated by the user. */
+    size_t bytes_used;         /* Byte total of user-allocated chunks. */
+    size_t chunks_free;                /* Chunks in the free list. */
+    size_t bytes_free;         /* Byte total of chunks in the free list. */
+  };
+
+/* Pick up the current statistics. */
+extern struct mstats EXFUN(mstats, (NOARGS));
+
+#endif /* malloc.h  */
diff --git a/gdb/gould-pinsn.c b/gdb/gould-pinsn.c
new file mode 100644 (file)
index 0000000..b655f26
--- /dev/null
@@ -0,0 +1,294 @@
+/* Print GOULD RISC instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "gdbcore.h"
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+#if defined GOULD_PN
+#include "pn-opcode.h"
+#else
+#include "np1-opcode.h"
+#endif
+
+/* GOULD RISC instructions are never longer than this many bytes.  */
+#define MAXLEN 4
+
+/* Number of elements in the opcode table.  */
+#define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
+
+\f
+/* Print the GOULD instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+       CORE_ADDR memaddr;
+       FILE *stream;
+{
+       unsigned char buffer[MAXLEN];
+       register int i;
+       register char *d;
+       register int bestmask;
+       unsigned best;
+       int temp, index, bestlen;
+
+       read_memory (memaddr, buffer, MAXLEN);
+
+       bestmask = 0;
+       index = -1;
+       best = 0xffffffff;
+       for (i = 0; i < NOPCODES; i++)
+       {
+               register unsigned int opcode = gld_opcodes[i].opcode;
+               register unsigned int mask = gld_opcodes[i].mask;
+               register unsigned int len = gld_opcodes[i].length;
+               register unsigned int test;
+
+               /* Get possible opcode bytes into integer */
+               test = buffer[0] << 24;
+               test |= buffer[1] << 16;
+               test |= buffer[2] << 8;
+               test |= buffer[3];
+
+               /* Mask with opcode and see if match */
+               if ((opcode & mask) == (test & mask))
+               {
+                       /* See if second or third match */
+                       if (index >= 0)
+                       {
+                               /* Take new one if it looks good */
+                               if (bestlen == MAXLEN && len == MAXLEN)
+                               {
+                                       /* See if lower bits matched */
+                                       if (((bestmask & 3) == 0) &&
+                                           ((mask & 3) != 0))
+                                       {
+                                               bestmask = mask;
+                                               bestlen = len;
+                                               best = test;
+                                               index = i;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               /* First match, save it */
+                               bestmask = mask;
+                               bestlen = len;
+                               best = test;
+                               index = i;
+                       }
+               }
+       }
+
+       /* Handle undefined instructions.  */
+       if (index < 0)
+       {
+               fprintf (stream, "undefined   0%o",(buffer[0]<<8)+buffer[1]);
+               return 2;
+       }
+
+       /* Print instruction name */
+       fprintf (stream, "%-12s", gld_opcodes[index].name);
+
+       /* Adjust if short instruction */
+       if (gld_opcodes[index].length < 4)
+       {
+               best >>= 16;
+               i = 0;
+       }
+       else
+       {
+               i = 16;
+       }
+
+       /* Dump out instruction arguments */
+       for (d = gld_opcodes[index].args; *d; ++d)
+       {
+           switch (*d)
+           {
+               case 'f':
+                   fprintf (stream, "%d",  (best >> (7 + i)) & 7);
+                   break;
+               case 'r':
+                   fprintf (stream, "r%d", (best >> (7 + i)) & 7);
+                   break;
+               case 'R':
+                   fprintf (stream, "r%d", (best >> (4 + i)) & 7);
+                   break;
+               case 'b':
+                   fprintf (stream, "b%d", (best >> (7 + i)) & 7);
+                   break;
+               case 'B':
+                   fprintf (stream, "b%d", (best >> (4 + i)) & 7);
+                   break;
+               case 'v':
+                   fprintf (stream, "b%d", (best >> (7 + i)) & 7);
+                   break;
+               case 'V':
+                   fprintf (stream, "b%d", (best >> (4 + i)) & 7);
+                   break;
+               case 'X':
+                   temp = (best >> 20) & 7;
+                   if (temp)
+                       fprintf (stream, "r%d", temp);
+                   else
+                       putc ('0', stream);
+                   break;
+               case 'A':
+                   temp = (best >> 16) & 7;
+                   if (temp)
+                       fprintf (stream, "(b%d)", temp);
+                   break;
+               case 'S':
+                   fprintf (stream, "#%d", best & 0x1f);
+                   break;
+               case 'I':
+                   fprintf (stream, "#%x", best & 0xffff);
+                   break;
+               case 'O':
+                   fprintf (stream, "%x", best & 0xffff);
+                   break;
+               case 'h':
+                   fprintf (stream, "%d", best & 0xfffe);
+                   break;
+               case 'd':
+                   fprintf (stream, "%d", best & 0xfffc);
+                   break;
+               case 'T':
+                   fprintf (stream, "%d", (best >> 8) & 0xff);
+                   break;
+               case 'N':
+                   fprintf (stream, "%d", best & 0xff);
+                   break;
+               default:
+                   putc (*d, stream);
+                   break;
+           }
+       }
+
+       /* Return length of instruction */
+       return (gld_opcodes[index].length);
+}
+
+/*
+ * Find the number of arguments to a function.
+ */
+findarg(frame)
+       struct frame_info *frame;
+{
+       register struct symbol *func;
+       register unsigned pc;
+
+#ifdef notdef
+       /* find starting address of frame function */
+       pc = get_pc_function_start (frame->pc);
+
+       /* find function symbol info */
+       func = find_pc_function (pc);
+
+       /* call blockframe code to look for match */
+       if (func != NULL)
+                return (func->value.block->nsyms / sizeof(int));
+#endif
+
+        return (-1);
+} 
+
+/*
+ * In the case of the NPL, the frame's norminal address is Br2 and the 
+ * previous routines frame is up the stack X bytes.  Finding out what
+ * 'X' is can be tricky.
+ *
+ *    1.) stored in the code function header xA(Br1).
+ *    2.) must be careful of recurssion.
+ */
+FRAME_ADDR
+findframe(thisframe)
+    FRAME thisframe;
+{
+    register FRAME_ADDR pointer;
+    FRAME_ADDR framechain();
+#if 0    
+    struct frame_info *frame;
+
+    /* Setup toplevel frame structure */
+    frame->pc = read_pc();
+    frame->next_frame = 0;
+    frame->frame = read_register (SP_REGNUM);  /* Br2 */
+
+    /* Search for this frame (start at current Br2) */
+    do
+    {
+       pointer = framechain(frame);
+       frame->next_frame = frame->frame;
+       frame->frame = pointer;
+       frame->pc = FRAME_SAVED_PC(frame);
+    }
+    while (frame->next_frame != thisframe);
+#endif
+
+    pointer = framechain (thisframe);
+
+    /* stop gap for now, end at __base3 */
+    if (thisframe->pc == 0)
+       return 0;
+
+    return pointer;
+}
+
+/*
+ * Gdb front-end and internal framechain routine.
+ * Go back up stack one level.  Tricky...
+ */
+FRAME_ADDR
+framechain(frame)
+    register struct frame_info *frame;
+{
+    register CORE_ADDR func, prevsp;
+    register unsigned value;
+
+    /* Get real function start address from internal frame address */
+    func = get_pc_function_start(frame->pc);
+
+    /* If no stack given, read register Br1 "(sp)" */
+    if (!frame->frame)
+       prevsp = read_register (SP_REGNUM);
+    else
+       prevsp = frame->frame;
+
+    /* Check function header, case #2 */
+    value = read_memory_integer (func, 4);
+    if (value)
+    {
+       /* 32bit call push value stored in function header */
+       prevsp += value;
+    }
+    else
+    {
+       /* read half-word from suabr at start of function */
+       prevsp += read_memory_integer (func + 10, 2);
+    }
+
+    return (prevsp);
+}
diff --git a/gdb/gould-xdep.c b/gdb/gould-xdep.c
new file mode 100644 (file)
index 0000000..c3aec0d
--- /dev/null
@@ -0,0 +1,132 @@
+/* Low level interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include "gdbcore.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+\f
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct user u;
+       int reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name (filename);
+       data_start = exec_data_start;
+
+       data_end = data_start + NBPG * u.u_dsize;
+       stack_start = stack_end - NBPG * u.u_ssize;
+       data_offset = NBPG * UPAGES;
+       stack_offset = NBPG * (UPAGES + u.u_dsize);
+       reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
+
+       /* I don't know where to find this info.
+          So, for now, mark it as not available.  */
+       core_aouthdr.a_magic = 0;
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < NUM_REGS; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             val = lseek (corechan, register_addr (regno, reg_offset), 0);
+             if (val < 0)
+               perror_with_name (filename);
+
+             val = myread (corechan, buf, sizeof buf);
+             if (val < 0)
+               perror_with_name (filename);
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
diff --git a/gdb/hp300hpux-xdep.c b/gdb/hp300hpux-xdep.c
new file mode 100755 (executable)
index 0000000..f7f1cf0
--- /dev/null
@@ -0,0 +1,230 @@
+/* HP/UX interface for HP 300's, for GDB when running under Unix.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+/* Defining this means some system include files define some extra stuff.  */
+#define WOPR
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <sys/ptrace.h>
+#include <sys/reg.h>
+#include <sys/trap.h>
+
+#include "gdbcore.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#define INFERIOR_AR0(u)                                                        \
+  ((ptrace                                                             \
+    (PT_RUAREA, inferior_pid, ((char *) &u.u_ar0 - (char *) &u), 0))   \
+   - KERNEL_U_ADDR)
+
+static void
+fetch_inferior_register (regno, regaddr)
+     register int regno;
+     register unsigned int regaddr;
+{
+#ifndef HPUX_VERSION_5
+  if (regno == PS_REGNUM)
+    {
+      union { int i; short s[2]; } ps_val;
+      int regval;
+      
+      ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
+      regval = ps_val.s[0];
+      supply_register (regno, &regval);
+    }
+  else
+#endif /* not HPUX_VERSION_5 */
+    {
+      char buf[MAX_REGISTER_RAW_SIZE];
+      register int i;
+      
+      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+       {
+         *(int *) &buf[i] = ptrace (PT_RUAREA, inferior_pid, regaddr, 0);
+         regaddr += sizeof (int);
+       }
+      supply_register (regno, buf);
+    }
+  return;
+}
+
+static void
+store_inferior_register_1 (regno, regaddr, value)
+     int regno;
+     unsigned int regaddr;
+     int value;
+{
+  errno = 0;
+  ptrace (PT_WUAREA, inferior_pid, regaddr, value);
+#if 0
+  /* HP-UX randomly sets errno to non-zero for regno == 25.
+     However, the value is correctly written, so ignore errno. */
+  if (errno != 0)
+    {
+      char string_buf[64];
+      
+      sprintf (string_buf, "writing register number %d", regno);
+      perror_with_name (string_buf);
+    }
+#endif
+  return;
+}
+
+static void
+store_inferior_register (regno, regaddr)
+     register int regno;
+     register unsigned int regaddr;
+{
+#ifndef HPUX_VERSION_5
+  if (regno == PS_REGNUM)
+    {
+      union { int i; short s[2]; } ps_val;
+      
+      ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
+      ps_val.s[0] = (read_register (regno));
+      store_inferior_register_1 (regno, regaddr, ps_val.i);
+    }
+  else
+#endif /* not HPUX_VERSION_5 */
+    {
+      char buf[MAX_REGISTER_RAW_SIZE];
+      register int i;
+      extern char registers[];
+      
+      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+       {
+         store_inferior_register_1
+           (regno, regaddr,
+            (*(int *) &registers[(REGISTER_BYTE (regno)) + i]));
+         regaddr += sizeof (int);
+       }
+    }
+  return;
+}
+
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+  struct user u;
+  register int regno;
+  register unsigned int ar0_offset;
+  
+  ar0_offset = (INFERIOR_AR0 (u));
+  if (regno == -1)
+    {
+      for (regno = 0; (regno < FP0_REGNUM); regno++)
+       fetch_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+      for (; (regno < NUM_REGS); regno++)
+       fetch_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+    }
+  else
+    fetch_inferior_register (regno,
+                            (regno < FP0_REGNUM
+                             ? REGISTER_ADDR (ar0_offset, regno)
+                             : FP_REGISTER_ADDR (u, regno)));
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     register int regno;
+{
+  struct user u;
+  register unsigned int ar0_offset;
+  extern char registers[];
+
+  if (regno >= FP0_REGNUM)
+    {
+      store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+      return;
+    }
+  
+  ar0_offset = (INFERIOR_AR0 (u));
+  if (regno >= 0)
+    {
+      store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+      return;
+    }
+
+  for (regno = 0; (regno < FP0_REGNUM); regno++)
+    store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
+  for (; (regno < NUM_REGS); regno++)
+    store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
+  return;
+}
+
+\f
+/* Take the register values out of a core file and store
+   them where `read_register' will find them.  */
+
+#ifdef HPUX_VERSION_5
+#define e_PS e_regs[PS]
+#define e_PC e_regs[PC]
+#endif /* HPUX_VERSION_5 */
+
+void
+fetch_core_registers (core_reg_sect, core_reg_size, which)
+     char *core_reg_sect;
+     int core_reg_size;
+     int which;
+{
+  int val, regno;
+  struct user u;
+  struct exception_stack *pes = (struct exception_stack *) core_reg_sect;
+#define es (*pes)
+  char *buf;
+
+  if (which == 0) {
+    if (core_reg_size < 
+                 ((char *) &es.e_offset - (char *) &es.e_regs[R0]))
+         error ("Not enough registers in core file");
+    for (regno = 0; (regno < PS_REGNUM); regno++)
+      supply_register (regno, &es.e_regs[regno + R0]);
+    val = es.e_PS;
+    supply_register (regno++, &val);
+    supply_register (regno++, &es.e_PC);
+
+  } else if (which == 2) {
+
+    /* FIXME: This may not work if the float regs and control regs are
+       discontinuous.  */
+    for (regno = FP0_REGNUM, buf = core_reg_sect;
+        (regno < NUM_REGS);
+        buf += REGISTER_RAW_SIZE (regno), regno++)
+      {
+       supply_register (regno, buf);
+      }
+  }
+}
diff --git a/gdb/i386-pinsn.c b/gdb/i386-pinsn.c
new file mode 100644 (file)
index 0000000..50cf14b
--- /dev/null
@@ -0,0 +1,1834 @@
+/* Print i386 instructions for GDB, the GNU debugger.
+   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+/*
+ * The main tables describing the instructions is essentially a copy
+ * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ * Programmers Manual.  Usually, there is a capital letter, followed
+ * by a small letter.  The capital letter tell the addressing mode,
+ * and the small letter tells about the operand size.  Refer to 
+ * the Intel manual for details.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#define Eb OP_E, b_mode
+#define indirEb OP_indirE, b_mode
+#define Gb OP_G, b_mode
+#define Ev OP_E, v_mode
+#define indirEv OP_indirE, v_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_E, 0
+#define Mp OP_E, 0             /* ? */
+#define Gv OP_G, v_mode
+#define Gw OP_G, w_mode
+#define Rw OP_rm, w_mode
+#define Rd OP_rm, d_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode      /* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iw OP_I, w_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define ONE OP_ONE, 0
+#define Cd OP_C, d_mode
+#define Dd OP_D, d_mode
+#define Td OP_T, d_mode
+
+#define eAX OP_REG, eAX_reg
+#define eBX OP_REG, eBX_reg
+#define eCX OP_REG, eCX_reg
+#define eDX OP_REG, eDX_reg
+#define eSP OP_REG, eSP_reg
+#define eBP OP_REG, eBP_reg
+#define eSI OP_REG, eSI_reg
+#define eDI OP_REG, eDI_reg
+#define AL OP_REG, al_reg
+#define CL OP_REG, cl_reg
+#define DL OP_REG, dl_reg
+#define BL OP_REG, bl_reg
+#define AH OP_REG, ah_reg
+#define CH OP_REG, ch_reg
+#define DH OP_REG, dh_reg
+#define BH OP_REG, bh_reg
+#define AX OP_REG, ax_reg
+#define DX OP_REG, dx_reg
+#define indirDX OP_REG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, lptr
+#define Av OP_DIR, v_mode
+#define Ob OP_OFF, b_mode
+#define Ov OP_OFF, v_mode
+#define Xb OP_DSSI, b_mode
+#define Xv OP_DSSI, v_mode
+#define Yb OP_ESDI, b_mode
+#define Yv OP_ESDI, v_mode
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
+int OP_J(), OP_SEG();
+int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
+int OP_D(), OP_T(), OP_rm();
+
+
+#define b_mode 1
+#define v_mode 2
+#define w_mode 3
+#define d_mode 4
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+#define eAX_reg 107
+#define eCX_reg 108
+#define eDX_reg 109
+#define eBX_reg 110
+#define eSP_reg 111
+#define eBP_reg 112
+#define eSI_reg 113
+#define eDI_reg 114
+
+#define lptr 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define indir_dx_reg 150
+
+#define GRP1b NULL, NULL, 0
+#define GRP1S NULL, NULL, 1
+#define GRP1Ss NULL, NULL, 2
+#define GRP2b NULL, NULL, 3
+#define GRP2S NULL, NULL, 4
+#define GRP2b_one NULL, NULL, 5
+#define GRP2S_one NULL, NULL, 6
+#define GRP2b_cl NULL, NULL, 7
+#define GRP2S_cl NULL, NULL, 8
+#define GRP3b NULL, NULL, 9
+#define GRP3S NULL, NULL, 10
+#define GRP4  NULL, NULL, 11
+#define GRP5  NULL, NULL, 12
+#define GRP6  NULL, NULL, 13
+#define GRP7 NULL, NULL, 14
+#define GRP8 NULL, NULL, 15
+
+#define FLOATCODE 50
+#define FLOAT NULL, NULL, FLOATCODE
+
+struct dis386 {
+  char *name;
+  int (*op1)();
+  int bytemode1;
+  int (*op2)();
+  int bytemode2;
+  int (*op3)();
+  int bytemode3;
+};
+
+struct dis386 dis386[] = {
+  /* 00 */
+  { "addb",    Eb, Gb },
+  { "addS",    Ev, Gv },
+  { "addb",    Gb, Eb },
+  { "addS",    Gv, Ev },
+  { "addb",    AL, Ib },
+  { "addS",    eAX, Iv },
+  { "pushl",   es },
+  { "popl",    es },
+  /* 08 */
+  { "orb",     Eb, Gb },
+  { "orS",     Ev, Gv },
+  { "orb",     Gb, Eb },
+  { "orS",     Gv, Ev },
+  { "orb",     AL, Ib },
+  { "orS",     eAX, Iv },
+  { "pushl",   cs },
+  { "(bad)" }, /* 0x0f extended opcode escape */
+  /* 10 */
+  { "adcb",    Eb, Gb },
+  { "adcS",    Ev, Gv },
+  { "adcb",    Gb, Eb },
+  { "adcS",    Gv, Ev },
+  { "adcb",    AL, Ib },
+  { "adcS",    eAX, Iv },
+  { "pushl",   ss },
+  { "popl",    ss },
+  /* 18 */
+  { "sbbb",    Eb, Gb },
+  { "sbbS",    Ev, Gv },
+  { "sbbb",    Gb, Eb },
+  { "sbbS",    Gv, Ev },
+  { "sbbb",    AL, Ib },
+  { "sbbS",    eAX, Iv },
+  { "pushl",   ds },
+  { "popl",    ds },
+  /* 20 */
+  { "andb",    Eb, Gb },
+  { "andS",    Ev, Gv },
+  { "andb",    Gb, Eb },
+  { "andS",    Gv, Ev },
+  { "andb",    AL, Ib },
+  { "andS",    eAX, Iv },
+  { "(bad)" },                 /* SEG ES prefix */
+  { "daa" },
+  /* 28 */
+  { "subb",    Eb, Gb },
+  { "subS",    Ev, Gv },
+  { "subb",    Gb, Eb },
+  { "subS",    Gv, Ev },
+  { "subb",    AL, Ib },
+  { "subS",    eAX, Iv },
+  { "(bad)" },                 /* SEG CS prefix */
+  { "das" },
+  /* 30 */
+  { "xorb",    Eb, Gb },
+  { "xorS",    Ev, Gv },
+  { "xorb",    Gb, Eb },
+  { "xorS",    Gv, Ev },
+  { "xorb",    AL, Ib },
+  { "xorS",    eAX, Iv },
+  { "(bad)" },                 /* SEG SS prefix */
+  { "aaa" },
+  /* 38 */
+  { "cmpb",    Eb, Gb },
+  { "cmpS",    Ev, Gv },
+  { "cmpb",    Gb, Eb },
+  { "cmpS",    Gv, Ev },
+  { "cmpb",    AL, Ib },
+  { "cmpS",    eAX, Iv },
+  { "(bad)" },                 /* SEG DS prefix */
+  { "aas" },
+  /* 40 */
+  { "incS",    eAX },
+  { "incS",    eCX },
+  { "incS",    eDX },
+  { "incS",    eBX },
+  { "incS",    eSP },
+  { "incS",    eBP },
+  { "incS",    eSI },
+  { "incS",    eDI },
+  /* 48 */
+  { "decS",    eAX },
+  { "decS",    eCX },
+  { "decS",    eDX },
+  { "decS",    eBX },
+  { "decS",    eSP },
+  { "decS",    eBP },
+  { "decS",    eSI },
+  { "decS",    eDI },
+  /* 50 */
+  { "pushS",   eAX },
+  { "pushS",   eCX },
+  { "pushS",   eDX },
+  { "pushS",   eBX },
+  { "pushS",   eSP },
+  { "pushS",   eBP },
+  { "pushS",   eSI },
+  { "pushS",   eDI },
+  /* 58 */
+  { "popS",    eAX },
+  { "popS",    eCX },
+  { "popS",    eDX },
+  { "popS",    eBX },
+  { "popS",    eSP },
+  { "popS",    eBP },
+  { "popS",    eSI },
+  { "popS",    eDI },
+  /* 60 */
+  { "pusha" },
+  { "popa" },
+  { "boundS",  Gv, Ma },
+  { "arpl",    Ew, Gw },
+  { "(bad)" },                 /* seg fs */
+  { "(bad)" },                 /* seg gs */
+  { "(bad)" },                 /* op size prefix */
+  { "(bad)" },                 /* adr size prefix */
+  /* 68 */
+  { "pushS",   Iv },           /* 386 book wrong */
+  { "imulS",   Gv, Ev, Iv },
+  { "pushl",   sIb },          /* push of byte really pushes 4 bytes */
+  { "imulS",   Gv, Ev, Ib },
+  { "insb",    Yb, indirDX },
+  { "insS",    Yv, indirDX },
+  { "outsb",   indirDX, Xb },
+  { "outsS",   indirDX, Xv },
+  /* 70 */
+  { "jo",              Jb },
+  { "jno",     Jb },
+  { "jb",              Jb },
+  { "jae",     Jb },
+  { "je",              Jb },
+  { "jne",     Jb },
+  { "jbe",     Jb },
+  { "ja",              Jb },
+  /* 78 */
+  { "js",              Jb },
+  { "jns",     Jb },
+  { "jp",              Jb },
+  { "jnp",     Jb },
+  { "jl",              Jb },
+  { "jnl",     Jb },
+  { "jle",     Jb },
+  { "jg",              Jb },
+  /* 80 */
+  { GRP1b },
+  { GRP1S },
+  { "(bad)" },
+  { GRP1Ss },
+  { "testb",   Eb, Gb },
+  { "testS",   Ev, Gv },
+  { "xchgb",   Eb, Gb },
+  { "xchgS",   Ev, Gv },
+  /* 88 */
+  { "movb",    Eb, Gb },
+  { "movS",    Ev, Gv },
+  { "movb",    Gb, Eb },
+  { "movS",    Gv, Ev },
+  { "movw",    Ew, Sw },
+  { "leaS",    Gv, M },
+  { "movw",    Sw, Ew },
+  { "popS",    Ev },
+  /* 90 */
+  { "nop" },
+  { "xchgS",   eCX, eAX },
+  { "xchgS",   eDX, eAX },
+  { "xchgS",   eBX, eAX },
+  { "xchgS",   eSP, eAX },
+  { "xchgS",   eBP, eAX },
+  { "xchgS",   eSI, eAX },
+  { "xchgS",   eDI, eAX },
+  /* 98 */
+  { "cwtl" },
+  { "cltd" },
+  { "lcall",   Ap },
+  { "(bad)" },         /* fwait */
+  { "pushf" },
+  { "popf" },
+  { "sahf" },
+  { "lahf" },
+  /* a0 */
+  { "movb",    AL, Ob },
+  { "movS",    eAX, Ov },
+  { "movb",    Ob, AL },
+  { "movS",    Ov, eAX },
+  { "movsb",   Yb, Xb },
+  { "movsS",   Yv, Xv },
+  { "cmpsb",   Yb, Xb },
+  { "cmpsS",   Yv, Xv },
+  /* a8 */
+  { "testb",   AL, Ib },
+  { "testS",   eAX, Iv },
+  { "stosb",   Yb, AL },
+  { "stosS",   Yv, eAX },
+  { "lodsb",   AL, Xb },
+  { "lodsS",   eAX, Xv },
+  { "scasb",   AL, Xb },
+  { "scasS",   eAX, Xv },
+  /* b0 */
+  { "movb",    AL, Ib },
+  { "movb",    CL, Ib },
+  { "movb",    DL, Ib },
+  { "movb",    BL, Ib },
+  { "movb",    AH, Ib },
+  { "movb",    CH, Ib },
+  { "movb",    DH, Ib },
+  { "movb",    BH, Ib },
+  /* b8 */
+  { "movS",    eAX, Iv },
+  { "movS",    eCX, Iv },
+  { "movS",    eDX, Iv },
+  { "movS",    eBX, Iv },
+  { "movS",    eSP, Iv },
+  { "movS",    eBP, Iv },
+  { "movS",    eSI, Iv },
+  { "movS",    eDI, Iv },
+  /* c0 */
+  { GRP2b },
+  { GRP2S },
+  { "ret",     Iw },
+  { "ret" },
+  { "lesS",    Gv, Mp },
+  { "ldsS",    Gv, Mp },
+  { "movb",    Eb, Ib },
+  { "movS",    Ev, Iv },
+  /* c8 */
+  { "enter",   Iw, Ib },
+  { "leave" },
+  { "lret",    Iw },
+  { "lret" },
+  { "int3" },
+  { "int",     Ib },
+  { "into" },
+  { "iret" },
+  /* d0 */
+  { GRP2b_one },
+  { GRP2S_one },
+  { GRP2b_cl },
+  { GRP2S_cl },
+  { "aam",     Ib },
+  { "aad",     Ib },
+  { "(bad)" },
+  { "xlat" },
+  /* d8 */
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  /* e0 */
+  { "loopne",  Jb },
+  { "loope",   Jb },
+  { "loop",    Jb },
+  { "jCcxz",   Jb },
+  { "inb",     AL, Ib },
+  { "inS",     eAX, Ib },
+  { "outb",    Ib, AL },
+  { "outS",    Ib, eAX },
+  /* e8 */
+  { "call",    Av },
+  { "jmp",     Jv },
+  { "ljmp",    Ap },
+  { "jmp",     Jb },
+  { "inb",     AL, indirDX },
+  { "inS",     eAX, indirDX },
+  { "outb",    indirDX, AL },
+  { "outS",    indirDX, eAX },
+  /* f0 */
+  { "(bad)" },                 /* lock prefix */
+  { "(bad)" },
+  { "(bad)" },                 /* repne */
+  { "(bad)" },                 /* repz */
+  { "hlt" },
+  { "cmc" },
+  { GRP3b },
+  { GRP3S },
+  /* f8 */
+  { "clc" },
+  { "stc" },
+  { "cli" },
+  { "sti" },
+  { "cld" },
+  { "std" },
+  { GRP4 },
+  { GRP5 },
+};
+
+struct dis386 dis386_twobyte[] = {
+  /* 00 */
+  { GRP6 },
+  { GRP7 },
+  { "larS", Gv, Ew },
+  { "lslS", Gv, Ew },  
+  { "(bad)" },
+  { "(bad)" },
+  { "clts" },
+  { "(bad)" },  
+  /* 08 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 10 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 18 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 20 */
+  /* these are all backward in appendix A of the intel book */
+  { "movl", Rd, Cd },
+  { "movl", Rd, Dd },
+  { "movl", Cd, Rd },
+  { "movl", Dd, Rd },  
+  { "movl", Rd, Td },
+  { "(bad)" },
+  { "movl", Td, Rd },
+  { "(bad)" },  
+  /* 28 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 30 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 38 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 40 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 48 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 50 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 58 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 60 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 68 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 70 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 78 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 80 */
+  { "jo", Jv },
+  { "jno", Jv },
+  { "jb", Jv },
+  { "jae", Jv },  
+  { "je", Jv },
+  { "jne", Jv },
+  { "jbe", Jv },
+  { "ja", Jv },  
+  /* 88 */
+  { "js", Jv },
+  { "jns", Jv },
+  { "jp", Jv },
+  { "jnp", Jv },  
+  { "jl", Jv },
+  { "jge", Jv },
+  { "jle", Jv },
+  { "jg", Jv },  
+  /* 90 */
+  { "seto", Eb },
+  { "setno", Eb },
+  { "setb", Eb },
+  { "setae", Eb },
+  { "sete", Eb },
+  { "setne", Eb },
+  { "setbe", Eb },
+  { "seta", Eb },
+  /* 98 */
+  { "sets", Eb },
+  { "setns", Eb },
+  { "setp", Eb },
+  { "setnp", Eb },
+  { "setl", Eb },
+  { "setge", Eb },
+  { "setle", Eb },
+  { "setg", Eb },  
+  /* a0 */
+  { "pushl", fs },
+  { "popl", fs },
+  { "(bad)" },
+  { "btS", Ev, Gv },  
+  { "shldS", Ev, Gv, Ib },
+  { "shldS", Ev, Gv, CL },
+  { "(bad)" },
+  { "(bad)" },  
+  /* a8 */
+  { "pushl", gs },
+  { "popl", gs },
+  { "(bad)" },
+  { "btsS", Ev, Gv },  
+  { "shrdS", Ev, Gv, Ib },
+  { "shrdS", Ev, Gv, CL },
+  { "(bad)" },
+  { "imulS", Gv, Ev },  
+  /* b0 */
+  { "(bad)" },
+  { "(bad)" },
+  { "lssS", Gv, Mp },  /* 386 lists only Mp */
+  { "btrS", Ev, Gv },  
+  { "lfsS", Gv, Mp },  /* 386 lists only Mp */
+  { "lgsS", Gv, Mp },  /* 386 lists only Mp */
+  { "movzbS", Gv, Eb },
+  { "movzwS", Gv, Ew },  
+  /* b8 */
+  { "(bad)" },
+  { "(bad)" },
+  { GRP8 },
+  { "btcS", Ev, Gv },  
+  { "bsfS", Gv, Ev },
+  { "bsrS", Gv, Ev },
+  { "movsbS", Gv, Eb },
+  { "movswS", Gv, Ew },  
+  /* c0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* c8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* d0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* d8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* e0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* e8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* f0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* f8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *codep;
+static int mod;
+static int rm;
+static int reg;
+static void oappend ();
+
+static char *names32[]={
+  "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
+};
+static char *names16[] = {
+  "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
+};
+static char *names8[] = {
+  "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
+};
+static char *names_seg[] = {
+  "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+};
+
+struct dis386 grps[][8] = {
+  /* GRP1b */
+  {
+    { "addb",  Eb, Ib },
+    { "orb",   Eb, Ib },
+    { "adcb",  Eb, Ib },
+    { "sbbb",  Eb, Ib },
+    { "andb",  Eb, Ib },
+    { "subb",  Eb, Ib },
+    { "xorb",  Eb, Ib },
+    { "cmpb",  Eb, Ib }
+  },
+  /* GRP1S */
+  {
+    { "addS",  Ev, Iv },
+    { "orS",   Ev, Iv },
+    { "adcS",  Ev, Iv },
+    { "sbbS",  Ev, Iv },
+    { "andS",  Ev, Iv },
+    { "subS",  Ev, Iv },
+    { "xorS",  Ev, Iv },
+    { "cmpS",  Ev, Iv }
+  },
+  /* GRP1Ss */
+  {
+    { "addS",  Ev, sIb },
+    { "orS",   Ev, sIb },
+    { "adcS",  Ev, sIb },
+    { "sbbS",  Ev, sIb },
+    { "andS",  Ev, sIb },
+    { "subS",  Ev, sIb },
+    { "xorS",  Ev, sIb },
+    { "cmpS",  Ev, sIb }
+  },
+  /* GRP2b */
+  {
+    { "rolb",  Eb, Ib },
+    { "rorb",  Eb, Ib },
+    { "rclb",  Eb, Ib },
+    { "rcrb",  Eb, Ib },
+    { "shlb",  Eb, Ib },
+    { "shrb",  Eb, Ib },
+    { "(bad)" },
+    { "sarb",  Eb, Ib },
+  },
+  /* GRP2S */
+  {
+    { "rolS",  Ev, Ib },
+    { "rorS",  Ev, Ib },
+    { "rclS",  Ev, Ib },
+    { "rcrS",  Ev, Ib },
+    { "shlS",  Ev, Ib },
+    { "shrS",  Ev, Ib },
+    { "(bad)" },
+    { "sarS",  Ev, Ib },
+  },
+  /* GRP2b_one */
+  {
+    { "rolb",  Eb },
+    { "rorb",  Eb },
+    { "rclb",  Eb },
+    { "rcrb",  Eb },
+    { "shlb",  Eb },
+    { "shrb",  Eb },
+    { "(bad)" },
+    { "sarb",  Eb },
+  },
+  /* GRP2S_one */
+  {
+    { "rolS",  Ev },
+    { "rorS",  Ev },
+    { "rclS",  Ev },
+    { "rcrS",  Ev },
+    { "shlS",  Ev },
+    { "shrS",  Ev },
+    { "(bad)" },
+    { "sarS",  Ev },
+  },
+  /* GRP2b_cl */
+  {
+    { "rolb",  Eb, CL },
+    { "rorb",  Eb, CL },
+    { "rclb",  Eb, CL },
+    { "rcrb",  Eb, CL },
+    { "shlb",  Eb, CL },
+    { "shrb",  Eb, CL },
+    { "(bad)" },
+    { "sarb",  Eb, CL },
+  },
+  /* GRP2S_cl */
+  {
+    { "rolS",  Ev, CL },
+    { "rorS",  Ev, CL },
+    { "rclS",  Ev, CL },
+    { "rcrS",  Ev, CL },
+    { "shlS",  Ev, CL },
+    { "shrS",  Ev, CL },
+    { "(bad)" },
+    { "sarS",  Ev, CL }
+  },
+  /* GRP3b */
+  {
+    { "testb", Eb, Ib },
+    { "(bad)", Eb },
+    { "notb",  Eb },
+    { "negb",  Eb },
+    { "mulb",  AL, Eb },
+    { "imulb", AL, Eb },
+    { "divb",  AL, Eb },
+    { "idivb", AL, Eb }
+  },
+  /* GRP3S */
+  {
+    { "testS", Ev, Iv },
+    { "(bad)" },
+    { "notS",  Ev },
+    { "negS",  Ev },
+    { "mulS",  eAX, Ev },
+    { "imulS", eAX, Ev },
+    { "divS",  eAX, Ev },
+    { "idivS", eAX, Ev },
+  },
+  /* GRP4 */
+  {
+    { "incb", Eb },
+    { "decb", Eb },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* GRP5 */
+  {
+    { "incS",  Ev },
+    { "decS",  Ev },
+    { "call",  indirEv },
+    { "lcall", indirEv },
+    { "jmp",   indirEv },
+    { "ljmp",  indirEv },
+    { "pushS", Ev },
+    { "(bad)" },
+  },
+  /* GRP6 */
+  {
+    { "sldt",  Ew },
+    { "str",   Ew },
+    { "lldt",  Ew },
+    { "ltr",   Ew },
+    { "verr",  Ew },
+    { "verw",  Ew },
+    { "(bad)" },
+    { "(bad)" }
+  },
+  /* GRP7 */
+  {
+    { "sgdt", Ew },
+    { "sidt", Ew },
+    { "lgdt", Ew },
+    { "lidt", Ew },
+    { "smsw", Ew },
+    { "(bad)" },
+    { "lmsw", Ew },
+    { "(bad)" },
+  },
+  /* GRP8 */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "btS",   Ev, Ib },
+    { "btsS",  Ev, Ib },
+    { "btrS",  Ev, Ib },
+    { "btcS",  Ev, Ib },
+  }
+};
+
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADR 0x400
+#define PREFIX_FWAIT 0x800
+
+static int prefixes;
+
+ckprefix ()
+{
+  prefixes = 0;
+  while (1)
+    {
+      switch (*codep)
+       {
+       case 0xf3:
+         prefixes |= PREFIX_REPZ;
+         break;
+       case 0xf2:
+         prefixes |= PREFIX_REPNZ;
+         break;
+       case 0xf0:
+         prefixes |= PREFIX_LOCK;
+         break;
+       case 0x2e:
+         prefixes |= PREFIX_CS;
+         break;
+       case 0x36:
+         prefixes |= PREFIX_SS;
+         break;
+       case 0x3e:
+         prefixes |= PREFIX_DS;
+         break;
+       case 0x26:
+         prefixes |= PREFIX_ES;
+         break;
+       case 0x64:
+         prefixes |= PREFIX_FS;
+         break;
+       case 0x65:
+         prefixes |= PREFIX_GS;
+         break;
+       case 0x66:
+         prefixes |= PREFIX_DATA;
+         break;
+       case 0x67:
+         prefixes |= PREFIX_ADR;
+         break;
+       case 0x9b:
+         prefixes |= PREFIX_FWAIT;
+         break;
+       default:
+         return;
+       }
+      codep++;
+    }
+}
+
+static int dflag;
+static int aflag;              
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_address[3], op_ad, op_index[3];
+static int start_pc;
+extern void fputs_filtered ();
+
+/*
+ * disassemble the first instruction in 'inbuf'.  You have to make
+ *   sure all of the bytes of the instruction are filled in.
+ *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ *   (see topic "Redundant prefixes" in the "Differences from 8086"
+ *   section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ *   be used to print the target address if this is a relative jump or call
+ * 'outbuf' gets filled in with the disassembled instruction.  it should
+ *   be long enough to hold the longest disassembled instruction.
+ *   100 bytes is certainly enough, unless symbol printing is added later
+ * The function returns the length of this instruction in bytes.
+ */
+i386dis (pc, inbuf, stream)
+     int pc;
+     unsigned char *inbuf;
+     FILE *stream;
+{
+  struct dis386 *dp;
+  char *p;
+  int i;
+  int enter_instruction;
+  char *first, *second, *third;
+  int needcomma;
+  
+  obuf[0] = 0;
+  op1out[0] = 0;
+  op2out[0] = 0;
+  op3out[0] = 0;
+
+  op_index[0] = op_index[1] = op_index[2] = -1;
+  
+  start_pc = pc;
+  start_codep = inbuf;
+  codep = inbuf;
+  
+  ckprefix ();
+  
+  if (*codep == 0xc8)
+    enter_instruction = 1;
+  else
+    enter_instruction = 0;
+  
+  obufp = obuf;
+  
+  if (prefixes & PREFIX_REPZ)
+    oappend ("repz ");
+  if (prefixes & PREFIX_REPNZ)
+    oappend ("repnz ");
+  if (prefixes & PREFIX_LOCK)
+    oappend ("lock ");
+  
+  if ((prefixes & PREFIX_FWAIT)
+      && ((*codep < 0xd8) || (*codep > 0xdf)))
+    {
+      /* fwait not followed by floating point instruction */
+      fputs_filtered ("fwait", stream);
+      return (1);
+    }
+  
+  /* these would be initialized to 0 if disassembling for 8086 or 286 */
+  dflag = 1;
+  aflag = 1;
+  
+  if (prefixes & PREFIX_DATA)
+    dflag ^= 1;
+  
+  if (prefixes & PREFIX_ADR)
+    {
+      aflag ^= 1;
+      oappend ("addr16 ");
+    }
+  
+  if (*codep == 0x0f)
+    dp = &dis386_twobyte[*++codep];
+  else
+    dp = &dis386[*codep];
+  codep++;
+  mod = (*codep >> 6) & 3;
+  reg = (*codep >> 3) & 7;
+  rm = *codep & 7;
+  
+  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+    {
+      dofloat ();
+    }
+  else
+    {
+      if (dp->name == NULL)
+       dp = &grps[dp->bytemode1][reg];
+      
+      putop (dp->name);
+      
+      obufp = op1out;
+      op_ad = 2;
+      if (dp->op1)
+       (*dp->op1)(dp->bytemode1);
+      
+      obufp = op2out;
+      op_ad = 1;
+      if (dp->op2)
+       (*dp->op2)(dp->bytemode2);
+      
+      obufp = op3out;
+      op_ad = 0;
+      if (dp->op3)
+       (*dp->op3)(dp->bytemode3);
+    }
+  
+  obufp = obuf + strlen (obuf);
+  for (i = strlen (obuf); i < 6; i++)
+    oappend (" ");
+  oappend (" ");
+  fputs_filtered (obuf, stream);
+  
+  /* enter instruction is printed with operands in the
+   * same order as the intel book; everything else
+   * is printed in reverse order 
+   */
+  if (enter_instruction)
+    {
+      first = op1out;
+      second = op2out;
+      third = op3out;
+      op_ad = op_index[0];
+      op_index[0] = op_index[2];
+      op_index[2] = op_ad;
+    }
+  else
+    {
+      first = op3out;
+      second = op2out;
+      third = op1out;
+    }
+  needcomma = 0;
+  if (*first)
+    {
+      if (op_index[0] != -1)
+       print_address (op_address[op_index[0]], stream);
+      else
+       fputs_filtered (first, stream);
+      needcomma = 1;
+    }
+  if (*second)
+    {
+      if (needcomma)
+       fputs_filtered (",", stream);
+      if (op_index[1] != -1)
+       print_address (op_address[op_index[1]], stream);
+      else
+       fputs_filtered (second, stream);
+      needcomma = 1;
+    }
+  if (*third)
+    {
+      if (needcomma)
+       fputs_filtered (",", stream);
+      if (op_index[2] != -1)
+       print_address (op_address[op_index[2]], stream);
+      else
+       fputs_filtered (third, stream);
+    }
+  return (codep - inbuf);
+}
+
+char *float_mem[] = {
+  /* d8 */
+  "fadds",
+  "fmuls",
+  "fcoms",
+  "fcomps",
+  "fsubs",
+  "fsubrs",
+  "fdivs",
+  "fdivrs",
+  /*  d9 */
+  "flds",
+  "(bad)",
+  "fsts",
+  "fstps",
+  "fldenv",
+  "fldcw",
+  "fNstenv",
+  "fNstcw",
+  /* da */
+  "fiaddl",
+  "fimull",
+  "ficoml",
+  "ficompl",
+  "fisubl",
+  "fisubrl",
+  "fidivl",
+  "fidivrl",
+  /* db */
+  "fildl",
+  "(bad)",
+  "fistl",
+  "fistpl",
+  "(bad)",
+  "fldt",
+  "(bad)",
+  "fstpt",
+  /* dc */
+  "faddl",
+  "fmull",
+  "fcoml",
+  "fcompl",
+  "fsubl",
+  "fsubrl",
+  "fdivl",
+  "fdivrl",
+  /* dd */
+  "fldl",
+  "(bad)",
+  "fstl",
+  "fstpl",
+  "frstor",
+  "(bad)",
+  "fNsave",
+  "fNstsw",
+  /* de */
+  "fiadd",
+  "fimul",
+  "ficom",
+  "ficomp",
+  "fisub",
+  "fisubr",
+  "fidiv",
+  "fidivr",
+  /* df */
+  "fild",
+  "(bad)",
+  "fist",
+  "fistp",
+  "fbld",
+  "fildll",
+  "fbstp",
+  "fistpll",
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+int OP_ST(), OP_STi();
+
+#define FGRPd9_2 NULL, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1
+#define FGRPd9_5 NULL, NULL, 2
+#define FGRPd9_6 NULL, NULL, 3
+#define FGRPd9_7 NULL, NULL, 4
+#define FGRPda_5 NULL, NULL, 5
+#define FGRPdb_4 NULL, NULL, 6
+#define FGRPde_3 NULL, NULL, 7
+#define FGRPdf_4 NULL, NULL, 8
+
+struct dis386 float_reg[][8] = {
+  /* d8 */
+  {
+    { "fadd",  ST, STi },
+    { "fmul",  ST, STi },
+    { "fcom",  STi },
+    { "fcomp", STi },
+    { "fsub",  ST, STi },
+    { "fsubr", ST, STi },
+    { "fdiv",  ST, STi },
+    { "fdivr", ST, STi },
+  },
+  /* d9 */
+  {
+    { "fld",   STi },
+    { "fxch",  STi },
+    { FGRPd9_2 },
+    { "(bad)" },
+    { FGRPd9_4 },
+    { FGRPd9_5 },
+    { FGRPd9_6 },
+    { FGRPd9_7 },
+  },
+  /* da */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPda_5 },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* db */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPdb_4 },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* dc */
+  {
+    { "fadd",  STi, ST },
+    { "fmul",  STi, ST },
+    { "(bad)" },
+    { "(bad)" },
+    { "fsub",  STi, ST },
+    { "fsubr", STi, ST },
+    { "fdiv",  STi, ST },
+    { "fdivr", STi, ST },
+  },
+  /* dd */
+  {
+    { "ffree", STi },
+    { "(bad)" },
+    { "fst",   STi },
+    { "fstp",  STi },
+    { "fucom", STi },
+    { "fucomp",        STi },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* de */
+  {
+    { "faddp", STi, ST },
+    { "fmulp", STi, ST },
+    { "(bad)" },
+    { FGRPde_3 },
+    { "fsubp", STi, ST },
+    { "fsubrp",        STi, ST },
+    { "fdivp", STi, ST },
+    { "fdivrp",        STi, ST },
+  },
+  /* df */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPdf_4 },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+};
+
+
+char *fgrps[][8] = {
+  /* d9_2  0 */
+  {
+    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* d9_4  1 */
+  {
+    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+  },
+
+  /* d9_5  2 */
+  {
+    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+  },
+
+  /* d9_6  3 */
+  {
+    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+  },
+
+  /* d9_7  4 */
+  {
+    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+  },
+
+  /* da_5  5 */
+  {
+    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* db_4  6 */
+  {
+    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+  },
+
+  /* de_3  7 */
+  {
+    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* df_4  8 */
+  {
+    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+};
+
+
+dofloat ()
+{
+  struct dis386 *dp;
+  unsigned char floatop;
+  
+  floatop = codep[-1];
+  
+  if (mod != 3)
+    {
+      putop (float_mem[(floatop - 0xd8) * 8 + reg]);
+      obufp = op1out;
+      OP_E (v_mode);
+      return;
+    }
+  codep++;
+  
+  dp = &float_reg[floatop - 0xd8][reg];
+  if (dp->name == NULL)
+    {
+      putop (fgrps[dp->bytemode1][rm]);
+      /* instruction fnstsw is only one with strange arg */
+      if (floatop == 0xdf && *codep == 0xe0)
+       strcpy (op1out, "%eax");
+    }
+  else
+    {
+      putop (dp->name);
+      obufp = op1out;
+      if (dp->op1)
+       (*dp->op1)(dp->bytemode1);
+      obufp = op2out;
+      if (dp->op2)
+       (*dp->op2)(dp->bytemode2);
+    }
+}
+
+/* ARGSUSED */
+OP_ST (ignore)
+{
+  oappend ("%st");
+}
+
+/* ARGSUSED */
+OP_STi (ignore)
+{
+  sprintf (scratchbuf, "%%st(%d)", rm);
+  oappend (scratchbuf);
+}
+
+
+/* capital letters in template are macros */
+putop (template)
+     char *template;
+{
+  char *p;
+  
+  for (p = template; *p; p++)
+    {
+      switch (*p)
+       {
+       default:
+         *obufp++ = *p;
+         break;
+       case 'C':               /* For jcxz/jecxz */
+         if (aflag == 0)
+           *obufp++ = 'e';
+         break;
+       case 'N':
+         if ((prefixes & PREFIX_FWAIT) == 0)
+           *obufp++ = 'n';
+         break;
+       case 'S':
+         /* operand size flag */
+         if (dflag)
+           *obufp++ = 'l';
+         else
+           *obufp++ = 'w';
+         break;
+       }
+    }
+  *obufp = 0;
+}
+
+static void
+oappend (s)
+char *s;
+{
+  strcpy (obufp, s);
+  obufp += strlen (s);
+  *obufp = 0;
+}
+
+append_prefix ()
+{
+  if (prefixes & PREFIX_CS)
+    oappend ("%cs:");
+  if (prefixes & PREFIX_DS)
+    oappend ("%ds:");
+  if (prefixes & PREFIX_SS)
+    oappend ("%ss:");
+  if (prefixes & PREFIX_ES)
+    oappend ("%es:");
+  if (prefixes & PREFIX_FS)
+    oappend ("%fs:");
+  if (prefixes & PREFIX_GS)
+    oappend ("%gs:");
+}
+
+OP_indirE (bytemode)
+{
+  oappend ("*");
+  OP_E (bytemode);
+}
+
+OP_E (bytemode)
+{
+  int disp;
+  int havesib;
+  int didoutput = 0;
+  int base;
+  int index;
+  int scale;
+  int havebase;
+  
+  /* skip mod/rm byte */
+  codep++;
+  
+  havesib = 0;
+  havebase = 0;
+  disp = 0;
+  
+  if (mod == 3)
+    {
+      switch (bytemode)
+       {
+       case b_mode:
+         oappend (names8[rm]);
+         break;
+       case w_mode:
+         oappend (names16[rm]);
+         break;
+       case v_mode:
+         if (dflag)
+           oappend (names32[rm]);
+         else
+           oappend (names16[rm]);
+         break;
+       default:
+         oappend ("<bad dis table>");
+         break;
+       }
+      return;
+    }
+  
+  append_prefix ();
+  if (rm == 4)
+    {
+      havesib = 1;
+      havebase = 1;
+      scale = (*codep >> 6) & 3;
+      index = (*codep >> 3) & 7;
+      base = *codep & 7;
+      codep++;
+    }
+  
+  switch (mod)
+    {
+    case 0:
+      switch (rm)
+       {
+       case 4:
+         /* implies havesib and havebase */
+         if (base == 5) {
+           havebase = 0;
+           disp = get32 ();
+         }
+         break;
+       case 5:
+         disp = get32 ();
+         break;
+       default:
+         havebase = 1;
+         base = rm;
+         break;
+       }
+      break;
+    case 1:
+      disp = *(char *)codep++;
+      if (rm != 4)
+       {
+         havebase = 1;
+         base = rm;
+       }
+      break;
+    case 2:
+      disp = get32 ();
+      if (rm != 4)
+       {
+         havebase = 1;
+         base = rm;
+       }
+      break;
+    }
+  
+  if (mod != 0 || rm == 5 || (havesib && base == 5))
+    {
+      sprintf (scratchbuf, "%d", disp);
+      oappend (scratchbuf);
+    }
+  
+  if (havebase || havesib) 
+    {
+      oappend ("(");
+      if (havebase)
+       oappend (names32[base]);
+      if (havesib) 
+       {
+         if (index != 4) 
+           {
+             sprintf (scratchbuf, ",%s", names32[index]);
+             oappend (scratchbuf);
+           }
+         sprintf (scratchbuf, ",%d", 1 << scale);
+         oappend (scratchbuf);
+       }
+      oappend (")");
+    }
+}
+
+OP_G (bytemode)
+{
+  switch (bytemode) 
+    {
+    case b_mode:
+      oappend (names8[reg]);
+      break;
+    case w_mode:
+      oappend (names16[reg]);
+      break;
+    case d_mode:
+      oappend (names32[reg]);
+      break;
+    case v_mode:
+      if (dflag)
+       oappend (names32[reg]);
+      else
+       oappend (names16[reg]);
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      break;
+    }
+}
+
+get32 ()
+{
+  int x = 0;
+  
+  x = *codep++ & 0xff;
+  x |= (*codep++ & 0xff) << 8;
+  x |= (*codep++ & 0xff) << 16;
+  x |= (*codep++ & 0xff) << 24;
+  return (x);
+}
+
+get16 ()
+{
+  int x = 0;
+  
+  x = *codep++ & 0xff;
+  x |= (*codep++ & 0xff) << 8;
+  return (x);
+}
+
+set_op (op)
+int op;
+{
+  op_index[op_ad] = op_ad;
+  op_address[op_ad] = op;
+}
+
+OP_REG (code)
+{
+  char *s;
+  
+  switch (code) 
+    {
+    case indir_dx_reg: s = "(%dx)"; break;
+       case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+       case sp_reg: case bp_reg: case si_reg: case di_reg:
+               s = names16[code - ax_reg];
+               break;
+       case es_reg: case ss_reg: case cs_reg:
+       case ds_reg: case fs_reg: case gs_reg:
+               s = names_seg[code - es_reg];
+               break;
+       case al_reg: case ah_reg: case cl_reg: case ch_reg:
+       case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+               s = names8[code - al_reg];
+               break;
+       case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+       case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+      if (dflag)
+       s = names32[code - eAX_reg];
+      else
+       s = names16[code - eAX_reg];
+      break;
+    default:
+      s = "<internal disassembler error>";
+      break;
+    }
+  oappend (s);
+}
+
+OP_I (bytemode)
+{
+  int op;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      op = *codep++ & 0xff;
+      break;
+    case v_mode:
+      if (dflag)
+       op = get32 ();
+      else
+       op = get16 ();
+      break;
+    case w_mode:
+      op = get16 ();
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return;
+    }
+  sprintf (scratchbuf, "$0x%x", op);
+  oappend (scratchbuf);
+}
+
+OP_sI (bytemode)
+{
+  int op;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      op = *(char *)codep++;
+      break;
+    case v_mode:
+      if (dflag)
+       op = get32 ();
+      else
+       op = (short)get16();
+      break;
+    case w_mode:
+      op = (short)get16 ();
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return;
+    }
+  sprintf (scratchbuf, "$0x%x", op);
+  oappend (scratchbuf);
+}
+
+OP_J (bytemode)
+{
+  int disp;
+  int mask = -1;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      disp = *(char *)codep++;
+      break;
+    case v_mode:
+      if (dflag)
+       disp = get32 ();
+      else
+       {
+         disp = (short)get16 ();
+         /* for some reason, a data16 prefix on a jump instruction
+            means that the pc is masked to 16 bits after the
+            displacement is added!  */
+         mask = 0xffff;
+       }
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return;
+    }
+  disp = (start_pc + codep - start_codep + disp) & mask;
+  set_op (disp);
+  sprintf (scratchbuf, "0x%x", disp);
+  oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+OP_SEG (dummy)
+{
+  static char *sreg[] = {
+    "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+  };
+
+  oappend (sreg[reg]);
+}
+
+OP_DIR (size)
+{
+  int seg, offset;
+  
+  switch (size) 
+    {
+    case lptr:
+      if (aflag) 
+       {
+         offset = get32 ();
+         seg = get16 ();
+       } 
+      else 
+       {
+         offset = get16 ();
+         seg = get16 ();
+       }
+      sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+      oappend (scratchbuf);
+      break;
+    case v_mode:
+      if (aflag)
+       offset = get32 ();
+      else
+       offset = (short)get16 ();
+      
+      offset = start_pc + codep - start_codep + offset;
+      set_op (offset);
+      sprintf (scratchbuf, "0x%x", offset);
+      oappend (scratchbuf);
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      break;
+    }
+}
+
+/* ARGSUSED */
+OP_OFF (bytemode)
+{
+  int off;
+  
+  if (aflag)
+    off = get32 ();
+  else
+    off = get16 ();
+  
+  sprintf (scratchbuf, "0x%x", off);
+  oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+OP_ESDI (dummy)
+{
+  oappend ("%es:(");
+  oappend (aflag ? "%edi" : "%di");
+  oappend (")");
+}
+
+/* ARGSUSED */
+OP_DSSI (dummy)
+{
+  oappend ("%ds:(");
+  oappend (aflag ? "%esi" : "%si");
+  oappend (")");
+}
+
+/* ARGSUSED */
+OP_ONE (dummy)
+{
+  oappend ("1");
+}
+
+/* ARGSUSED */
+OP_C (dummy)
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%cr%d", reg);
+  oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+OP_D (dummy)
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%db%d", reg);
+  oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+OP_T (dummy)
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%tr%d", reg);
+  oappend (scratchbuf);
+}
+
+OP_rm (bytemode)
+{
+  switch (bytemode) 
+    {
+    case d_mode:
+      oappend (names32[rm]);
+      break;
+    case w_mode:
+      oappend (names16[rm]);
+      break;
+    }
+}
+       
+/* GDB interface */
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+
+#define MAXLEN 20
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  
+  read_memory (memaddr, buffer, MAXLEN);
+  
+  return (i386dis ((int)memaddr, buffer, stream));
+}
+
diff --git a/gdb/i386-xdep.c b/gdb/i386-xdep.c
new file mode 100644 (file)
index 0000000..dddf22d
--- /dev/null
@@ -0,0 +1,357 @@
+/* Intel 386 stuff.
+   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "gdbcore.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <sys/reg.h>
+\f
+/* this table must line up with REGISTER_NAMES in m-i386.h */
+/* symbols like 'EAX' come from <sys/reg.h> */
+static int regmap[] = 
+{
+  EAX, ECX, EDX, EBX,
+  UESP, EBP, ESI, EDI,
+  EIP, EFL, CS, SS,
+  DS, ES, FS, GS,
+};
+
+/* blockend is the value of u.u_ar0, and points to the
+ * place where GS is stored
+ */
+i386_register_u_addr (blockend, regnum)
+{
+#if 0
+  /* this will be needed if fp registers are reinstated */
+  /* for now, you can look at them with 'info float'
+   * sys5 wont let you change them with ptrace anyway
+   */
+  if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) 
+    {
+      int ubase, fpstate;
+      struct user u;
+      ubase = blockend + 4 * (SS + 1) - KSTKSZ;
+      fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
+      return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
+    } 
+  else
+#endif
+    return (blockend + 4 * regmap[regnum]);
+  
+}
+
+/* This is broken for cross debugging.  Possible solutions are:
+
+1.  Don't worry about whether the thing compiles for cross-debugging.
+Go ahead and call them from i386-tdep.c.
+1a.  Same thing but use some macros in xm-i386.h so that gdb will
+compile for cross-debugging but just give an error (or some such behavior)
+when you attempt to convert floats.
+
+2.  Write a portable (in the sense of running on any machine; it would
+always be for i387 floating-point formats) extended<->double converter
+(which just deals with the values as arrays of char).
+
+3.  Assume the host machine has *some* IEEE chip.  However, IEEE does
+not standardize formats for extended floats (387 is 10 bytes, 68881 is
+12 bytes), so this won't work.  */
+
+i387_to_double (from, to)
+     char *from;
+     char *to;
+{
+  long *lp;
+  /* push extended mode on 387 stack, then pop in double mode
+   *
+   * first, set exception masks so no error is generated -
+   * number will be rounded to inf or 0, if necessary 
+   */
+  asm ("pushl %eax");          /* grab a stack slot */
+  asm ("fstcw (%esp)");                /* get 387 control word */
+  asm ("movl (%esp),%eax");    /* save old value */
+  asm ("orl $0x3f,%eax");              /* mask all exceptions */
+  asm ("pushl %eax");
+  asm ("fldcw (%esp)");                /* load new value into 387 */
+  
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldt (%eax)");         /* push extended number on 387 stack */
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpl (%eax)");                /* pop double */
+  asm ("fwait");
+  
+  asm ("popl %eax");           /* flush modified control word */
+  asm ("fnclex");                      /* clear exceptions */
+  asm ("fldcw (%esp)");                /* restore original control word */
+  asm ("popl %eax");           /* flush saved copy */
+}
+
+double_to_i387 (from, to)
+     char *from;
+     char *to;
+{
+  /* push double mode on 387 stack, then pop in extended mode
+   * no errors are possible because every 64-bit pattern
+   * can be converted to an extended
+   */
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldl (%eax)");
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpt (%eax)");
+  asm ("fwait");
+}
+
+struct env387 
+{
+  unsigned short control;
+  unsigned short r0;
+  unsigned short status;
+  unsigned short r1;
+  unsigned short tag;
+  unsigned short r2;
+  unsigned long eip;
+  unsigned short code_seg;
+  unsigned short opcode;
+  unsigned long operand;
+  unsigned short operand_seg;
+  unsigned short r3;
+  unsigned char regs[8][10];
+};
+
+static
+print_387_control_word (control)
+unsigned short control;
+{
+  printf ("control 0x%04x: ", control);
+  printf ("compute to ");
+  switch ((control >> 8) & 3) 
+    {
+    case 0: printf ("24 bits; "); break;
+    case 1: printf ("(bad); "); break;
+    case 2: printf ("53 bits; "); break;
+    case 3: printf ("64 bits; "); break;
+    }
+  printf ("round ");
+  switch ((control >> 10) & 3) 
+    {
+    case 0: printf ("NEAREST; "); break;
+    case 1: printf ("DOWN; "); break;
+    case 2: printf ("UP; "); break;
+    case 3: printf ("CHOP; "); break;
+    }
+  if (control & 0x3f) 
+    {
+      printf ("mask:");
+      if (control & 0x0001) printf (" INVALID");
+      if (control & 0x0002) printf (" DENORM");
+      if (control & 0x0004) printf (" DIVZ");
+      if (control & 0x0008) printf (" OVERF");
+      if (control & 0x0010) printf (" UNDERF");
+      if (control & 0x0020) printf (" LOS");
+      printf (";");
+    }
+  printf ("\n");
+  if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n",
+                               control & 0xe080);
+}
+
+static
+print_387_status_word (status)
+     unsigned short status;
+{
+  printf ("status 0x%04x: ", status);
+  if (status & 0xff) 
+    {
+      printf ("exceptions:");
+      if (status & 0x0001) printf (" INVALID");
+      if (status & 0x0002) printf (" DENORM");
+      if (status & 0x0004) printf (" DIVZ");
+      if (status & 0x0008) printf (" OVERF");
+      if (status & 0x0010) printf (" UNDERF");
+      if (status & 0x0020) printf (" LOS");
+      if (status & 0x0040) printf (" FPSTACK");
+      printf ("; ");
+    }
+  printf ("flags: %d%d%d%d; ",
+         (status & 0x4000) != 0,
+         (status & 0x0400) != 0,
+         (status & 0x0200) != 0,
+         (status & 0x0100) != 0);
+  
+  printf ("top %d\n", (status >> 11) & 7);
+}
+
+static
+print_387_status (status, ep)
+     unsigned short status;
+     struct env387 *ep;
+{
+  int i;
+  int bothstatus;
+  int top;
+  int fpreg;
+  unsigned char *p;
+  
+  bothstatus = ((status != 0) && (ep->status != 0));
+  if (status != 0) 
+    {
+      if (bothstatus)
+       printf ("u: ");
+      print_387_status_word (status);
+    }
+  
+  if (ep->status != 0) 
+    {
+      if (bothstatus)
+       printf ("e: ");
+      print_387_status_word (ep->status);
+    }
+  
+  print_387_control_word (ep->control);
+  printf ("last exception: ");
+  printf ("opcode 0x%x; ", ep->opcode);
+  printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip);
+  printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand);
+  
+  top = (ep->status >> 11) & 7;
+  
+  printf ("regno  tag  msb              lsb  value\n");
+  for (fpreg = 7; fpreg >= 0; fpreg--) 
+    {
+      double val;
+      
+      printf ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
+      
+      switch ((ep->tag >> (fpreg * 2)) & 3) 
+       {
+       case 0: printf ("valid "); break;
+       case 1: printf ("zero  "); break;
+       case 2: printf ("trap  "); break;
+       case 3: printf ("empty "); break;
+       }
+      for (i = 9; i >= 0; i--)
+       printf ("%02x", ep->regs[fpreg][i]);
+      
+      i387_to_double (ep->regs[fpreg], (char *)&val);
+      printf ("  %g\n", val);
+    }
+  if (ep->r0)
+    printf ("warning: reserved0 is 0x%x\n", ep->r0);
+  if (ep->r1)
+    printf ("warning: reserved1 is 0x%x\n", ep->r1);
+  if (ep->r2)
+    printf ("warning: reserved2 is 0x%x\n", ep->r2);
+  if (ep->r3)
+    printf ("warning: reserved3 is 0x%x\n", ep->r3);
+}
+
+#ifndef U_FPSTATE
+#define U_FPSTATE(u) u.u_fpstate
+#endif
+
+i386_float_info ()
+{
+  struct user u; /* just for address computations */
+  int i;
+  /* fpstate defined in <sys/user.h> */
+  struct fpstate *fpstatep;
+  char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
+  unsigned int uaddr;
+  char fpvalid;
+  unsigned int rounded_addr;
+  unsigned int rounded_size;
+  extern int corechan;
+  int skip;
+  
+  uaddr = (char *)&u.u_fpvalid - (char *)&u;
+  if (have_inferior_p()) 
+    {
+      unsigned int data;
+      unsigned int mask;
+      
+      rounded_addr = uaddr & -sizeof (int);
+      data = ptrace (3, inferior_pid, rounded_addr, 0);
+      mask = 0xff << ((uaddr - rounded_addr) * 8);
+      
+      fpvalid = ((data & mask) != 0);
+    } 
+  else 
+    {
+      if (lseek (corechan, uaddr, 0) < 0)
+       perror ("seek on core file");
+      if (myread (corechan, &fpvalid, 1) < 0) 
+       perror ("read on core file");
+      
+    }
+  
+  if (fpvalid == 0) 
+    {
+      printf ("no floating point status saved\n");
+      return;
+    }
+  
+  uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
+  if (have_inferior_p ()) 
+    {
+      int *ip;
+      
+      rounded_addr = uaddr & -sizeof (int);
+      rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
+                     sizeof (int) - 1) / sizeof (int);
+      skip = uaddr - rounded_addr;
+      
+      ip = (int *)buf;
+      for (i = 0; i < rounded_size; i++) 
+       {
+         *ip++ = ptrace (3, inferior_pid, rounded_addr, 0);
+         rounded_addr += sizeof (int);
+       }
+    } 
+  else 
+    {
+      if (lseek (corechan, uaddr, 0) < 0)
+       perror_with_name ("seek on core file");
+      if (myread (corechan, buf, sizeof (struct fpstate)) < 0) 
+       perror_with_name ("read from core file");
+      skip = 0;
+    }
+  
+  fpstatep = (struct fpstate *)(buf + skip);
+  print_387_status (fpstatep->status, (struct env387 *)fpstatep->state);
+}
+
diff --git a/gdb/i960-pinsn.c b/gdb/i960-pinsn.c
new file mode 100644 (file)
index 0000000..ea3fa64
--- /dev/null
@@ -0,0 +1,847 @@
+/* Disassemble i80960 instructions.
+ */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+extern char *reg_names[];
+
+static FILE *stream;           /* Output goes here */
+static void print_addr();
+static void ctrl();
+static void cobr();
+static void reg();
+static int mem();
+static void ea();
+static void dstop();
+static void regop();
+static void invalid();
+static int pinsn();
+static void put_abs();
+
+
+/* Print the i960 instruction at address 'memaddr' in debugged memory,
+   on stream 's'.  Returns length of the instruction, in bytes.  */
+int
+print_insn( memaddr, s )
+    CORE_ADDR memaddr;
+    FILE *s;
+{
+       unsigned int word1, word2;
+
+       stream = s;
+       word1 = read_memory_integer( memaddr, 4 );
+       word2 = read_memory_integer( memaddr+4, 4 );
+       return pinsn( memaddr, word1, word2 );
+}
+
+
+/* Read the i960 instruction at 'memaddr' and return the address of 
+   the next instruction after that, or 0 if 'memaddr' is not the
+   address of a valid instruction.  The first word of the instruction
+   is stored at 'pword1', and the second word, if any, is stored at
+   'pword2'.  */
+
+CORE_ADDR
+next_insn (memaddr, pword1, pword2)
+     unsigned long *pword1, *pword2;
+     CORE_ADDR memaddr;
+{
+  int len;
+  unsigned long buf[2];
+
+  /* Read the two (potential) words of the instruction at once,
+     to eliminate the overhead of two calls to read_memory ().
+     TODO: read more instructions at once and cache them.  */
+
+  read_memory (memaddr, buf, sizeof (buf));
+  *pword1 = buf[0];
+  SWAP_TARGET_AND_HOST (pword1, sizeof (long));
+  *pword2 = buf[1];
+  SWAP_TARGET_AND_HOST (pword2, sizeof (long));
+
+  /* Divide instruction set into classes based on high 4 bits of opcode*/
+
+  switch ((*pword1 >> 28) & 0xf)
+    {
+    case 0x0:
+    case 0x1:  /* ctrl */
+
+    case 0x2:
+    case 0x3:  /* cobr */
+
+    case 0x5:
+    case 0x6:
+    case 0x7:  /* reg */
+      len = 4;
+      break;
+
+    case 0x8:
+    case 0x9:
+    case 0xa:
+    case 0xb:
+    case 0xc:
+      len = mem (memaddr, *pword1, *pword2, 1);
+      break;
+
+    default:   /* invalid instruction */
+      len = 0;
+      break;
+    }
+
+  if (len)
+    return memaddr + len;
+  else
+    return 0;
+}
+\f
+#define IN_GDB
+
+/*****************************************************************************
+ *     All code below this point should be identical with that of
+ *     the disassembler in gdmp960.
+ *****************************************************************************/
+
+struct tabent {
+       char    *name;
+       char    numops;
+};
+
+static int
+pinsn( memaddr, word1, word2 )
+    unsigned long memaddr;
+    unsigned long word1, word2;
+{
+       int instr_len;
+
+       instr_len = 4;
+       put_abs( word1, word2 );
+
+       /* Divide instruction set into classes based on high 4 bits of opcode*/
+
+       switch ( (word1 >> 28) & 0xf ){
+       case 0x0:
+       case 0x1:
+               ctrl( memaddr, word1, word2 );
+               break;
+       case 0x2:
+       case 0x3:
+               cobr( memaddr, word1, word2 );
+               break;
+       case 0x5:
+       case 0x6:
+       case 0x7:
+               reg( word1 );
+               break;
+       case 0x8:
+       case 0x9:
+       case 0xa:
+       case 0xb:
+       case 0xc:
+               instr_len = mem( memaddr, word1, word2, 0 );
+               break;
+       default:
+               /* invalid instruction, print as data word */ 
+               invalid( word1 );
+               break;
+       }
+       return instr_len;
+}
+
+/****************************************/
+/* CTRL format                         */
+/****************************************/
+static void
+ctrl( memaddr, word1, word2 )
+    unsigned long memaddr;
+    unsigned long word1, word2;
+{
+       int i;
+       static struct tabent ctrl_tab[] = {
+               NULL,           0,      /* 0x00 */
+               NULL,           0,      /* 0x01 */
+               NULL,           0,      /* 0x02 */
+               NULL,           0,      /* 0x03 */
+               NULL,           0,      /* 0x04 */
+               NULL,           0,      /* 0x05 */
+               NULL,           0,      /* 0x06 */
+               NULL,           0,      /* 0x07 */
+               "b",            1,      /* 0x08 */
+               "call",         1,      /* 0x09 */
+               "ret",          0,      /* 0x0a */
+               "bal",          1,      /* 0x0b */
+               NULL,           0,      /* 0x0c */
+               NULL,           0,      /* 0x0d */
+               NULL,           0,      /* 0x0e */
+               NULL,           0,      /* 0x0f */
+               "bno",          1,      /* 0x10 */
+               "bg",           1,      /* 0x11 */
+               "be",           1,      /* 0x12 */
+               "bge",          1,      /* 0x13 */
+               "bl",           1,      /* 0x14 */
+               "bne",          1,      /* 0x15 */
+               "ble",          1,      /* 0x16 */
+               "bo",           1,      /* 0x17 */
+               "faultno",      0,      /* 0x18 */
+               "faultg",       0,      /* 0x19 */
+               "faulte",       0,      /* 0x1a */
+               "faultge",      0,      /* 0x1b */
+               "faultl",       0,      /* 0x1c */
+               "faultne",      0,      /* 0x1d */
+               "faultle",      0,      /* 0x1e */
+               "faulto",       0,      /* 0x1f */
+       };
+
+       i = (word1 >> 24) & 0xff;
+       if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){
+               invalid( word1 );
+               return;
+       }
+
+       fputs( ctrl_tab[i].name, stream );
+       if ( word1 & 2 ){               /* Predicts branch not taken */
+               fputs( ".f", stream );
+       }
+
+       if ( ctrl_tab[i].numops == 1 ){
+               /* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */
+               word1 &= 0x00ffffff;
+               if ( word1 & 0x00800000 ){              /* Sign bit is set */
+                       word1 |= (-1 & ~0xffffff);      /* Sign extend */
+               }
+               putc( '\t', stream );
+               print_addr( word1 + memaddr );
+       }
+}
+
+/****************************************/
+/* COBR format                         */
+/****************************************/
+static void
+cobr( memaddr, word1, word2 )
+    unsigned long memaddr;
+    unsigned long word1, word2;
+{
+       int src1;
+       int src2;
+       int i;
+
+       static struct tabent cobr_tab[] = {
+               "testno",       1,      /* 0x20 */
+               "testg",        1,      /* 0x21 */
+               "teste",        1,      /* 0x22 */
+               "testge",       1,      /* 0x23 */
+               "testl",        1,      /* 0x24 */
+               "testne",       1,      /* 0x25 */
+               "testle",       1,      /* 0x26 */
+               "testo",        1,      /* 0x27 */
+               NULL,           0,      /* 0x28 */
+               NULL,           0,      /* 0x29 */
+               NULL,           0,      /* 0x2a */
+               NULL,           0,      /* 0x2b */
+               NULL,           0,      /* 0x2c */
+               NULL,           0,      /* 0x2d */
+               NULL,           0,      /* 0x2e */
+               NULL,           0,      /* 0x2f */
+               "bbc",          3,      /* 0x30 */
+               "cmpobg",       3,      /* 0x31 */
+               "cmpobe",       3,      /* 0x32 */
+               "cmpobge",      3,      /* 0x33 */
+               "cmpobl",       3,      /* 0x34 */
+               "cmpobne",      3,      /* 0x35 */
+               "cmpoble",      3,      /* 0x36 */
+               "bbs",          3,      /* 0x37 */
+               "cmpibno",      3,      /* 0x38 */
+               "cmpibg",       3,      /* 0x39 */
+               "cmpibe",       3,      /* 0x3a */
+               "cmpibge",      3,      /* 0x3b */
+               "cmpibl",       3,      /* 0x3c */
+               "cmpibne",      3,      /* 0x3d */
+               "cmpible",      3,      /* 0x3e */
+               "cmpibo",       3,      /* 0x3f */
+       };
+
+       i = ((word1 >> 24) & 0xff) - 0x20;
+       if ( cobr_tab[i].name == NULL ){
+               invalid( word1 );
+               return;
+       }
+
+       fputs( cobr_tab[i].name, stream );
+       if ( word1 & 2 ){               /* Predicts branch not taken */
+               fputs( ".f", stream );
+       }
+       putc( '\t', stream );
+
+       src1 = (word1 >> 19) & 0x1f;
+       src2 = (word1 >> 14) & 0x1f;
+
+       if ( word1 & 0x02000 ){         /* M1 is 1 */
+               fprintf( stream, "%d", src1 );
+       } else {                        /* M1 is 0 */
+               fputs( reg_names[src1], stream );
+       }
+
+       if ( cobr_tab[i].numops > 1 ){
+               if ( word1 & 1 ){               /* S2 is 1 */
+                       fprintf( stream, ",sf%d,", src2 );
+               } else {                        /* S1 is 0 */
+                       fprintf( stream, ",%s,", reg_names[src2] );
+               }
+
+               /* Extract displacement and convert to address
+                */
+               word1 &= 0x00001ffc;
+               if ( word1 & 0x00001000 ){      /* Negative displacement */
+                       word1 |= (-1 & ~0x1fff);        /* Sign extend */
+               }
+               print_addr( memaddr + word1 );
+       }
+}
+
+/****************************************/
+/* MEM format                          */
+/****************************************/
+static int                             /* returns instruction length: 4 or 8 */
+mem( memaddr, word1, word2, noprint )
+    unsigned long memaddr;
+    unsigned long word1, word2;
+    int noprint;               /* If TRUE, return instruction length, but
+                                  don't output any text.  */
+{
+       int i, j;
+       int len;
+       int mode;
+       int offset;
+       char *reg1, *reg2, *reg3;
+
+       /* This lookup table is too sparse to make it worth typing in, but not
+        * so large as to make a sparse array necessary.  We allocate the
+        * table at runtime, initialize all entries to empty, and copy the
+        * real ones in from an initialization table.
+        *
+        * NOTE: In this table, the meaning of 'numops' is:
+        *       1: single operand
+        *       2: 2 operands, load instruction
+        *      -2: 2 operands, store instruction
+        */
+       static struct tabent *mem_tab = NULL;
+       static struct { int opcode; char *name; char numops; } mem_init[] = {
+#define MEM_MIN        0x80
+               0x80,   "ldob",  2,
+               0x82,   "stob", -2,
+               0x84,   "bx",    1,
+               0x85,   "balx",  2,
+               0x86,   "callx", 1,
+               0x88,   "ldos",  2,
+               0x8a,   "stos", -2,
+               0x8c,   "lda",   2,
+               0x90,   "ld",    2,
+               0x92,   "st",   -2,
+               0x98,   "ldl",   2,
+               0x9a,   "stl",  -2,
+               0xa0,   "ldt",   2,
+               0xa2,   "stt",  -2,
+               0xb0,   "ldq",   2,
+               0xb2,   "stq",  -2,
+               0xc0,   "ldib",  2,
+               0xc2,   "stib", -2,
+               0xc8,   "ldis",  2,
+               0xca,   "stis", -2,
+#define MEM_MAX        0xca
+#define MEM_SIZ        ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
+               0,      NULL,   0
+       };
+
+       if ( mem_tab == NULL ){
+               mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
+               bzero( mem_tab, MEM_SIZ );
+               for ( i = 0; mem_init[i].opcode != 0; i++ ){
+                       j = mem_init[i].opcode - MEM_MIN;
+                       mem_tab[j].name = mem_init[i].name;
+                       mem_tab[j].numops = mem_init[i].numops;
+               }
+       }
+
+       i = ((word1 >> 24) & 0xff) - MEM_MIN;
+       mode = (word1 >> 10) & 0xf;
+
+       if ( (mem_tab[i].name != NULL)          /* Valid instruction */
+       &&   ((mode == 5) || (mode >=12)) ){    /* With 32-bit displacement */
+               len = 8;
+       } else {
+               len = 4;
+       }
+
+       if ( noprint ){
+               return len;
+       }
+
+       if ( (mem_tab[i].name == NULL) || (mode == 6) ){
+               invalid( word1 );
+               return len;
+       }
+
+       fprintf( stream, "%s\t", mem_tab[i].name );
+
+       reg1 = reg_names[ (word1 >> 19) & 0x1f ];       /* MEMB only */
+       reg2 = reg_names[ (word1 >> 14) & 0x1f ];
+       reg3 = reg_names[ word1 & 0x1f ];               /* MEMB only */
+       offset = word1 & 0xfff;                         /* MEMA only  */
+
+       switch ( mem_tab[i].numops ){
+
+       case 2: /* LOAD INSTRUCTION */
+               if ( mode & 4 ){                        /* MEMB FORMAT */
+                       ea( memaddr, mode, reg2, reg3, word1, word2 );
+                       fprintf( stream, ",%s", reg1 );
+               } else {                                /* MEMA FORMAT */
+                       fprintf( stream, "0x%x", offset );
+                       if (mode & 8) {
+                               fprintf( stream, "(%s)", reg2 );
+                       }
+                       fprintf( stream, ",%s", reg1 );
+               }
+               break;
+
+       case -2: /* STORE INSTRUCTION */
+               if ( mode & 4 ){                        /* MEMB FORMAT */
+                       fprintf( stream, "%s,", reg1 );
+                       ea( memaddr, mode, reg2, reg3, word1, word2 );
+               } else {                                /* MEMA FORMAT */
+                       fprintf( stream, "%s,0x%x", reg1, offset );
+                       if (mode & 8) {
+                               fprintf( stream, "(%s)", reg2 );
+                       }
+               }
+               break;
+
+       case 1: /* BX/CALLX INSTRUCTION */
+               if ( mode & 4 ){                        /* MEMB FORMAT */
+                       ea( memaddr, mode, reg2, reg3, word1, word2 );
+               } else {                                /* MEMA FORMAT */
+                       fprintf( stream, "0x%x", offset );
+                       if (mode & 8) {
+                               fprintf( stream, "(%s)", reg2 );
+                       }
+               }
+               break;
+       }
+
+       return len;
+}
+
+/****************************************/
+/* REG format                          */
+/****************************************/
+static void
+reg( word1 )
+    unsigned long word1;
+{
+       int i, j;
+       int opcode;
+       int fp;
+       int m1, m2, m3;
+       int s1, s2;
+       int src, src2, dst;
+       char *mnemp;
+
+       /* This lookup table is too sparse to make it worth typing in, but not
+        * so large as to make a sparse array necessary.  We allocate the
+        * table at runtime, initialize all entries to empty, and copy the
+        * real ones in from an initialization table.
+        *
+        * NOTE: In this table, the meaning of 'numops' is:
+        *       1: single operand, which is NOT a destination.
+        *      -1: single operand, which IS a destination.
+        *       2: 2 operands, the 2nd of which is NOT a destination.
+        *      -2: 2 operands, the 2nd of which IS a destination.
+        *       3: 3 operands
+        *
+        *      If an opcode mnemonic begins with "F", it is a floating-point
+        *      opcode (the "F" is not printed).
+        */
+
+       static struct tabent *reg_tab = NULL;
+       static struct { int opcode; char *name; char numops; } reg_init[] = {
+#define REG_MIN        0x580
+               0x580,  "notbit",       3,
+               0x581,  "and",          3,
+               0x582,  "andnot",       3,
+               0x583,  "setbit",       3,
+               0x584,  "notand",       3,
+               0x586,  "xor",          3,
+               0x587,  "or",           3,
+               0x588,  "nor",          3,
+               0x589,  "xnor",         3,
+               0x58a,  "not",          -2,
+               0x58b,  "ornot",        3,
+               0x58c,  "clrbit",       3,
+               0x58d,  "notor",        3,
+               0x58e,  "nand",         3,
+               0x58f,  "alterbit",     3,
+               0x590,  "addo",         3,
+               0x591,  "addi",         3,
+               0x592,  "subo",         3,
+               0x593,  "subi",         3,
+               0x598,  "shro",         3,
+               0x59a,  "shrdi",        3,
+               0x59b,  "shri",         3,
+               0x59c,  "shlo",         3,
+               0x59d,  "rotate",       3,
+               0x59e,  "shli",         3,
+               0x5a0,  "cmpo",         2,
+               0x5a1,  "cmpi",         2,
+               0x5a2,  "concmpo",      2,
+               0x5a3,  "concmpi",      2,
+               0x5a4,  "cmpinco",      3,
+               0x5a5,  "cmpinci",      3,
+               0x5a6,  "cmpdeco",      3,
+               0x5a7,  "cmpdeci",      3,
+               0x5ac,  "scanbyte",     2,
+               0x5ae,  "chkbit",       2,
+               0x5b0,  "addc",         3,
+               0x5b2,  "subc",         3,
+               0x5cc,  "mov",          -2,
+               0x5d8,  "eshro",        3,
+               0x5dc,  "movl",         -2,
+               0x5ec,  "movt",         -2,
+               0x5fc,  "movq",         -2,
+               0x600,  "synmov",       2,
+               0x601,  "synmovl",      2,
+               0x602,  "synmovq",      2,
+               0x603,  "cmpstr",       3,
+               0x604,  "movqstr",      3,
+               0x605,  "movstr",       3,
+               0x610,  "atmod",        3,
+               0x612,  "atadd",        3,
+               0x613,  "inspacc",      -2,
+               0x614,  "ldphy",        -2,
+               0x615,  "synld",        -2,
+               0x617,  "fill",         3,
+               0x630,  "sdma",         3,
+               0x631,  "udma",         0,
+               0x640,  "spanbit",      -2,
+               0x641,  "scanbit",      -2,
+               0x642,  "daddc",        3,
+               0x643,  "dsubc",        3,
+               0x644,  "dmovt",        -2,
+               0x645,  "modac",        3,
+               0x646,  "condrec",      -2,
+               0x650,  "modify",       3,
+               0x651,  "extract",      3,
+               0x654,  "modtc",        3,
+               0x655,  "modpc",        3,
+               0x656,  "receive",      -2,
+               0x659,  "sysctl",       3,
+               0x660,  "calls",        1,
+               0x662,  "send",         3,
+               0x663,  "sendserv",     1,
+               0x664,  "resumprcs",    1,
+               0x665,  "schedprcs",    1,
+               0x666,  "saveprcs",     0,
+               0x668,  "condwait",     1,
+               0x669,  "wait",         1,
+               0x66a,  "signal",       1,
+               0x66b,  "mark",         0,
+               0x66c,  "fmark",        0,
+               0x66d,  "flushreg",     0,
+               0x66f,  "syncf",        0,
+               0x670,  "emul",         3,
+               0x671,  "ediv",         3,
+               0x673,  "ldtime",       -1,
+               0x674,  "Fcvtir",       -2,
+               0x675,  "Fcvtilr",      -2,
+               0x676,  "Fscalerl",     3,
+               0x677,  "Fscaler",      3,
+               0x680,  "Fatanr",       3,
+               0x681,  "Flogepr",      3,
+               0x682,  "Flogr",        3,
+               0x683,  "Fremr",        3,
+               0x684,  "Fcmpor",       2,
+               0x685,  "Fcmpr",        2,
+               0x688,  "Fsqrtr",       -2,
+               0x689,  "Fexpr",        -2,
+               0x68a,  "Flogbnr",      -2,
+               0x68b,  "Froundr",      -2,
+               0x68c,  "Fsinr",        -2,
+               0x68d,  "Fcosr",        -2,
+               0x68e,  "Ftanr",        -2,
+               0x68f,  "Fclassr",      1,
+               0x690,  "Fatanrl",      3,
+               0x691,  "Flogeprl",     3,
+               0x692,  "Flogrl",       3,
+               0x693,  "Fremrl",       3,
+               0x694,  "Fcmporl",      2,
+               0x695,  "Fcmprl",       2,
+               0x698,  "Fsqrtrl",      -2,
+               0x699,  "Fexprl",       -2,
+               0x69a,  "Flogbnrl",     -2,
+               0x69b,  "Froundrl",     -2,
+               0x69c,  "Fsinrl",       -2,
+               0x69d,  "Fcosrl",       -2,
+               0x69e,  "Ftanrl",       -2,
+               0x69f,  "Fclassrl",     1,
+               0x6c0,  "Fcvtri",       -2,
+               0x6c1,  "Fcvtril",      -2,
+               0x6c2,  "Fcvtzri",      -2,
+               0x6c3,  "Fcvtzril",     -2,
+               0x6c9,  "Fmovr",        -2,
+               0x6d9,  "Fmovrl",       -2,
+               0x6e1,  "Fmovre",       -2,
+               0x6e2,  "Fcpysre",      3,
+               0x6e3,  "Fcpyrsre",     3,
+               0x701,  "mulo",         3,
+               0x708,  "remo",         3,
+               0x70b,  "divo",         3,
+               0x741,  "muli",         3,
+               0x748,  "remi",         3,
+               0x749,  "modi",         3,
+               0x74b,  "divi",         3,
+               0x78b,  "Fdivr",        3,
+               0x78c,  "Fmulr",        3,
+               0x78d,  "Fsubr",        3,
+               0x78f,  "Faddr",        3,
+               0x79b,  "Fdivrl",       3,
+               0x79c,  "Fmulrl",       3,
+               0x79d,  "Fsubrl",       3,
+               0x79f,  "Faddrl",       3,
+#define REG_MAX        0x79f
+#define REG_SIZ        ((REG_MAX-REG_MIN+1) * sizeof(struct tabent))
+               0,      NULL,   0
+       };
+
+       if ( reg_tab == NULL ){
+               reg_tab = (struct tabent *) xmalloc( REG_SIZ );
+               bzero( reg_tab, REG_SIZ );
+               for ( i = 0; reg_init[i].opcode != 0; i++ ){
+                       j = reg_init[i].opcode - REG_MIN;
+                       reg_tab[j].name = reg_init[i].name;
+                       reg_tab[j].numops = reg_init[i].numops;
+               }
+       }
+
+       opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
+       i = opcode - REG_MIN;
+
+       if ( (opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL) ){
+               invalid( word1 );
+               return;
+       }
+
+       mnemp = reg_tab[i].name;
+       if ( *mnemp == 'F' ){
+               fp = 1;
+               mnemp++;
+       } else {
+               fp = 0;
+       }
+
+       fputs( mnemp, stream );
+
+       s1   = (word1 >> 5)  & 1;
+       s2   = (word1 >> 6)  & 1;
+       m1   = (word1 >> 11) & 1;
+       m2   = (word1 >> 12) & 1;
+       m3   = (word1 >> 13) & 1;
+       src  =  word1        & 0x1f;
+       src2 = (word1 >> 14) & 0x1f;
+       dst  = (word1 >> 19) & 0x1f;
+
+       if  ( reg_tab[i].numops != 0 ){
+               putc( '\t', stream );
+
+               switch ( reg_tab[i].numops ){
+               case 1:
+                       regop( m1, s1, src, fp );
+                       break;
+               case -1:
+                       dstop( m3, dst, fp );
+                       break;
+               case 2:
+                       regop( m1, s1, src, fp );
+                       putc( ',', stream );
+                       regop( m2, s2, src2, fp );
+                       break;
+               case -2:
+                       regop( m1, s1, src, fp );
+                       putc( ',', stream );
+                       dstop( m3, dst, fp );
+                       break;
+               case 3:
+                       regop( m1, s1, src, fp );
+                       putc( ',', stream );
+                       regop( m2, s2, src2, fp );
+                       putc( ',', stream );
+                       dstop( m3, dst, fp );
+                       break;
+               }
+       }
+}
+
+
+/*
+ * Print out effective address for memb instructions.
+ */
+static void
+ea( memaddr, mode, reg2, reg3, word1, word2 )
+    unsigned long memaddr;
+    int mode;
+    char *reg2, *reg3;
+    unsigned int word2;
+{
+       int scale;
+       static int scale_tab[] = { 1, 2, 4, 8, 16 };
+
+       scale = (word1 >> 7) & 0x07;
+       if ( (scale > 4) || ((word1 >> 5) & 0x03 != 0) ){
+               invalid( word1 );
+               return;
+       }
+       scale = scale_tab[scale];
+
+       switch (mode) {
+       case 4:                                         /* (reg) */
+               fprintf( stream, "(%s)", reg2 );
+               break;
+       case 5:                                         /* displ+8(ip) */
+               print_addr( word2+8+memaddr );
+               break;
+       case 7:                                         /* (reg)[index*scale] */
+               if (scale == 1) {
+                       fprintf( stream, "(%s)[%s]", reg2, reg3 );
+               } else {
+                       fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale);
+               }
+               break;
+       case 12:                                        /* displacement */
+               print_addr( word2 );
+               break;
+       case 13:                                        /* displ(reg) */
+               print_addr( word2 );
+               fprintf( stream, "(%s)", reg2 );
+               break;
+       case 14:                                        /* displ[index*scale] */
+               print_addr( word2 );
+               if (scale == 1) {
+                       fprintf( stream, "[%s]", reg3 );
+               } else {
+                       fprintf( stream, "[%s*%d]", reg3, scale );
+               }
+               break;
+       case 15:                                /* displ(reg)[index*scale] */
+               print_addr( word2 );
+               if (scale == 1) {
+                       fprintf( stream, "(%s)[%s]", reg2, reg3 );
+               } else {
+                       fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale );
+               }
+               break;
+       default:
+               invalid( word1 );
+               return;
+       }
+}
+
+
+/************************************************/
+/* Register Instruction Operand                */
+/************************************************/
+static void
+regop( mode, spec, reg, fp )
+    int mode, spec, reg, fp;
+{
+       if ( fp ){                              /* FLOATING POINT INSTRUCTION */
+               if ( mode == 1 ){                       /* FP operand */
+                       switch ( reg ){
+                       case 0:  fputs( "fp0", stream );        break;
+                       case 1:  fputs( "fp1", stream );        break;
+                       case 2:  fputs( "fp2", stream );        break;
+                       case 3:  fputs( "fp3", stream );        break;
+                       case 16: fputs( "0f0.0", stream );      break;
+                       case 22: fputs( "0f1.0", stream );      break;
+                       default: putc( '?', stream );           break;
+                       }
+               } else {                                /* Non-FP register */
+                       fputs( reg_names[reg], stream );
+               }
+       } else {                                /* NOT FLOATING POINT */
+               if ( mode == 1 ){                       /* Literal */
+                       fprintf( stream, "%d", reg );
+               } else {                                /* Register */
+                       if ( spec == 0 ){
+                               fputs( reg_names[reg], stream );
+                       } else {
+                               fprintf( stream, "sf%d", reg );
+                       }
+               }
+       }
+}
+
+/************************************************/
+/* Register Instruction Destination Operand    */
+/************************************************/
+static void
+dstop( mode, reg, fp )
+    int mode, reg, fp;
+{
+       /* 'dst' operand can't be a literal. On non-FP instructions,  register
+        * mode is assumed and "m3" acts as if were "s3";  on FP-instructions,
+        * sf registers are not allowed so m3 acts normally.
+        */
+        if ( fp ){
+               regop( mode, 0, reg, fp );
+        } else {
+               regop( 0, mode, reg, fp );
+        }
+}
+
+
+static void
+invalid( word1 )
+    int word1;
+{
+       fprintf( stream, ".word\t0x%08x", word1 );
+}      
+
+static void
+print_addr(a)
+{
+       fprintf( stream, "0x%x", a );
+}
+
+static void
+put_abs( word1, word2 )
+    unsigned long word1, word2;
+{
+#ifdef IN_GDB
+       return;
+#else
+       int len;
+
+       switch ( (word1 >> 28) & 0xf ){
+       case 0x8:
+       case 0x9:
+       case 0xa:
+       case 0xb:
+       case 0xc:
+               /* MEM format instruction */
+               len = mem( 0, word1, word2, 1 );
+               break;
+       default:
+               len = 4;
+               break;
+       }
+
+       if ( len == 8 ){
+               fprintf( stream, "%08x %08x\t", word1, word2 );
+       } else {
+               fprintf( stream, "%08x         \t", word1 );
+       }
+;
+
+#endif
+}
diff --git a/gdb/i960-tdep.c b/gdb/i960-tdep.c
new file mode 100644 (file)
index 0000000..a82328a
--- /dev/null
@@ -0,0 +1,646 @@
+/* Target-machine dependent code for the Intel 960
+   Copyright (C) 1991 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.
+   examine_prologue and other parts contributed by Wind River Systems.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Miscellaneous i80960-dependent routines.
+   Most are called from macros defined in "tm-i960.h".  */
+
+#include <stdio.h>
+#include <signal.h>
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "value.h"
+#include "frame.h"
+#include "signame.h"
+#include "ieee-float.h"
+
+/* Structure of i960 extended floating point format.  */
+
+const struct ext_format ext_format_i960 [] = {
+/* tot sbyte smask expbyte manbyte */
+ { 12, 9,    0x80, 9,8,           4,0  },              /* i960 */
+};
+
+/* gdb960 is always running on a non-960 host.  Check its characteristics.
+   This routine must be called as part of gdb initialization.  */
+
+static void
+check_host()
+{
+       int i;
+
+       static struct typestruct {
+               int hostsize;           /* Size of type on host         */
+               int i960size;           /* Size of type on i960         */
+               char *typename;         /* Name of type, for error msg  */
+       } types[] = {
+               { sizeof(short),  2, "short" },
+               { sizeof(int),    4, "int" },
+               { sizeof(long),   4, "long" },
+               { sizeof(float),  4, "float" },
+               { sizeof(double), 8, "double" },
+               { sizeof(char *), 4, "pointer" },
+       };
+#define TYPELEN        (sizeof(types) / sizeof(struct typestruct))
+
+       /* Make sure that host type sizes are same as i960
+        */
+       for ( i = 0; i < TYPELEN; i++ ){
+               if ( types[i].hostsize != types[i].i960size ){
+                       printf("sizeof(%s) != %d:  PROCEED AT YOUR OWN RISK!\n",
+                                       types[i].typename, types[i].i960size );
+               }
+
+       }
+}
+\f
+/* Examine an i960 function prologue, recording the addresses at which
+   registers are saved explicitly by the prologue code, and returning
+   the address of the first instruction after the prologue (but not
+   after the instruction at address LIMIT, as explained below).
+
+   LIMIT places an upper bound on addresses of the instructions to be
+   examined.  If the prologue code scan reaches LIMIT, the scan is
+   aborted and LIMIT is returned.  This is used, when examining the
+   prologue for the current frame, to keep examine_prologue () from
+   claiming that a given register has been saved when in fact the
+   instruction that saves it has not yet been executed.  LIMIT is used
+   at other times to stop the scan when we hit code after the true
+   function prologue (e.g. for the first source line) which might
+   otherwise be mistaken for function prologue.
+
+   The format of the function prologue matched by this routine is
+   derived from examination of the source to gcc960 1.21, particularly
+   the routine i960_function_prologue ().  A "regular expression" for
+   the function prologue is given below:
+
+   (lda LRn, g14
+    mov g14, g[0-7]
+    (mov 0, g14) | (lda 0, g14))?
+
+   (mov[qtl]? g[0-15], r[4-15])*
+   ((addo [1-31], sp, sp) | (lda n(sp), sp))?
+   (st[qtl]? g[0-15], n(fp))*
+
+   (cmpobne 0, g14, LFn
+    mov sp, g14
+    lda 0x30(sp), sp
+    LFn: stq g0, (g14)
+    stq g4, 0x10(g14)
+    stq g8, 0x20(g14))?
+
+   (st g14, n(fp))?
+   (mov g13,r[4-15])?
+*/
+
+/* Macros for extracting fields from i960 instructions.  */
+
+#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
+#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
+
+#define REG_SRC1(insn)    EXTRACT_FIELD (insn, 0, 5)
+#define REG_SRC2(insn)    EXTRACT_FIELD (insn, 14, 5)
+#define REG_SRCDST(insn)  EXTRACT_FIELD (insn, 19, 5)
+#define MEM_SRCDST(insn)  EXTRACT_FIELD (insn, 19, 5)
+#define MEMA_OFFSET(insn) EXTRACT_FIELD (insn, 0, 12)
+
+/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
+   is not the address of a valid instruction, the address of the next
+   instruction beyond ADDR otherwise.  *PWORD1 receives the first word
+   of the instruction, and (for two-word instructions), *PWORD2 receives
+   the second.  */
+
+#define NEXT_PROLOGUE_INSN(addr, lim, pword1, pword2) \
+  (((addr) < (lim)) ? next_insn (addr, pword1, pword2) : 0)
+
+static CORE_ADDR
+examine_prologue (ip, limit, frame_addr, fsr)
+     register CORE_ADDR ip;
+     register CORE_ADDR limit;
+     FRAME_ADDR frame_addr;
+     struct frame_saved_regs *fsr;
+{
+  register CORE_ADDR next_ip;
+  register int src, dst;
+  register unsigned int *pcode;
+  unsigned int insn1, insn2;
+  int size;
+  int within_leaf_prologue;
+  CORE_ADDR save_addr;
+  static unsigned int varargs_prologue_code [] =
+    {
+       0x3507a00c,     /* cmpobne 0x0, g14, LFn */
+       0x5cf01601,     /* mov sp, g14           */
+       0x8c086030,     /* lda 0x30(sp), sp      */
+       0xb2879000,     /* LFn: stq  g0, (g14)   */
+       0xb2a7a010,     /* stq g4, 0x10(g14)     */
+       0xb2c7a020      /* stq g8, 0x20(g14)     */
+    };
+
+  /* Accept a leaf procedure prologue code fragment if present.
+     Note that ip might point to either the leaf or non-leaf
+     entry point; we look for the non-leaf entry point first:  */
+
+  within_leaf_prologue = 0;
+  if ((next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2))
+      && ((insn1 & 0xfffff000) == 0x8cf00000         /* lda LRx, g14 (MEMA) */
+         || (insn1 & 0xfffffc60) == 0x8cf03000))    /* lda LRx, g14 (MEMB) */
+    {
+      within_leaf_prologue = 1;
+      next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn1, &insn2);
+    }
+
+  /* Now look for the prologue code at a leaf entry point:  */
+
+  if (next_ip
+      && (insn1 & 0xff87ffff) == 0x5c80161e         /* mov g14, gx */
+      && REG_SRCDST (insn1) <= G0_REGNUM + 7)
+    {
+      within_leaf_prologue = 1;
+      if ((next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn1, &insn2))
+         && (insn1 == 0x8cf00000                   /* lda 0, g14 */
+             || insn1 == 0x5cf01e00))              /* mov 0, g14 */
+       {
+         ip = next_ip;
+         next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+         within_leaf_prologue = 0;
+       }
+    }
+
+  /* If something that looks like the beginning of a leaf prologue
+     has been seen, but the remainder of the prologue is missing, bail.
+     We don't know what we've got.  */
+
+  if (within_leaf_prologue)
+    return (ip);
+         
+  /* Accept zero or more instances of "mov[qtl]? gx, ry", where y >= 4.
+     This may cause us to mistake the moving of a register
+     parameter to a local register for the saving of a callee-saved
+     register, but that can't be helped, since with the
+     "-fcall-saved" flag, any register can be made callee-saved.  */
+
+  while (next_ip
+        && (insn1 & 0xfc802fb0) == 0x5c000610
+        && (dst = REG_SRCDST (insn1)) >= (R0_REGNUM + 4))
+    {
+      src = REG_SRC1 (insn1);
+      size = EXTRACT_FIELD (insn1, 24, 2) + 1;
+      save_addr = frame_addr + ((dst - R0_REGNUM) * 4);
+      while (size--)
+       {
+         fsr->regs[src++] = save_addr;
+         save_addr += 4;
+       }
+      ip = next_ip;
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+    }
+
+  /* Accept an optional "addo n, sp, sp" or "lda n(sp), sp".  */
+
+  if (next_ip &&
+      ((insn1 & 0xffffffe0) == 0x59084800      /* addo n, sp, sp */
+       || (insn1 & 0xfffff000) == 0x8c086000   /* lda n(sp), sp (MEMA) */
+       || (insn1 & 0xfffffc60) == 0x8c087400)) /* lda n(sp), sp (MEMB) */
+    {
+      ip = next_ip;
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+    }
+
+  /* Accept zero or more instances of "st[qtl]? gx, n(fp)".  
+     This may cause us to mistake the copying of a register
+     parameter to the frame for the saving of a callee-saved
+     register, but that can't be helped, since with the
+     "-fcall-saved" flag, any register can be made callee-saved.
+     We can, however, refuse to accept a save of register g14,
+     since that is matched explicitly below.  */
+
+  while (next_ip &&
+        ((insn1 & 0xf787f000) == 0x9287e000      /* stl? gx, n(fp) (MEMA) */
+         || (insn1 & 0xf787fc60) == 0x9287f400   /* stl? gx, n(fp) (MEMB) */
+         || (insn1 & 0xef87f000) == 0xa287e000   /* st[tq] gx, n(fp) (MEMA) */
+         || (insn1 & 0xef87fc60) == 0xa287f400)  /* st[tq] gx, n(fp) (MEMB) */
+        && ((src = MEM_SRCDST (insn1)) != G14_REGNUM))
+    {
+      save_addr = frame_addr + ((insn1 & BITMASK (12, 1))
+                               ? insn2 : MEMA_OFFSET (insn1));
+      size = (insn1 & BITMASK (29, 1)) ? ((insn1 & BITMASK (28, 1)) ? 4 : 3)
+                                      : ((insn1 & BITMASK (27, 1)) ? 2 : 1);
+      while (size--)
+       {
+         fsr->regs[src++] = save_addr;
+         save_addr += 4;
+       }
+      ip = next_ip;
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+    }
+
+  /* Accept the varargs prologue code if present.  */
+
+  size = sizeof (varargs_prologue_code) / sizeof (int);
+  pcode = varargs_prologue_code;
+  while (size-- && next_ip && *pcode++ == insn1)
+    {
+      ip = next_ip;
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+    }
+
+  /* Accept an optional "st g14, n(fp)".  */
+
+  if (next_ip &&
+      ((insn1 & 0xfffff000) == 0x92f7e000       /* st g14, n(fp) (MEMA) */
+       || (insn1 & 0xfffffc60) == 0x92f7f400))   /* st g14, n(fp) (MEMB) */
+    {
+      fsr->regs[G14_REGNUM] = frame_addr + ((insn1 & BITMASK (12, 1))
+                                           ? insn2 : MEMA_OFFSET (insn1));
+      ip = next_ip;
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+    }
+
+  /* Accept zero or one instance of "mov g13, ry", where y >= 4.
+     This is saving the address where a struct should be returned.  */
+
+  if (next_ip
+      && (insn1 & 0xff802fbf) == 0x5c00061d
+      && (dst = REG_SRCDST (insn1)) >= (R0_REGNUM + 4))
+    {
+      save_addr = frame_addr + ((dst - R0_REGNUM) * 4);
+      fsr->regs[G0_REGNUM+13] = save_addr;
+      ip = next_ip;
+#if 0  /* We'll need this once there is a subsequent instruction examined. */
+      next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn1, &insn2);
+#endif
+    }
+
+  return (ip);
+}
+
+/* Given an ip value corresponding to the start of a function,
+   return the ip of the first instruction after the function 
+   prologue.  */
+
+CORE_ADDR
+skip_prologue (ip)
+     CORE_ADDR (ip);
+{
+  struct frame_saved_regs saved_regs_dummy;
+  struct symtab_and_line sal;
+  CORE_ADDR limit;
+
+  sal = find_pc_line (ip, 0);
+  limit = (sal.end) ? sal.end : 0xffffffff;
+
+  return (examine_prologue (ip, limit, (FRAME_ADDR) 0, &saved_regs_dummy));
+}
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.
+
+   We cache the result of doing this in the frame_cache_obstack, since
+   it is fairly expensive.  */
+
+void
+frame_find_saved_regs (fi, fsr)
+     struct frame_info *fi;
+     struct frame_saved_regs *fsr;
+{
+  register CORE_ADDR next_addr;
+  register CORE_ADDR *saved_regs;
+  register int regnum;
+  register struct frame_saved_regs *cache_fsr;
+  extern struct obstack frame_cache_obstack;
+  CORE_ADDR ip;
+  struct symtab_and_line sal;
+  CORE_ADDR limit;
+
+  if (!fi->fsr)
+    {
+      cache_fsr = (struct frame_saved_regs *)
+                 obstack_alloc (&frame_cache_obstack,
+                                sizeof (struct frame_saved_regs));
+      bzero (cache_fsr, sizeof (struct frame_saved_regs));
+      fi->fsr = cache_fsr;
+
+      /* Find the start and end of the function prologue.  If the PC
+        is in the function prologue, we only consider the part that
+        has executed already.  */
+         
+      ip = get_pc_function_start (fi->pc);
+      sal = find_pc_line (ip, 0);
+      limit = (sal.end && sal.end < fi->pc) ? sal.end: fi->pc;
+
+      examine_prologue (ip, limit, fi->frame, cache_fsr);
+
+      /* Record the addresses at which the local registers are saved.
+        Strictly speaking, we should only do this for non-leaf procedures,
+        but no one will ever look at these values if it is a leaf procedure,
+        since local registers are always caller-saved.  */
+
+      next_addr = (CORE_ADDR) fi->frame;
+      saved_regs = cache_fsr->regs;
+      for (regnum = R0_REGNUM; regnum <= R15_REGNUM; regnum++)
+       {
+         *saved_regs++ = next_addr;
+         next_addr += 4;
+       }
+
+      cache_fsr->regs[FP_REGNUM] = cache_fsr->regs[PFP_REGNUM];
+    }
+
+  *fsr = *fi->fsr;
+
+  /* Fetch the value of the sp from memory every time, since it
+     is conceivable that it has changed since the cache was flushed.  
+     This unfortunately undoes much of the savings from caching the 
+     saved register values.  I suggest adding an argument to 
+     get_frame_saved_regs () specifying the register number we're
+     interested in (or -1 for all registers).  This would be passed
+     through to FRAME_FIND_SAVED_REGS (), permitting more efficient
+     computation of saved register addresses (e.g., on the i960,
+     we don't have to examine the prologue to find local registers). 
+       -- markf@wrs.com 
+     FIXME, we don't need to refetch this, since the cache is cleared
+     every time the child process is restarted.  If GDB itself
+     modifies SP, it has to clear the cache by hand (does it?).  -gnu */
+
+  fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[SP_REGNUM], 4);
+}
+
+/* Return the address of the argument block for the frame
+   described by FI.  Returns 0 if the address is unknown.  */
+
+CORE_ADDR
+frame_args_address (fi, must_be_correct)
+     struct frame_info *fi;
+{
+  register FRAME frame;
+  struct frame_saved_regs fsr;
+  CORE_ADDR ap;
+
+  /* If g14 was saved in the frame by the function prologue code, return
+     the saved value.  If the frame is current and we are being sloppy,
+     return the value of g14.  Otherwise, return zero.  */
+
+  frame = FRAME_INFO_ID (fi);
+  get_frame_saved_regs (fi, &fsr);
+  if (fsr.regs[G14_REGNUM])
+    ap = read_memory_integer (fsr.regs[G14_REGNUM],4);
+  else {
+    if (must_be_correct)
+      return 0;                        /* Don't cache this result */
+    if (get_next_frame (frame))
+      ap = 0;
+    else
+      ap = read_register (G14_REGNUM);
+  }
+  fi->arg_pointer = ap;                /* Cache it for next time */
+  return ap;
+}
+
+/* Return the address of the return struct for the frame
+   described by FI.  Returns 0 if the address is unknown.  */
+
+CORE_ADDR
+frame_struct_result_address (fi)
+     struct frame_info *fi;
+{
+  register FRAME frame;
+  struct frame_saved_regs fsr;
+  CORE_ADDR ap;
+
+  /* If the frame is non-current, check to see if g14 was saved in the
+     frame by the function prologue code; return the saved value if so,
+     zero otherwise.  If the frame is current, return the value of g14.
+
+     FIXME, shouldn't this use the saved value as long as we are past
+     the function prologue, and only use the current value if we have
+     no saved value and are at TOS?   -- gnu@cygnus.com */
+
+  frame = FRAME_INFO_ID (fi);
+  if (get_next_frame (frame)) {
+    get_frame_saved_regs (fi, &fsr);
+    if (fsr.regs[G13_REGNUM])
+      ap = read_memory_integer (fsr.regs[G13_REGNUM],4);
+    else
+      ap = 0;
+  } else {
+    ap = read_register (G13_REGNUM);
+  }
+  return ap;
+}
+
+/* Return address to which the currently executing leafproc will return,
+   or 0 if ip is not in a leafproc (or if we can't tell if it is).
+  
+   Do this by finding the starting address of the routine in which ip lies.
+   If the instruction there is "mov g14, gx" (where x is in [0,7]), this
+   is a leafproc and the return address is in register gx.  Well, this is
+   true unless the return address points at a RET instruction in the current
+   procedure, which indicates that we have a 'dual entry' routine that
+   has been entered through the CALL entry point.  */
+
+CORE_ADDR
+leafproc_return (ip)
+     CORE_ADDR ip;     /* ip from currently executing function */
+{
+  int i;
+  register struct misc_function *mf;
+  char *p;
+  int dst;
+  unsigned int insn1, insn2;
+  CORE_ADDR return_addr;
+  char *index ();
+
+  if ((i = find_pc_misc_function (ip)) >= 0)
+    {
+      mf = &misc_function_vector[i];
+      if ((p = index (mf->name, '.')) && !strcmp (p, ".lf"))
+       {
+         if (next_insn (mf->address, &insn1, &insn2)
+             && (insn1 & 0xff87ffff) == 0x5c80161e       /* mov g14, gx */
+             && (dst = REG_SRCDST (insn1)) <= G0_REGNUM + 7)
+           {
+             /* Get the return address.  If the "mov g14, gx" 
+                instruction hasn't been executed yet, read
+                the return address from g14; otherwise, read it
+                from the register into which g14 was moved.  */
+
+             return_addr = read_register ((ip == mf->address)
+                                          ? G14_REGNUM : dst);
+
+             /* We know we are in a leaf procedure, but we don't know
+                whether the caller actually did a "bal" to the ".lf"
+                entry point, or a normal "call" to the non-leaf entry
+                point one instruction before.  In the latter case, the
+                return address will be the address of a "ret"
+                instruction within the procedure itself.  We test for
+                this below.  */
+
+             if (!next_insn (return_addr, &insn1, &insn2)
+                 || (insn1 & 0xff000000) != 0xa000000   /* ret */
+                 || find_pc_misc_function (return_addr) != i)
+               return (return_addr);
+           }
+       }
+    }
+  
+  return (0);
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions. 
+   On the i960, the frame *is* set up immediately after the call,
+   unless the function is a leaf procedure.  */
+
+CORE_ADDR
+saved_pc_after_call (frame)
+     FRAME frame;
+{
+  CORE_ADDR saved_pc;
+  CORE_ADDR get_frame_pc ();
+
+  saved_pc = leafproc_return (get_frame_pc (frame));
+  if (!saved_pc)
+    saved_pc = FRAME_SAVED_PC (frame);
+
+  return (saved_pc);
+}
+
+/* Discard from the stack the innermost frame,
+   restoring all saved registers.  */
+
+pop_frame ()
+{
+  register struct frame_info *current_fi, *prev_fi;
+  register int i;
+  CORE_ADDR save_addr;
+  CORE_ADDR leaf_return_addr;
+  struct frame_saved_regs fsr;
+  char local_regs_buf[16 * 4];
+
+  current_fi = get_frame_info (get_current_frame ());
+
+  /* First, undo what the hardware does when we return.
+     If this is a non-leaf procedure, restore local registers from
+     the save area in the calling frame.  Otherwise, load the return
+     address obtained from leafproc_return () into the rip.  */
+
+  leaf_return_addr = leafproc_return (current_fi->pc);
+  if (!leaf_return_addr)
+    {
+      /* Non-leaf procedure.  Restore local registers, incl IP.  */
+      prev_fi = get_frame_info (get_prev_frame (FRAME_INFO_ID (current_fi)));
+      read_memory (prev_fi->frame, local_regs_buf, sizeof (local_regs_buf));
+      write_register_bytes (REGISTER_BYTE (R0_REGNUM), local_regs_buf, 
+                           sizeof (local_regs_buf));
+
+      /* Restore frame pointer.  */
+      write_register (FP_REGNUM, prev_fi->frame);
+    }
+  else
+    {
+      /* Leaf procedure.  Just restore the return address into the IP.  */
+      write_register (RIP_REGNUM, leaf_return_addr);
+    }
+
+  /* Now restore any global regs that the current function had saved. */
+  get_frame_saved_regs (current_fi, &fsr);
+  for (i = G0_REGNUM; i < G14_REGNUM; i++)
+    {
+      if (save_addr = fsr.regs[i])
+       write_register (i, read_memory_integer (save_addr, 4));
+    }
+
+  /* Flush the frame cache, create a frame for the new innermost frame,
+     and make it the current frame.  */
+
+  flush_cached_frames ();
+  set_current_frame (create_new_frame (read_register (FP_REGNUM), read_pc ()));
+}
+
+/* Print out text describing a "signal number" with which the i80960 halted.
+  
+   See the file "fault.c" in the nindy monitor source code for a list
+   of stop codes.  */
+
+void
+print_fault( siggnal )
+    int siggnal;       /* Signal number, as returned by target_wait() */
+{
+       static char unknown[] = "Unknown fault or trace";
+       static char *sigmsgs[] = {
+               /* FAULTS */
+               "parallel fault",       /* 0x00 */
+               unknown,                /* 0x01 */
+               "operation fault",      /* 0x02 */
+               "arithmetic fault",     /* 0x03 */
+               "floating point fault", /* 0x04 */
+               "constraint fault",     /* 0x05 */
+               "virtual memory fault", /* 0x06 */
+               "protection fault",     /* 0x07 */
+               "machine fault",        /* 0x08 */
+               "structural fault",     /* 0x09 */
+               "type fault",           /* 0x0a */
+               "reserved (0xb) fault", /* 0x0b */
+               "process fault",        /* 0x0c */
+               "descriptor fault",     /* 0x0d */
+               "event fault",          /* 0x0e */
+               "reserved (0xf) fault", /* 0x0f */
+
+               /* TRACES */
+               "single-step trace",    /* 0x10 */
+               "branch trace",         /* 0x11 */
+               "call trace",           /* 0x12 */
+               "return trace",         /* 0x13 */
+               "pre-return trace",     /* 0x14 */
+               "supervisor call trace",/* 0x15 */
+               "breakpoint trace",     /* 0x16 */
+       };
+#      define NUMMSGS ((int)( sizeof(sigmsgs) / sizeof(sigmsgs[0]) ))
+
+       if (siggnal < NSIG) {
+             printf ("\nProgram received signal %d, %s\n",
+                     siggnal,
+                     sys_siglist[siggnal]);
+       } else {
+               /* The various target_wait()s bias the 80960 "signal number"
+                  by adding NSIG to it, so it won't get confused with any
+                  of the Unix signals elsewhere in GDB.  We need to
+                  "unbias" it before using it.  */
+               siggnal -= NSIG;
+
+               printf("Program stopped for reason #%d: %s.\n", siggnal,
+                               (siggnal < NUMMSGS && siggnal >= 0)?
+                               sigmsgs[siggnal] : unknown );
+       }
+}
+
+/* Initialization stub */
+
+_initialize_i960_tdep ()
+{
+  check_host ();
+}
diff --git a/gdb/ieee-float.c b/gdb/ieee-float.c
new file mode 100644 (file)
index 0000000..7b7f9f1
--- /dev/null
@@ -0,0 +1,141 @@
+/* IEEE floating point support routines, for GDB, the GNU Debugger.
+   Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "param.h"
+#include "ieee-float.h"
+#include <math.h>              /* ldexp */
+
+/* Convert an IEEE extended float to a double.
+   FROM is the address of the extended float.
+   Store the double in *TO.  */
+
+void
+ieee_extended_to_double (ext_format, from, to)
+     struct ext_format *ext_format;
+     char *from;
+     double *to;
+{
+  unsigned char *ufrom = (unsigned char *)from;
+  double dto;
+  unsigned long mant0, mant1, exp;
+  
+  bcopy (&from[MANBYTE_H], &mant0, 4);
+  bcopy (&from[MANBYTE_L], &mant1, 4);
+  exp = ((ufrom[EXPBYTE_H] & (unsigned char)~SIGNMASK) << 8) | ufrom[EXPBYTE_L];
+
+  if (exp == EXT_EXP_NAN) {
+    /* We have a NaN source.  */
+    dto = 0.123456789; /* Not much else useful to do */
+  } else if (exp == 0 && mant0 == 0 && mant1 == 0) {
+    dto = 0;
+  } else {
+    /* Build the result algebraically.  Might go infinite, underflow, etc;
+       who cares. */
+    mant0 |= 0x80000000;
+    dto = ldexp  ((double)mant0, exp - EXT_EXP_BIAS - 31);
+    dto += ldexp ((double)mant1, exp - EXT_EXP_BIAS - 31 - 32);
+  }
+  *to = dto;
+}
+
+/* The converse: convert the double *FROM to an extended float
+   and store where TO points.  */
+
+void
+double_to_ieee_extended (ext_format, from, to)
+     struct ext_format *ext_format;
+     double *from;
+     char *to;
+{
+  double dfrom = *from;
+  unsigned long twolongs[2];
+  unsigned long mant0, mant1, exp;
+  unsigned char twobytes[2];
+
+  bzero (to, TOTALSIZE);
+  if (dfrom == 0)
+    return;                    /* Result is zero */
+  if (dfrom != dfrom) {
+    /* From is NaN */
+    to[EXPBYTE_H] = (unsigned char)(EXT_EXP_NAN >> 8);
+    to[EXPBYTE_L] = (unsigned char)EXT_EXP_NAN;
+    to[MANBYTE_H] = 1; /* Be sure it's not infinity, but NaN value is irrel */
+    return;                    /* Result is NaN */
+  }
+  if (dfrom < 0)
+    to[SIGNBYTE] |= SIGNMASK;  /* Set negative sign */
+  /* How to tell an infinity from an ordinary number?  FIXME-someday */
+
+  /* The following code assumes that the host has IEEE doubles.  FIXME-someday.
+     It also assumes longs are 32 bits!  FIXME-someday.  */
+  bcopy (from, twolongs, 8);
+  bcopy (from, twobytes, 2);
+#if HOST_BYTE_ORDER == BIG_ENDIAN
+  exp = ((twobytes[1] & 0xF0) >> 4) | (twobytes[0] & 0x7F) << 4;
+  mant0 = (twolongs[0] << 11) | twolongs[1] >> 21;
+  mant1 = (twolongs[1] << 11);
+#else
+  exp = ((twobytes[0] & 0xF0) >> 4) | (twobytes[1] & 0x7F) << 4;
+  mant0 = (twolongs[1] << 11) | twolongs[0] >> 21;
+  mant1 = (twolongs[0] << 11);
+#endif
+
+  /* Fiddle with leading 1-bit, implied in double, explicit in extended. */
+  if (exp == 0)
+    mant0 &= 0x7FFFFFFF;
+  else
+    mant0 |= 0x80000000;
+
+  exp -= DBL_EXP_BIAS;                         /* Get integer exp */
+  exp += EXT_EXP_BIAS;                         /* Offset for extended *&/
+
+  /* OK, now store it in extended format. */
+  to[EXPBYTE_H] |= (unsigned char)(exp >> 8);  /* Retain sign */
+  to[EXPBYTE_L] =  (unsigned char) exp;
+  
+  bcopy (&mant0, &to[MANBYTE_H], 4);
+  bcopy (&mant1, &to[MANBYTE_L], 4);
+}
+
+
+#ifdef DEBUG
+
+/* Test some numbers to see that extended/double conversion works for them.  */
+
+ieee_test (n)
+     int n;
+{
+  union { double d; int i[2]; } di;
+  double result;
+  int i;
+  char exten[16];
+  extern struct ext_format ext_format_68881;
+
+  for (i = 0; i < n; i++) {
+    di.i[0] = random();
+    di.i[1] = random();
+    double_to_ieee_extended (ext_format_68881, &di.d, exten);
+    ieee_extended_to_double (ext_format_68881, exten, &result);
+    if (di.d != result)
+      printf ("Differ: %x %x %g => %x %x %g\n", di.d, di.d, result, result);
+  }
+}
+
+#endif
diff --git a/gdb/ieee-float.h b/gdb/ieee-float.h
new file mode 100644 (file)
index 0000000..9325518
--- /dev/null
@@ -0,0 +1,66 @@
+/* IEEE floating point support declarations, for GDB, the GNU Debugger.
+   Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Parameters for extended float format:  */
+
+struct ext_format {
+  unsigned totalsize;          /* Total size of extended number */
+  unsigned signbyte;           /* Byte number of sign bit */
+  unsigned char signmask;      /* Mask for sign bit */
+  unsigned expbyte_h;          /* High byte of exponent */
+  unsigned expbyte_l;          /* Low  byte of exponent */
+  unsigned manbyte_h;          /* High byte of mantissa */
+  unsigned manbyte_l;          /* Low  byte of mantissa */
+};
+
+#define        TOTALSIZE       ext_format->totalsize
+#define        SIGNBYTE        ext_format->signbyte
+#define        SIGNMASK        ext_format->signmask
+#define EXPBYTE_H      ext_format->expbyte_h
+#define EXPBYTE_L      ext_format->expbyte_l
+#define        MANBYTE_H       ext_format->manbyte_h
+#define        MANBYTE_L       ext_format->manbyte_l
+
+/* Actual ext_format structs for various machines are in the *-tdep.c file
+   for each machine.  */
+
+#define        EXT_EXP_NAN     0x7FFF  /* Exponent value that indicates NaN */
+#define        EXT_EXP_BIAS    0x3FFF  /* Amount added to "true" exponent for ext */
+#define        DBL_EXP_BIAS     0x3FF  /* Ditto, for doubles */
+
+/* Convert an IEEE extended float to a double.
+   FROM is the address of the extended float.
+   Store the double in *TO.  */
+
+extern void
+ieee_extended_to_double (
+#ifdef __STDC__
+       struct ext_format *ext_format, char *from, double *to
+#endif
+);
+
+/* The converse: convert the double *FROM to an extended float
+   and store where TO points.  */
+
+void
+double_to_ieee_extended (
+#ifdef __STDC__
+       struct ext_format *ext_format, double *from, char *to
+#endif
+);
diff --git a/gdb/kdb-start.c b/gdb/kdb-start.c
new file mode 100644 (file)
index 0000000..cbc69fd
--- /dev/null
@@ -0,0 +1,40 @@
+/* Main loop for the standalone kernel debugger.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "param.h"
+
+static char *args[] = {"kdb", "kdb-symbols", 0};
+
+static char *environment[] = {0};
+
+char **environ;
+
+start ()
+{
+#ifdef NAMES_HAVE_UNDERSCORE
+  INIT_STACK (_kdb_stack_beg, _kdb_stack_end);
+#else /* not NAMES_HAVE_UNDERSCORE */
+  INIT_STACK (kdb_stack_beg, kdb_stack_end);
+#endif /* not NAMES_HAVE_UNDERSCORE */
+
+  environ = environment;
+
+  main (2, args, environment);
+}
diff --git a/gdb/m68k-opcode.h b/gdb/m68k-opcode.h
new file mode 100755 (executable)
index 0000000..a0961f6
--- /dev/null
@@ -0,0 +1,1680 @@
+/* Opcode table for m68000/m68020 and m68881.
+   Copyright (C) 1989, Free Software Foundation.
+
+This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
+
+Both GDB and GAS are free software; you can redistribute and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB and GAS are distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB or GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   
+
+struct m68k_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long  match;
+  char *args;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+   is the most any of them need.  The actual length of an instruction
+   is always at least 2 bytes, and is as much longer as necessary to
+   hold the operands it has.
+
+   The match component is a mask saying which bits must match
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing two characters
+   for each operand of the instruction.  The first specifies
+   the kind of operand; the second, the place it is stored.  */
+
+/* Kinds of operands:
+   D  data register only.  Stored as 3 bits.
+   A  address register only.  Stored as 3 bits.
+   R  either kind of register.  Stored as 4 bits.
+   F  floating point coprocessor register only.   Stored as 3 bits.
+   O  an offset (or width): immediate data 0-31 or data register.
+      Stored as 6 bits in special format for BF... insns.
+   +  autoincrement only.  Stored as 3 bits (number of the address register).
+   -  autodecrement only.  Stored as 3 bits (number of the address register).
+   Q  quick immediate data.  Stored as 3 bits.
+      This matches an immediate operand only when value is in range 1 .. 8.
+   M  moveq immediate data.  Stored as 8 bits.
+      This matches an immediate operand only when value is in range -128..127
+   T  trap vector immediate data.  Stored as 4 bits.
+
+   k  K-factor for fmove.p instruction.   Stored as a 7-bit constant or
+      a three bit register offset, depending on the field type.
+
+   #  immediate data.  Stored in special places (b, w or l)
+      which say how many bits to store.
+   ^  immediate data for floating point instructions.   Special places
+      are offset by 2 bytes from '#'...
+   B  pc-relative address, converted to an offset
+      that is treated as immediate data.
+   d  displacement and register.  Stores the register as 3 bits
+      and stores the displacement in the entire second word.
+
+   C  the CCR.  No need to store it; this is just for filtering validity.
+   S  the SR.  No need to store, just as with CCR.
+   U  the USP.  No need to store, just as with CCR.
+
+   I  Coprocessor ID.   Not printed if 1.   The Coprocessor ID is always
+      extracted from the 'd' field of word one, which means that an extended
+      coprocessor opcode can be skipped using the 'i' place, if needed.
+
+   s  System Control register for the floating point coprocessor.
+   S  List of system control registers for floating point coprocessor.
+
+   J  Misc register for movec instruction, stored in 'j' format.
+       Possible values:
+       000     SFC     Source Function Code reg
+       001     DFC     Data Function Code reg
+       002     CACR    Cache Control Register
+       800     USP     User Stack Pointer
+       801     VBR     Vector Base reg
+       802     CAAR    Cache Address Register
+       803     MSP     Master Stack Pointer
+       804     ISP     Interrupt Stack Pointer
+
+    L  Register list of the type d0-d7/a0-a7 etc.
+       (New!  Improved!  Can also hold fp0-fp7, as well!)
+       The assembler tries to see if the registers match the insn by
+       looking at where the insn wants them stored.
+
+    l  Register list like L, but with all the bits reversed.
+       Used for going the other way. . .
+
+ They are all stored as 6 bits using an address mode and a register number;
+ they differ in which addressing modes they match.
+
+   *  all                                      (modes 0-6,7.*)
+   ~  alterable memory                         (modes 2-6,7.0,7.1)(not 0,1,7.~)
+   %  alterable                                        (modes 0-6,7.0,7.1)(not 7.~)
+   ;  data                                     (modes 0,2-6,7.*)(not 1)
+   @  data, but not immediate                  (modes 0,2-6,7.? ? ?)(not 1,7.?)  This may really be ;, the 68020 book says it is
+   !  control                                  (modes 2,5,6,7.*-)(not 0,1,3,4,7.4)
+   &  alterable control                                (modes 2,5,6,7.0,7.1)(not 0,1,7.? ? ?)
+   $  alterable data                           (modes 0,2-6,7.0,7.1)(not 1,7.~)
+   ?  alterable control, or data register      (modes 0,2,5,6,7.0,7.1)(not 1,3,4,7.~)
+   /  control, or data register                        (modes 0,2,5,6,7.0,7.1,7.2,7.3)(not 1,3,4,7.4)
+*/
+
+/* JF: for the 68851 */
+/*
+   I didn't use much imagination in choosing the 
+   following codes, so many of them aren't very
+   mnemonic. -rab
+
+   P  pmmu register
+       Possible values:
+       000     TC      Translation Control reg
+       100     CAL     Current Access Level
+       101     VAL     Validate Access Level
+       110     SCC     Stack Change Control
+       111     AC      Access Control
+
+   W  wide pmmu registers
+       Possible values:
+       001     DRP     Dma Root Pointer
+       010     SRP     Supervisor Root Pointer
+       011     CRP     Cpu Root Pointer
+
+   f   function code register
+       0       SFC
+       1       DFC
+
+   V   VAL register only
+
+   X   BADx, BACx
+       100     BAD     Breakpoint Acknowledge Data
+       101     BAC     Breakpoint Acknowledge Control
+
+   Y   PSR
+   Z   PCSR
+
+   |   memory          (modes 2-6, 7.*)
+
+*/
+
+/* Places to put an operand, for non-general operands:
+   s  source, low bits of first word.
+   d  dest, shifted 9 in first word
+   1  second word, shifted 12
+   2  second word, shifted 6
+   3  second word, shifted 0
+   4  third word, shifted 12
+   5  third word, shifted 6
+   6  third word, shifted 0
+   7  second word, shifted 7
+   8  second word, shifted 10
+   D  store in both place 1 and place 3; for divul and divsl.
+   b  second word, low byte
+   w  second word (entire)
+   l  second and third word (entire)
+   g  branch offset for bra and similar instructions.
+      The place to store depends on the magnitude of offset.
+   t  store in both place 7 and place 8; for floating point operations
+   c  branch offset for cpBcc operations.
+      The place to store is word two if bit six of word one is zero,
+      and words two and three if bit six of word one is one.
+   i  Increment by two, to skip over coprocessor extended operands.   Only
+      works with the 'I' format.
+   k  Dynamic K-factor field.   Bits 6-4 of word 2, used as a register number.
+      Also used for dynamic fmovem instruction.
+   C  floating point coprocessor constant - 7 bits.  Also used for static
+      K-factors...
+   j  Movec register #, stored in 12 low bits of second word.
+
+ Places to put operand, for general operands:
+   d  destination, shifted 6 bits in first word
+   b  source, at low bit of first word, and immediate uses one byte
+   w  source, at low bit of first word, and immediate uses two bytes
+   l  source, at low bit of first word, and immediate uses four bytes
+   s  source, at low bit of first word.
+      Used sometimes in contexts where immediate is not allowed anyway.
+   f  single precision float, low bit of 1st word, immediate uses 4 bytes
+   F  double precision float, low bit of 1st word, immediate uses 8 bytes
+   x  extended precision float, low bit of 1st word, immediate uses 12 bytes
+   p  packed float, low bit of 1st word, immediate uses 12 bytes
+*/
+
+#define one(x) ((x) << 16)
+#define two(x, y) (((x) << 16) + y)
+
+/*
+       *** DANGER WILL ROBINSON ***
+
+   The assembler requires that all instances of the same mnemonic must be
+   consecutive.  If they aren't, the assembler will bomb at runtime
+ */
+struct m68k_opcode m68k_opcodes[] =
+{
+{"abcd",       one(0140400),           one(0170770),           "DsDd"},
+{"abcd",       one(0140410),           one(0170770),           "-s-d"},
+
+               /* Add instructions */
+{"addal",      one(0150700),           one(0170700),           "*lAd"},
+{"addaw",      one(0150300),           one(0170700),           "*wAd"},
+{"addib",      one(0003000),           one(0177700),           "#b$b"},
+{"addil",      one(0003200),           one(0177700),           "#l$l"},
+{"addiw",      one(0003100),           one(0177700),           "#w$w"},
+{"addqb",      one(0050000),           one(0170700),           "Qd$b"},
+{"addql",      one(0050200),           one(0170700),           "Qd%l"},
+{"addqw",      one(0050100),           one(0170700),           "Qd%w"},
+
+{"addb",       one(0050000),           one(0170700),           "Qd$b"},        /* addq written as add */
+{"addb",       one(0003000),           one(0177700),           "#b$b"},        /* addi written as add */
+{"addb",       one(0150000),           one(0170700),           ";bDd"},        /* addb <ea>,   Dd */
+{"addb",       one(0150400),           one(0170700),           "Dd~b"},        /* addb Dd,     <ea> */
+
+{"addw",       one(0050100),           one(0170700),           "Qd%w"},        /* addq written as add */
+{"addw",       one(0003100),           one(0177700),           "#w$w"},        /* addi written as add */
+{"addw",       one(0150300),           one(0170700),           "*wAd"},        /* adda written as add */
+{"addw",       one(0150100),           one(0170700),           "*wDd"},        /* addw <ea>,   Dd */
+{"addw",       one(0150500),           one(0170700),           "Dd~w"},        /* addw Dd,     <ea> */
+
+{"addl",       one(0050200),           one(0170700),           "Qd%l"},        /* addq written as add */
+{"addl",       one(0003200),           one(0177700),           "#l$l"},        /* addi written as add */
+{"addl",       one(0150700),           one(0170700),           "*lAd"},        /* adda written as add */
+{"addl",       one(0150200),           one(0170700),           "*lDd"},        /* addl <ea>,   Dd */
+{"addl",       one(0150600),           one(0170700),           "Dd~l"},        /* addl Dd,     <ea> */
+
+{"addxb",      one(0150400),           one(0170770),           "DsDd"},
+{"addxb",      one(0150410),           one(0170770),           "-s-d"},
+{"addxl",      one(0150600),           one(0170770),           "DsDd"},
+{"addxl",      one(0150610),           one(0170770),           "-s-d"},
+{"addxw",      one(0150500),           one(0170770),           "DsDd"},
+{"addxw",      one(0150510),           one(0170770),           "-s-d"},
+
+{"andib",      one(0001000),           one(0177700),           "#b$b"},
+{"andib",      one(0001074),           one(0177777),           "#bCb"},        /* andi to ccr */
+{"andiw",      one(0001100),           one(0177700),           "#w$w"},
+{"andiw",      one(0001174),           one(0177777),           "#wSw"},        /* andi to sr */
+{"andil",      one(0001200),           one(0177700),           "#l$l"},
+
+{"andb",       one(0001000),           one(0177700),           "#b$b"},        /* andi written as or */
+{"andb",       one(0001074),           one(0177777),           "#bCb"},        /* andi to ccr */
+{"andb",       one(0140000),           one(0170700),           ";bDd"},        /* memory to register */
+{"andb",       one(0140400),           one(0170700),           "Dd~b"},        /* register to memory */
+{"andw",       one(0001100),           one(0177700),           "#w$w"},        /* andi written as or */
+{"andw",       one(0001174),           one(0177777),           "#wSw"},        /* andi to sr */
+{"andw",       one(0140100),           one(0170700),           ";wDd"},        /* memory to register */
+{"andw",       one(0140500),           one(0170700),           "Dd~w"},        /* register to memory */
+{"andl",       one(0001200),           one(0177700),           "#l$l"},        /* andi written as or */
+{"andl",       one(0140200),           one(0170700),           ";lDd"},        /* memory to register */
+{"andl",       one(0140600),           one(0170700),           "Dd~l"},        /* register to memory */
+
+{"aslb",       one(0160400),           one(0170770),           "QdDs"},
+{"aslb",       one(0160440),           one(0170770),           "DdDs"},
+{"asll",       one(0160600),           one(0170770),           "QdDs"},
+{"asll",       one(0160640),           one(0170770),           "DdDs"},
+{"aslw",       one(0160500),           one(0170770),           "QdDs"},
+{"aslw",       one(0160540),           one(0170770),           "DdDs"},
+{"aslw",       one(0160700),           one(0177700),           "~s"},  /* Shift memory */
+{"asrb",       one(0160000),           one(0170770),           "QdDs"},
+{"asrb",       one(0160040),           one(0170770),           "DdDs"},
+{"asrl",       one(0160200),           one(0170770),           "QdDs"},
+{"asrl",       one(0160240),           one(0170770),           "DdDs"},
+{"asrw",       one(0160100),           one(0170770),           "QdDs"},
+{"asrw",       one(0160140),           one(0170770),           "DdDs"},
+{"asrw",       one(0160300),           one(0177700),           "~s"},  /* Shift memory */
+
+{"bhi",                one(0061000),           one(0177400),           "Bg"},
+{"bls",                one(0061400),           one(0177400),           "Bg"},
+{"bcc",                one(0062000),           one(0177400),           "Bg"},
+{"bcs",                one(0062400),           one(0177400),           "Bg"},
+{"bne",                one(0063000),           one(0177400),           "Bg"},
+{"beq",                one(0063400),           one(0177400),           "Bg"},
+{"bvc",                one(0064000),           one(0177400),           "Bg"},
+{"bvs",                one(0064400),           one(0177400),           "Bg"},
+{"bpl",                one(0065000),           one(0177400),           "Bg"},
+{"bmi",                one(0065400),           one(0177400),           "Bg"},
+{"bge",                one(0066000),           one(0177400),           "Bg"},
+{"blt",                one(0066400),           one(0177400),           "Bg"},
+{"bgt",                one(0067000),           one(0177400),           "Bg"},
+{"ble",                one(0067400),           one(0177400),           "Bg"},
+
+{"bchg",       one(0000500),           one(0170700),           "Dd$s"},
+{"bchg",       one(0004100),           one(0177700),           "#b$s"},
+{"bclr",       one(0000600),           one(0170700),           "Dd$s"},
+{"bclr",       one(0004200),           one(0177700),           "#b$s"},
+{"bfchg",      two(0165300, 0),        two(0177700, 0170000),  "?sO2O3"},
+{"bfclr",      two(0166300, 0),        two(0177700, 0170000),  "?sO2O3"},
+{"bfexts",     two(0165700, 0),        two(0177700, 0100000),  "/sO2O3D1"},
+{"bfextu",     two(0164700, 0),        two(0177700, 0100000),  "/sO2O3D1"},
+{"bfffo",      two(0166700, 0),        two(0177700, 0100000),  "/sO2O3D1"},
+{"bfins",      two(0167700, 0),        two(0177700, 0100000),  "D1?sO2O3"},
+{"bfset",      two(0167300, 0),        two(0177700, 0170000),  "?sO2O3"},
+{"bftst",      two(0164300, 0),        two(0177700, 0170000),  "/sO2O3"},
+{"bset",       one(0000700),           one(0170700),           "Dd$s"},
+{"bset",       one(0004300),           one(0177700),           "#b$s"},
+{"btst",       one(0000400),           one(0170700),           "Dd@s"},
+{"btst",       one(0004000),           one(0177700),           "#b@s"},
+
+{"bkpt",       one(0044110),           one(0177770),           "Qs"},
+{"bra",                one(0060000),           one(0177400),           "Bg"},
+{"bras",       one(0060000),           one(0177400),           "Bw"},
+{"bsr",                one(0060400),           one(0177400),           "Bg"},
+{"bsrs",       one(0060400),           one(0177400),           "Bw"},
+
+{"callm",      one(0003300),           one(0177700),           "#b!s"},
+{"cas2l",      two(0007374, 0),        two(0177777, 0107070),  "D3D6D2D5R1R4"}, /* JF FOO this is really a 3 word ins */
+{"cas2w",      two(0006374, 0),        two(0177777, 0107070),  "D3D6D2D5R1R4"}, /* JF ditto */
+{"casb",       two(0005300, 0),        two(0177700, 0177070),  "D3D2~s"},
+{"casl",       two(0007300, 0),        two(0177700, 0177070),  "D3D2~s"},
+{"casw",       two(0006300, 0),        two(0177700, 0177070),  "D3D2~s"},
+
+/*  {"chk",    one(0040600),           one(0170700),           ";wDd"}, JF FOO this looks wrong */
+{"chk2b",      two(0000300, 0004000),  two(0177700, 07777),    "!sR1"},
+{"chk2l",      two(0002300, 0004000),  two(0177700, 07777),    "!sR1"},
+{"chk2w",      two(0001300, 0004000),  two(0177700, 07777),    "!sR1"},
+{"chkl",       one(0040400),           one(0170700),           ";lDd"},
+{"chkw",       one(0040600),           one(0170700),           ";wDd"},
+{"clrb",       one(0041000),           one(0177700),           "$s"},
+{"clrl",       one(0041200),           one(0177700),           "$s"},
+{"clrw",       one(0041100),           one(0177700),           "$s"},
+
+{"cmp2b",      two(0000300, 0),        two(0177700, 07777),    "!sR1"},
+{"cmp2l",      two(0002300, 0),        two(0177700, 07777),    "!sR1"},
+{"cmp2w",      two(0001300, 0),        two(0177700, 07777),    "!sR1"},
+{"cmpal",      one(0130700),           one(0170700),           "*lAd"},
+{"cmpaw",      one(0130300),           one(0170700),           "*wAd"},
+{"cmpib",      one(0006000),           one(0177700),           "#b;b"},
+{"cmpil",      one(0006200),           one(0177700),           "#l;l"},
+{"cmpiw",      one(0006100),           one(0177700),           "#w;w"},
+{"cmpb",       one(0006000),           one(0177700),           "#b;b"},        /* cmpi written as cmp */
+{"cmpb",       one(0130000),           one(0170700),           ";bDd"},
+{"cmpw",       one(0006100),           one(0177700),           "#w;w"},
+{"cmpw",       one(0130100),           one(0170700),           "*wDd"},
+{"cmpw",       one(0130300),           one(0170700),           "*wAd"},        /* cmpa written as cmp */
+{"cmpl",       one(0006200),           one(0177700),           "#l;l"},
+{"cmpl",       one(0130200),           one(0170700),           "*lDd"},
+{"cmpl",       one(0130700),           one(0170700),           "*lAd"},
+{"cmpmb",      one(0130410),           one(0170770),           "+s+d"},
+{"cmpml",      one(0130610),           one(0170770),           "+s+d"},
+{"cmpmw",      one(0130510),           one(0170770),           "+s+d"},
+
+{"dbcc",       one(0052310),           one(0177770),           "DsBw"},
+{"dbcs",       one(0052710),           one(0177770),           "DsBw"},
+{"dbeq",       one(0053710),           one(0177770),           "DsBw"},
+{"dbf",                one(0050710),           one(0177770),           "DsBw"},
+{"dbge",       one(0056310),           one(0177770),           "DsBw"},
+{"dbgt",       one(0057310),           one(0177770),           "DsBw"},
+{"dbhi",       one(0051310),           one(0177770),           "DsBw"},
+{"dble",       one(0057710),           one(0177770),           "DsBw"},
+{"dbls",       one(0051710),           one(0177770),           "DsBw"},
+{"dblt",       one(0056710),           one(0177770),           "DsBw"},
+{"dbmi",       one(0055710),           one(0177770),           "DsBw"},
+{"dbne",       one(0053310),           one(0177770),           "DsBw"},
+{"dbpl",       one(0055310),           one(0177770),           "DsBw"},
+{"dbra",       one(0050710),           one(0177770),           "DsBw"},
+{"dbt",                one(0050310),           one(0177770),           "DsBw"},
+{"dbvc",       one(0054310),           one(0177770),           "DsBw"},
+{"dbvs",       one(0054710),           one(0177770),           "DsBw"},
+
+{"divsl",      two(0046100, 0006000),  two(0177700, 0107770),  ";lD3D1"},
+{"divsl",      two(0046100, 0004000),  two(0177700, 0107770),  ";lDD"},
+{"divsll",     two(0046100, 0004000),  two(0177700, 0107770),  ";lD3D1"},
+{"divsw",      one(0100700),           one(0170700),           ";wDd"},
+{"divs",       one(0100700),           one(0170700),           ";wDd"},
+{"divul",      two(0046100, 0002000),  two(0177700, 0107770),  ";lD3D1"},
+{"divul",      two(0046100, 0000000),  two(0177700, 0107770),  ";lDD"},
+{"divull",     two(0046100, 0000000),  two(0177700, 0107770),  ";lD3D1"},
+{"divuw",      one(0100300),           one(0170700),           ";wDd"},
+{"divu",       one(0100300),           one(0170700),           ";wDd"},
+{"eorb",       one(0005000),           one(0177700),           "#b$s"},        /* eori written as or */
+{"eorb",       one(0005074),           one(0177777),           "#bCs"},        /* eori to ccr */
+{"eorb",       one(0130400),           one(0170700),           "Dd$s"},        /* register to memory */
+{"eorib",      one(0005000),           one(0177700),           "#b$s"},
+{"eorib",      one(0005074),           one(0177777),           "#bCs"},        /* eori to ccr */
+{"eoril",      one(0005200),           one(0177700),           "#l$s"},
+{"eoriw",      one(0005100),           one(0177700),           "#w$s"},
+{"eoriw",      one(0005174),           one(0177777),           "#wSs"},        /* eori to sr */
+{"eorl",       one(0005200),           one(0177700),           "#l$s"},
+{"eorl",       one(0130600),           one(0170700),           "Dd$s"},
+{"eorw",       one(0005100),           one(0177700),           "#w$s"},
+{"eorw",       one(0005174),           one(0177777),           "#wSs"},        /* eori to sr */
+{"eorw",       one(0130500),           one(0170700),           "Dd$s"},
+
+{"exg",                one(0140500),           one(0170770),           "DdDs"},
+{"exg",                one(0140510),           one(0170770),           "AdAs"},
+{"exg",                one(0140610),           one(0170770),           "DdAs"},
+{"exg",                one(0140610),           one(0170770),           "AsDd"},
+
+{"extw",       one(0044200),           one(0177770),           "Ds"},
+{"extl",       one(0044300),           one(0177770),           "Ds"},
+{"extbl",      one(0044700),           one(0177770),           "Ds"},
+{"extb.l",     one(0044700),           one(0177770),           "Ds"},  /* Not sure we should support this one*/
+
+{"illegal",    one(0045374),           one(0177777),           ""},
+{"jmp",                one(0047300),           one(0177700),           "!s"},
+{"jsr",                one(0047200),           one(0177700),           "!s"},
+{"lea",                one(0040700),           one(0170700),           "!sAd"},
+{"linkw",      one(0047120),           one(0177770),           "As#w"},
+{"linkl",      one(0044010),           one(0177770),           "As#l"},
+{"link",       one(0047120),           one(0177770),           "As#w"},
+{"link",       one(0044010),           one(0177770),           "As#l"},
+
+{"lslb",       one(0160410),           one(0170770),           "QdDs"},        /* lsrb #Q,     Ds */
+{"lslb",       one(0160450),           one(0170770),           "DdDs"},        /* lsrb Dd,     Ds */
+{"lslw",       one(0160510),           one(0170770),           "QdDs"},        /* lsrb #Q,     Ds */
+{"lslw",       one(0160550),           one(0170770),           "DdDs"},        /* lsrb Dd,     Ds */
+{"lslw",       one(0161700),           one(0177700),           "~s"},  /* Shift memory */
+{"lsll",       one(0160610),           one(0170770),           "QdDs"},        /* lsrb #Q,     Ds */
+{"lsll",       one(0160650),           one(0170770),           "DdDs"},        /* lsrb Dd,     Ds */
+
+{"lsrb",       one(0160010),           one(0170770),           "QdDs"} /* lsrb #Q,     Ds */,
+{"lsrb",       one(0160050),           one(0170770),           "DdDs"},        /* lsrb Dd,     Ds */
+{"lsrl",       one(0160210),           one(0170770),           "QdDs"},        /* lsrb #Q,     Ds */
+{"lsrl",       one(0160250),           one(0170770),           "DdDs"},        /* lsrb #Q,     Ds */
+{"lsrw",       one(0160110),           one(0170770),           "QdDs"},        /* lsrb #Q,     Ds */
+{"lsrw",       one(0160150),           one(0170770),           "DdDs"},        /* lsrb #Q,     Ds */
+{"lsrw",       one(0161300),           one(0177700),           "~s"},  /* Shift memory */
+
+{"moveal",     one(0020100),           one(0170700),           "*lAd"},
+{"moveaw",     one(0030100),           one(0170700),           "*wAd"},
+{"moveb",      one(0010000),           one(0170000),           ";b$d"},        /* move */
+{"movel",      one(0070000),           one(0170400),           "MsDd"},        /* moveq written as move */
+{"movel",      one(0020000),           one(0170000),           "*l$d"},
+{"movel",      one(0020100),           one(0170700),           "*lAd"},
+{"movel",      one(0047140),           one(0177770),           "AsUd"},        /* move to USP */
+{"movel",      one(0047150),           one(0177770),           "UdAs"},        /* move from USP */
+
+{"movec",      one(0047173),           one(0177777),           "R1Jj"},
+{"movec",      one(0047173),           one(0177777),           "R1#j"},
+{"movec",      one(0047172),           one(0177777),           "JjR1"},
+{"movec",      one(0047172),           one(0177777),           "#jR1"},
+
+/* JF added these next four for the assembler */
+{"moveml",     one(0044300),           one(0177700),           "Lw&s"},        /* movem reg to mem. */
+{"moveml",     one(0044340),           one(0177770),           "lw-s"},        /* movem reg to autodecrement. */
+{"moveml",     one(0046300),           one(0177700),           "!sLw"},        /* movem mem to reg. */
+{"moveml",     one(0046330),           one(0177770),           "+sLw"},        /* movem autoinc to reg. */
+
+{"moveml",     one(0044300),           one(0177700),           "#w&s"},        /* movem reg to mem. */
+{"moveml",     one(0044340),           one(0177770),           "#w-s"},        /* movem reg to autodecrement. */
+{"moveml",     one(0046300),           one(0177700),           "!s#w"},        /* movem mem to reg. */
+{"moveml",     one(0046330),           one(0177770),           "+s#w"},        /* movem autoinc to reg. */
+
+/* JF added these next four for the assembler */
+{"movemw",     one(0044200),           one(0177700),           "Lw&s"},        /* movem reg to mem. */
+{"movemw",     one(0044240),           one(0177770),           "lw-s"},        /* movem reg to autodecrement. */
+{"movemw",     one(0046200),           one(0177700),           "!sLw"},        /* movem mem to reg. */
+{"movemw",     one(0046230),           one(0177770),           "+sLw"},        /* movem autoinc to reg. */
+
+{"movemw",     one(0044200),           one(0177700),           "#w&s"},        /* movem reg to mem. */
+{"movemw",     one(0044240),           one(0177770),           "#w-s"},        /* movem reg to autodecrement. */
+{"movemw",     one(0046200),           one(0177700),           "!s#w"},        /* movem mem to reg. */
+{"movemw",     one(0046230),           one(0177770),           "+s#w"},        /* movem autoinc to reg. */
+
+{"movepl",     one(0000510),           one(0170770),           "dsDd"},        /* memory to register */
+{"movepl",     one(0000710),           one(0170770),           "Ddds"},        /* register to memory */
+{"movepw",     one(0000410),           one(0170770),           "dsDd"},        /* memory to register */
+{"movepw",     one(0000610),           one(0170770),           "Ddds"},        /* register to memory */
+{"moveq",      one(0070000),           one(0170400),           "MsDd"},
+{"movew",      one(0030000),           one(0170000),           "*w$d"},
+{"movew",      one(0030100),           one(0170700),           "*wAd"},        /* movea,       written as move */
+{"movew",      one(0040300),           one(0177700),           "Ss$s"},        /* Move from sr */
+{"movew",      one(0041300),           one(0177700),           "Cs$s"},        /* Move from ccr */
+{"movew",      one(0042300),           one(0177700),           ";wCd"},        /* move to ccr */
+{"movew",      one(0043300),           one(0177700),           ";wSd"},        /* move to sr */
+
+{"movesb",     two(0007000, 0),        two(0177700, 07777),    "~sR1"},         /* moves from memory */
+{"movesb",     two(0007000, 04000),    two(0177700, 07777),    "R1~s"},         /* moves to memory */
+{"movesl",     two(0007200, 0),        two(0177700, 07777),    "~sR1"},         /* moves from memory */
+{"movesl",     two(0007200, 04000),    two(0177700, 07777),    "R1~s"},         /* moves to memory */
+{"movesw",     two(0007100, 0),        two(0177700, 07777),    "~sR1"},         /* moves from memory */
+{"movesw",     two(0007100, 04000),    two(0177700, 07777),    "R1~s"},         /* moves to memory */
+
+{"mulsl",      two(0046000, 004000),   two(0177700, 0107770),  ";lD1"},
+{"mulsl",      two(0046000, 006000),   two(0177700, 0107770),  ";lD3D1"},
+{"mulsw",      one(0140700),           one(0170700),           ";wDd"},
+{"muls",       one(0140700),           one(0170700),           ";wDd"},
+{"mulul",      two(0046000, 000000),   two(0177700, 0107770),  ";lD1"},
+{"mulul",      two(0046000, 002000),   two(0177700, 0107770),  ";lD3D1"},
+{"muluw",      one(0140300),           one(0170700),           ";wDd"},
+{"mulu",       one(0140300),           one(0170700),           ";wDd"},
+{"nbcd",       one(0044000),           one(0177700),           "$s"},
+{"negb",       one(0042000),           one(0177700),           "$s"},
+{"negl",       one(0042200),           one(0177700),           "$s"},
+{"negw",       one(0042100),           one(0177700),           "$s"},
+{"negxb",      one(0040000),           one(0177700),           "$s"},
+{"negxl",      one(0040200),           one(0177700),           "$s"},
+{"negxw",      one(0040100),           one(0177700),           "$s"},
+{"nop",                one(0047161),           one(0177777),           ""},
+{"notb",       one(0043000),           one(0177700),           "$s"},
+{"notl",       one(0043200),           one(0177700),           "$s"},
+{"notw",       one(0043100),           one(0177700),           "$s"},
+
+{"orb",                one(0000000),           one(0177700),           "#b$s"},        /* ori written as or */
+{"orb",                one(0000074),           one(0177777),           "#bCs"},        /* ori to ccr */
+{"orb",                one(0100000),           one(0170700),           ";bDd"},        /* memory to register */
+{"orb",                one(0100400),           one(0170700),           "Dd~s"},        /* register to memory */
+{"orib",       one(0000000),           one(0177700),           "#b$s"},
+{"orib",       one(0000074),           one(0177777),           "#bCs"},        /* ori to ccr */
+{"oril",       one(0000200),           one(0177700),           "#l$s"},
+{"oriw",       one(0000100),           one(0177700),           "#w$s"},
+{"oriw",       one(0000174),           one(0177777),           "#wSs"},        /* ori to sr */
+{"orl",                one(0000200),           one(0177700),           "#l$s"},
+{"orl",                one(0100200),           one(0170700),           ";lDd"},        /* memory to register */
+{"orl",                one(0100600),           one(0170700),           "Dd~s"},        /* register to memory */
+{"orw",                one(0000100),           one(0177700),           "#w$s"},
+{"orw",                one(0000174),           one(0177777),           "#wSs"},        /* ori to sr */
+{"orw",                one(0100100),           one(0170700),           ";wDd"},        /* memory to register */
+{"orw",                one(0100500),           one(0170700),           "Dd~s"},        /* register to memory */
+
+{"pack",       one(0100500),           one(0170770),           "DsDd#w"},      /* pack Ds,     Dd,     #w */
+{"pack",       one(0100510),           one(0170770),           "-s-d#w"},      /* pack -(As),  -(Ad),  #w */
+{"pea",                one(0044100),           one(0177700),           "!s"},
+{"reset",      one(0047160),           one(0177777),           ""},
+
+{"rolb",       one(0160430),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"rolb",       one(0160470),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"roll",       one(0160630),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"roll",       one(0160670),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"rolw",       one(0160530),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"rolw",       one(0160570),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"rolw",       one(0163700),           one(0177700),           "~s"},  /* Rotate memory */
+{"rorb",       one(0160030),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"rorb",       one(0160070),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"rorl",       one(0160230),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"rorl",       one(0160270),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"rorw",       one(0160130),           one(0170770),           "QdDs"},        /* rorb #Q,     Ds */
+{"rorw",       one(0160170),           one(0170770),           "DdDs"},        /* rorb Dd,     Ds */
+{"rorw",       one(0163300),           one(0177700),           "~s"},  /* Rotate memory */
+
+{"roxlb",      one(0160420),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxlb",      one(0160460),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxll",      one(0160620),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxll",      one(0160660),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxlw",      one(0160520),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxlw",      one(0160560),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxlw",      one(0162700),           one(0177700),           "~s"},  /* Rotate memory */
+{"roxrb",      one(0160020),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxrb",      one(0160060),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxrl",      one(0160220),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxrl",      one(0160260),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxrw",      one(0160120),           one(0170770),           "QdDs"},        /* roxrb #Q,    Ds */
+{"roxrw",      one(0160160),           one(0170770),           "DdDs"},        /* roxrb Dd,    Ds */
+{"roxrw",      one(0162300),           one(0177700),           "~s"},  /* Rotate memory */
+
+{"rtd",                one(0047164),           one(0177777),           "#w"},
+{"rte",                one(0047163),           one(0177777),           ""},
+{"rtm",                one(0003300),           one(0177760),           "Rs"},
+{"rtr",                one(0047167),           one(0177777),           ""},
+{"rts",                one(0047165),           one(0177777),           ""},
+
+{"scc",                one(0052300),           one(0177700),           "$s"},
+{"scs",                one(0052700),           one(0177700),           "$s"},
+{"seq",                one(0053700),           one(0177700),           "$s"},
+{"sf",         one(0050700),           one(0177700),           "$s"},
+{"sge",                one(0056300),           one(0177700),           "$s"},
+{"sgt",                one(0057300),           one(0177700),           "$s"},
+{"shi",                one(0051300),           one(0177700),           "$s"},
+{"sle",                one(0057700),           one(0177700),           "$s"},
+{"sls",                one(0051700),           one(0177700),           "$s"},
+{"slt",                one(0056700),           one(0177700),           "$s"},
+{"smi",                one(0055700),           one(0177700),           "$s"},
+{"sne",                one(0053300),           one(0177700),           "$s"},
+{"spl",                one(0055300),           one(0177700),           "$s"},
+{"st",         one(0050300),           one(0177700),           "$s"},
+{"svc",                one(0054300),           one(0177700),           "$s"},
+{"svs",                one(0054700),           one(0177700),           "$s"},
+
+{"sbcd",       one(0100400),           one(0170770),           "DsDd"},
+{"sbcd",       one(0100410),           one(0170770),           "-s-d"},
+{"stop",       one(0047162),           one(0177777),           "#w"},
+
+{"subal",      one(0110700),           one(0170700),           "*lAd"},
+{"subaw",      one(0110300),           one(0170700),           "*wAd"},
+{"subb",       one(0050400),           one(0170700),           "Qd%s"},        /* subq written as sub */
+{"subb",       one(0002000),           one(0177700),           "#b$s"},        /* subi written as sub */
+{"subb",       one(0110000),           one(0170700),           ";bDd"},        /* subb ? ?,    Dd */
+{"subb",       one(0110400),           one(0170700),           "Dd~s"},        /* subb Dd,     ? ? */
+{"subib",      one(0002000),           one(0177700),           "#b$s"},
+{"subil",      one(0002200),           one(0177700),           "#l$s"},
+{"subiw",      one(0002100),           one(0177700),           "#w$s"},
+{"subl",       one(0050600),           one(0170700),           "Qd%s"},
+{"subl",       one(0002200),           one(0177700),           "#l$s"},
+{"subl",       one(0110700),           one(0170700),           "*lAd"},
+{"subl",       one(0110200),           one(0170700),           "*lDd"},
+{"subl",       one(0110600),           one(0170700),           "Dd~s"},
+{"subqb",      one(0050400),           one(0170700),           "Qd%s"},
+{"subql",      one(0050600),           one(0170700),           "Qd%s"},
+{"subqw",      one(0050500),           one(0170700),           "Qd%s"},
+{"subw",       one(0050500),           one(0170700),           "Qd%s"},
+{"subw",       one(0002100),           one(0177700),           "#w$s"},
+{"subw",       one(0110100),           one(0170700),           "*wDd"},
+{"subw",       one(0110300),           one(0170700),           "*wAd"},        /* suba written as sub */
+{"subw",       one(0110500),           one(0170700),           "Dd~s"},
+{"subxb",      one(0110400),           one(0170770),           "DsDd"},        /* subxb Ds,    Dd */
+{"subxb",      one(0110410),           one(0170770),           "-s-d"},        /* subxb -(As), -(Ad) */
+{"subxl",      one(0110600),           one(0170770),           "DsDd"},
+{"subxl",      one(0110610),           one(0170770),           "-s-d"},
+{"subxw",      one(0110500),           one(0170770),           "DsDd"},
+{"subxw",      one(0110510),           one(0170770),           "-s-d"},
+
+{"swap",       one(0044100),           one(0177770),           "Ds"},
+       
+{"tas",                one(0045300),           one(0177700),           "$s"},
+{"trap",       one(0047100),           one(0177760),           "Ts"},
+
+{"trapcc",     one(0052374),           one(0177777),           ""},
+{"trapcs",     one(0052774),           one(0177777),           ""},
+{"trapeq",     one(0053774),           one(0177777),           ""},
+{"trapf",      one(0050774),           one(0177777),           ""},
+{"trapge",     one(0056374),           one(0177777),           ""},
+{"trapgt",     one(0057374),           one(0177777),           ""},
+{"traphi",     one(0051374),           one(0177777),           ""},
+{"traple",     one(0057774),           one(0177777),           ""},
+{"trapls",     one(0051774),           one(0177777),           ""},
+{"traplt",     one(0056774),           one(0177777),           ""},
+{"trapmi",     one(0055774),           one(0177777),           ""},
+{"trapne",     one(0053374),           one(0177777),           ""},
+{"trappl",     one(0055374),           one(0177777),           ""},
+{"trapt",      one(0050374),           one(0177777),           ""},
+{"trapvc",     one(0054374),           one(0177777),           ""},
+{"trapvs",     one(0054774),           one(0177777),           ""},
+
+{"trapcc.w",   one(0052372),           one(0177777),           ""},
+{"trapcs.w",   one(0052772),           one(0177777),           ""},
+{"trapeq.w",   one(0053772),           one(0177777),           ""},
+{"trapf.w",    one(0050772),           one(0177777),           ""},
+{"trapge.w",   one(0056372),           one(0177777),           ""},
+{"trapgt.w",   one(0057372),           one(0177777),           ""},
+{"traphi.w",   one(0051372),           one(0177777),           ""},
+{"traple.w",   one(0057772),           one(0177777),           ""},
+{"trapls.w",   one(0051772),           one(0177777),           ""},
+{"traplt.w",   one(0056772),           one(0177777),           ""},
+{"trapmi.w",   one(0055772),           one(0177777),           ""},
+{"trapne.w",   one(0053372),           one(0177777),           ""},
+{"trappl.w",   one(0055372),           one(0177777),           ""},
+{"trapt.w",    one(0050372),           one(0177777),           ""},
+{"trapvc.w",   one(0054372),           one(0177777),           ""},
+{"trapvs.w",   one(0054772),           one(0177777),           ""},
+
+{"trapcc.l",   one(0052373),           one(0177777),           ""},
+{"trapcs.l",   one(0052773),           one(0177777),           ""},
+{"trapeq.l",   one(0053773),           one(0177777),           ""},
+{"trapf.l",    one(0050773),           one(0177777),           ""},
+{"trapge.l",   one(0056373),           one(0177777),           ""},
+{"trapgt.l",   one(0057373),           one(0177777),           ""},
+{"traphi.l",   one(0051373),           one(0177777),           ""},
+{"traple.l",   one(0057773),           one(0177777),           ""},
+{"trapls.l",   one(0051773),           one(0177777),           ""},
+{"traplt.l",   one(0056773),           one(0177777),           ""},
+{"trapmi.l",   one(0055773),           one(0177777),           ""},
+{"trapne.l",   one(0053373),           one(0177777),           ""},
+{"trappl.l",   one(0055373),           one(0177777),           ""},
+{"trapt.l",    one(0050373),           one(0177777),           ""},
+{"trapvc.l",   one(0054373),           one(0177777),           ""},
+{"trapvs.l",   one(0054773),           one(0177777),           ""},
+
+{"trapv",      one(0047166),           one(0177777),           ""},
+
+{"tstb",       one(0045000),           one(0177700),           ";b"},
+{"tstw",       one(0045100),           one(0177700),           "*w"},
+{"tstl",       one(0045200),           one(0177700),           "*l"},
+
+{"unlk",       one(0047130),           one(0177770),           "As"},
+{"unpk",       one(0100600),           one(0170770),           "DsDd#w"},
+{"unpk",       one(0100610),           one(0170770),           "-s-d#w"},
+       /* JF floating pt stuff moved down here */
+
+{"fabsb",      two(0xF000, 0x5818),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fabsd",      two(0xF000, 0x5418),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fabsl",      two(0xF000, 0x4018),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fabsp",      two(0xF000, 0x4C18),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fabss",      two(0xF000, 0x4418),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fabsw",      two(0xF000, 0x5018),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fabsx",      two(0xF000, 0x0018),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fabsx",      two(0xF000, 0x4818),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fabsx",      two(0xF000, 0x0018),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"facosb",     two(0xF000, 0x581C),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"facosd",     two(0xF000, 0x541C),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"facosl",     two(0xF000, 0x401C),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"facosp",     two(0xF000, 0x4C1C),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"facoss",     two(0xF000, 0x441C),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"facosw",     two(0xF000, 0x501C),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"facosx",     two(0xF000, 0x001C),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"facosx",     two(0xF000, 0x481C),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"facosx",     two(0xF000, 0x001C),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"faddb",      two(0xF000, 0x5822),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"faddd",      two(0xF000, 0x5422),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"faddl",      two(0xF000, 0x4022),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"faddp",      two(0xF000, 0x4C22),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fadds",      two(0xF000, 0x4422),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"faddw",      two(0xF000, 0x5022),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"faddx",      two(0xF000, 0x0022),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"faddx",      two(0xF000, 0x4822),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"faddx",   two(0xF000, 0x0022),    two(0xF1C0, 0xE07F),    "IiFt"}, JF removed */
+
+{"fasinb",     two(0xF000, 0x580C),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fasind",     two(0xF000, 0x540C),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fasinl",     two(0xF000, 0x400C),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fasinp",     two(0xF000, 0x4C0C),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fasins",     two(0xF000, 0x440C),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fasinw",     two(0xF000, 0x500C),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fasinx",     two(0xF000, 0x000C),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fasinx",     two(0xF000, 0x480C),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fasinx",     two(0xF000, 0x000C),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fatanb",     two(0xF000, 0x580A),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fatand",     two(0xF000, 0x540A),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fatanl",     two(0xF000, 0x400A),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fatanp",     two(0xF000, 0x4C0A),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fatans",     two(0xF000, 0x440A),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fatanw",     two(0xF000, 0x500A),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fatanx",     two(0xF000, 0x000A),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fatanx",     two(0xF000, 0x480A),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fatanx",     two(0xF000, 0x000A),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fatanhb",    two(0xF000, 0x580D),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fatanhd",    two(0xF000, 0x540D),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fatanhl",    two(0xF000, 0x400D),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fatanhp",    two(0xF000, 0x4C0D),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fatanhs",    two(0xF000, 0x440D),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fatanhw",    two(0xF000, 0x500D),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fatanhx",    two(0xF000, 0x000D),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fatanhx",    two(0xF000, 0x480D),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fatanhx",    two(0xF000, 0x000D),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fbeq",       one(0xF081),            one(0xF1BF),            "IdBc"},
+{"fbf",                one(0xF080),            one(0xF1BF),            "IdBc"},
+{"fbge",       one(0xF093),            one(0xF1BF),            "IdBc"},
+{"fbgl",       one(0xF096),            one(0xF1BF),            "IdBc"},
+{"fbgle",      one(0xF097),            one(0xF1BF),            "IdBc"},
+{"fbgt",       one(0xF092),            one(0xF1BF),            "IdBc"},
+{"fble",       one(0xF095),            one(0xF1BF),            "IdBc"},
+{"fblt",       one(0xF094),            one(0xF1BF),            "IdBc"},
+{"fbne",       one(0xF08E),            one(0xF1BF),            "IdBc"},
+{"fbnge",      one(0xF09C),            one(0xF1BF),            "IdBc"},
+{"fbngl",      one(0xF099),            one(0xF1BF),            "IdBc"},
+{"fbngle",     one(0xF098),            one(0xF1BF),            "IdBc"},
+{"fbngt",      one(0xF09D),            one(0xF1BF),            "IdBc"},
+{"fbnle",      one(0xF09A),            one(0xF1BF),            "IdBc"},
+{"fbnlt",      one(0xF09B),            one(0xF1BF),            "IdBc"},
+{"fboge",      one(0xF083),            one(0xF1BF),            "IdBc"},
+{"fbogl",      one(0xF086),            one(0xF1BF),            "IdBc"},
+{"fbogt",      one(0xF082),            one(0xF1BF),            "IdBc"},
+{"fbole",      one(0xF085),            one(0xF1BF),            "IdBc"},
+{"fbolt",      one(0xF084),            one(0xF1BF),            "IdBc"},
+{"fbor",       one(0xF087),            one(0xF1BF),            "IdBc"},
+{"fbseq",      one(0xF091),            one(0xF1BF),            "IdBc"},
+{"fbsf",       one(0xF090),            one(0xF1BF),            "IdBc"},
+{"fbsne",      one(0xF09E),            one(0xF1BF),            "IdBc"},
+{"fbst",       one(0xF09F),            one(0xF1BF),            "IdBc"},
+{"fbt",                one(0xF08F),            one(0xF1BF),            "IdBc"},
+{"fbueq",      one(0xF089),            one(0xF1BF),            "IdBc"},
+{"fbuge",      one(0xF08B),            one(0xF1BF),            "IdBc"},
+{"fbugt",      one(0xF08A),            one(0xF1BF),            "IdBc"},
+{"fbule",      one(0xF08D),            one(0xF1BF),            "IdBc"},
+{"fbult",      one(0xF08C),            one(0xF1BF),            "IdBc"},
+{"fbun",       one(0xF088),            one(0xF1BF),            "IdBc"},
+
+{"fcmpb",      two(0xF000, 0x5838),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fcmpd",      two(0xF000, 0x5438),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fcmpl",      two(0xF000, 0x4038),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fcmpp",      two(0xF000, 0x4C38),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fcmps",      two(0xF000, 0x4438),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fcmpw",      two(0xF000, 0x5038),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fcmpx",      two(0xF000, 0x0038),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fcmpx",      two(0xF000, 0x4838),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fcmpx",   two(0xF000, 0x0038),    two(0xF1C0, 0xE07F),    "IiFt"}, JF removed */
+
+{"fcosb",      two(0xF000, 0x581D),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fcosd",      two(0xF000, 0x541D),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fcosl",      two(0xF000, 0x401D),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fcosp",      two(0xF000, 0x4C1D),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fcoss",      two(0xF000, 0x441D),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fcosw",      two(0xF000, 0x501D),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fcosx",      two(0xF000, 0x001D),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fcosx",      two(0xF000, 0x481D),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fcosx",      two(0xF000, 0x001D),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fcoshb",     two(0xF000, 0x5819),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fcoshd",     two(0xF000, 0x5419),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fcoshl",     two(0xF000, 0x4019),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fcoshp",     two(0xF000, 0x4C19),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fcoshs",     two(0xF000, 0x4419),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fcoshw",     two(0xF000, 0x5019),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fcoshx",     two(0xF000, 0x0019),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fcoshx",     two(0xF000, 0x4819),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fcoshx",     two(0xF000, 0x0019),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fdbeq",      two(0xF048, 0x0001),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbf",       two(0xF048, 0x0000),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbge",      two(0xF048, 0x0013),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbgl",      two(0xF048, 0x0016),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbgle",     two(0xF048, 0x0017),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbgt",      two(0xF048, 0x0012),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdble",      two(0xF048, 0x0015),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdblt",      two(0xF048, 0x0014),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbne",      two(0xF048, 0x000E),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbnge",     two(0xF048, 0x001C),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbngl",     two(0xF048, 0x0019),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbngle",    two(0xF048, 0x0018),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbngt",     two(0xF048, 0x001D),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbnle",     two(0xF048, 0x001A),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbnlt",     two(0xF048, 0x001B),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdboge",     two(0xF048, 0x0003),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbogl",     two(0xF048, 0x0006),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbogt",     two(0xF048, 0x0002),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbole",     two(0xF048, 0x0005),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbolt",     two(0xF048, 0x0004),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbor",      two(0xF048, 0x0007),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbseq",     two(0xF048, 0x0011),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbsf",      two(0xF048, 0x0010),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbsne",     two(0xF048, 0x001E),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbst",      two(0xF048, 0x001F),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbt",       two(0xF048, 0x000F),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbueq",     two(0xF048, 0x0009),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbuge",     two(0xF048, 0x000B),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbugt",     two(0xF048, 0x000A),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbule",     two(0xF048, 0x000D),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbult",     two(0xF048, 0x000C),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+{"fdbun",      two(0xF048, 0x0008),    two(0xF1F8, 0xFFFF),    "IiDsBw"},
+
+{"fdivb",      two(0xF000, 0x5820),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fdivd",      two(0xF000, 0x5420),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fdivl",      two(0xF000, 0x4020),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fdivp",      two(0xF000, 0x4C20),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fdivs",      two(0xF000, 0x4420),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fdivw",      two(0xF000, 0x5020),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fdivx",      two(0xF000, 0x0020),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fdivx",      two(0xF000, 0x4820),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fdivx",   two(0xF000, 0x0020),    two(0xF1C0, 0xE07F),    "IiFt"}, JF */
+
+{"fetoxb",     two(0xF000, 0x5810),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fetoxd",     two(0xF000, 0x5410),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fetoxl",     two(0xF000, 0x4010),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fetoxp",     two(0xF000, 0x4C10),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fetoxs",     two(0xF000, 0x4410),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fetoxw",     two(0xF000, 0x5010),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fetoxx",     two(0xF000, 0x0010),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fetoxx",     two(0xF000, 0x4810),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fetoxx",     two(0xF000, 0x0010),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fetoxm1b",   two(0xF000, 0x5808),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fetoxm1d",   two(0xF000, 0x5408),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fetoxm1l",   two(0xF000, 0x4008),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fetoxm1p",   two(0xF000, 0x4C08),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fetoxm1s",   two(0xF000, 0x4408),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fetoxm1w",   two(0xF000, 0x5008),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fetoxm1x",   two(0xF000, 0x0008),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fetoxm1x",   two(0xF000, 0x4808),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fetoxm1x",   two(0xF000, 0x0008),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fgetexpb",   two(0xF000, 0x581E),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fgetexpd",   two(0xF000, 0x541E),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fgetexpl",   two(0xF000, 0x401E),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fgetexpp",   two(0xF000, 0x4C1E),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fgetexps",   two(0xF000, 0x441E),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fgetexpw",   two(0xF000, 0x501E),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fgetexpx",   two(0xF000, 0x001E),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fgetexpx",   two(0xF000, 0x481E),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fgetexpx",   two(0xF000, 0x001E),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fgetmanb",   two(0xF000, 0x581F),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fgetmand",   two(0xF000, 0x541F),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fgetmanl",   two(0xF000, 0x401F),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fgetmanp",   two(0xF000, 0x4C1F),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fgetmans",   two(0xF000, 0x441F),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fgetmanw",   two(0xF000, 0x501F),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fgetmanx",   two(0xF000, 0x001F),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fgetmanx",   two(0xF000, 0x481F),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fgetmanx",   two(0xF000, 0x001F),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fintb",      two(0xF000, 0x5801),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fintd",      two(0xF000, 0x5401),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fintl",      two(0xF000, 0x4001),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fintp",      two(0xF000, 0x4C01),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fints",      two(0xF000, 0x4401),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fintw",      two(0xF000, 0x5001),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fintx",      two(0xF000, 0x0001),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fintx",      two(0xF000, 0x4801),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fintx",      two(0xF000, 0x0001),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fintrzb",    two(0xF000, 0x5803),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fintrzd",    two(0xF000, 0x5403),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fintrzl",    two(0xF000, 0x4003),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fintrzp",    two(0xF000, 0x4C03),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fintrzs",    two(0xF000, 0x4403),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fintrzw",    two(0xF000, 0x5003),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fintrzx",    two(0xF000, 0x0003),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fintrzx",    two(0xF000, 0x4803),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fintrzx",    two(0xF000, 0x0003),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"flog10b",    two(0xF000, 0x5815),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"flog10d",    two(0xF000, 0x5415),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"flog10l",    two(0xF000, 0x4015),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"flog10p",    two(0xF000, 0x4C15),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"flog10s",    two(0xF000, 0x4415),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"flog10w",    two(0xF000, 0x5015),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"flog10x",    two(0xF000, 0x0015),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"flog10x",    two(0xF000, 0x4815),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"flog10x",    two(0xF000, 0x0015),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"flog2b",     two(0xF000, 0x5816),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"flog2d",     two(0xF000, 0x5416),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"flog2l",     two(0xF000, 0x4016),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"flog2p",     two(0xF000, 0x4C16),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"flog2s",     two(0xF000, 0x4416),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"flog2w",     two(0xF000, 0x5016),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"flog2x",     two(0xF000, 0x0016),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"flog2x",     two(0xF000, 0x4816),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"flog2x",     two(0xF000, 0x0016),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"flognb",     two(0xF000, 0x5814),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"flognd",     two(0xF000, 0x5414),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"flognl",     two(0xF000, 0x4014),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"flognp",     two(0xF000, 0x4C14),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"flogns",     two(0xF000, 0x4414),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"flognw",     two(0xF000, 0x5014),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"flognx",     two(0xF000, 0x0014),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"flognx",     two(0xF000, 0x4814),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"flognx",     two(0xF000, 0x0014),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"flognp1b",   two(0xF000, 0x5806),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"flognp1d",   two(0xF000, 0x5406),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"flognp1l",   two(0xF000, 0x4006),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"flognp1p",   two(0xF000, 0x4C06),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"flognp1s",   two(0xF000, 0x4406),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"flognp1w",   two(0xF000, 0x5006),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"flognp1x",   two(0xF000, 0x0006),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"flognp1x",   two(0xF000, 0x4806),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"flognp1x",   two(0xF000, 0x0006),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fmodb",      two(0xF000, 0x5821),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fmodd",      two(0xF000, 0x5421),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fmodl",      two(0xF000, 0x4021),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fmodp",      two(0xF000, 0x4C21),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fmods",      two(0xF000, 0x4421),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fmodw",      two(0xF000, 0x5021),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fmodx",      two(0xF000, 0x0021),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fmodx",      two(0xF000, 0x4821),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fmodx",   two(0xF000, 0x0021),    two(0xF1C0, 0xE07F),    "IiFt"}, JF */
+
+{"fmoveb",     two(0xF000, 0x5800),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},              /* fmove from <ea> to fp<n> */
+{"fmoveb",     two(0xF000, 0x7800),    two(0xF1C0, 0xFC7F),    "IiF7@b"},              /* fmove from fp<n> to <ea> */
+{"fmoved",     two(0xF000, 0x5400),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},              /* fmove from <ea> to fp<n> */
+{"fmoved",     two(0xF000, 0x7400),    two(0xF1C0, 0xFC7F),    "IiF7@F"},              /* fmove from fp<n> to <ea> */
+{"fmovel",     two(0xF000, 0x4000),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},              /* fmove from <ea> to fp<n> */
+{"fmovel",     two(0xF000, 0x6000),    two(0xF1C0, 0xFC7F),    "IiF7@l"},              /* fmove from fp<n> to <ea> */
+/* Warning:  The addressing modes on these are probably not right:
+   esp, Areg direct is only allowed for FPI */
+               /* fmove.l from/to system control registers: */
+{"fmovel",     two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "Iis8@s"},
+{"fmovel",     two(0xF000, 0x8000),    two(0xF1C0, 0xE3FF),    "Ii*ls8"},
+
+/* {"fmovel",  two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "Iis8@s"},
+{"fmovel",     two(0xF000, 0x8000),    two(0xF2C0, 0xE3FF),    "Ii*ss8"}, */
+
+{"fmovep",     two(0xF000, 0x4C00),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},              /* fmove from <ea> to fp<n> */
+{"fmovep",     two(0xF000, 0x6C00),    two(0xF1C0, 0xFC00),    "IiF7@pkC"},            /* fmove.p with k-factors: */
+{"fmovep",     two(0xF000, 0x7C00),    two(0xF1C0, 0xFC0F),    "IiF7@pDk"},            /* fmove.p with k-factors: */
+
+{"fmoves",     two(0xF000, 0x4400),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},              /* fmove from <ea> to fp<n> */
+{"fmoves",     two(0xF000, 0x6400),    two(0xF1C0, 0xFC7F),    "IiF7@f"},              /* fmove from fp<n> to <ea> */
+{"fmovew",     two(0xF000, 0x5000),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},              /* fmove from <ea> to fp<n> */
+{"fmovew",     two(0xF000, 0x7000),    two(0xF1C0, 0xFC7F),    "IiF7@w"},              /* fmove from fp<n> to <ea> */
+{"fmovex",     two(0xF000, 0x0000),    two(0xF1C0, 0xE07F),    "IiF8F7"},              /* fmove from <ea> to fp<n> */
+{"fmovex",     two(0xF000, 0x4800),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},              /* fmove from <ea> to fp<n> */
+{"fmovex",     two(0xF000, 0x6800),    two(0xF1C0, 0xFC7F),    "IiF7@x"},              /* fmove from fp<n> to <ea> */
+/* JF removed {"fmovex",       two(0xF000, 0x0000),    two(0xF1C0, 0xE07F),    "IiFt"},                / * fmove from <ea> to fp<n> */
+
+{"fmovecrx",   two(0xF000, 0x5C00),    two(0xF1FF, 0xFC00),    "Ii#CF7"},              /* fmovecr.x #ccc,      FPn */
+{"fmovecr",    two(0xF000, 0x5C00),    two(0xF1FF, 0xFC00),    "Ii#CF7"},
+
+/* Other fmovemx.  */
+{"fmovemx",    two(0xF020, 0xE000),    two(0xF1F8, 0xFF00),    "IdL3-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+{"fmovemx",    two(0xF020, 0xE000),    two(0xF1F8, 0xFF00),    "Id#3-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+
+{"fmovemx",    two(0xF020, 0xE800),    two(0xF1F8, 0xFF8F),    "IiDk-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+
+{"fmovemx",    two(0xF000, 0xF000),    two(0xF1C0, 0xFF00),    "Id#3&s"},              /* fmovem.x to control, static and dynamic: */
+{"fmovemx",    two(0xF000, 0xF800),    two(0xF1C0, 0xFF8F),    "IiDk&s"},              /* fmovem.x to control, static and dynamic: */
+{"fmovemx",    two(0xF000, 0xD000),    two(0xF1C0, 0xFF00),    "Id&s#3"},              /* fmovem.x from control,       static and dynamic: */
+{"fmovemx",    two(0xF000, 0xD800),    two(0xF1C0, 0xFF8F),    "Ii&sDk"},              /* fmovem.x from control,       static and dynamic: */
+{"fmovemx",    two(0xF000, 0xF000),    two(0xF1C0, 0xFF00),    "Idl3&s"},              /* fmovem.x to control, static and dynamic: */
+{"fmovemx",    two(0xF000, 0xD000),    two(0xF1C0, 0xFF00),    "Id&sl3"},              /* fmovem.x from control,       static and dynamic: */
+
+{"fmovemx",    two(0xF018, 0xD000),    two(0xF1F8, 0xFF00),    "Id+sl3"},              /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovemx",    two(0xF018, 0xD000),    two(0xF1F8, 0xFF00),    "Id+s#3"},              /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovemx",    two(0xF018, 0xD800),    two(0xF1F8, 0xFF8F),    "Ii+sDk"},              /* fmovem.x from autoincrement, static and dynamic: */
+
+{"fmoveml",    two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "IiL8@s"},
+{"fmoveml",    two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "Ii#8@s"},
+{"fmoveml",    two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "Iis8@s"},
+
+{"fmoveml",    two(0xF000, 0x8000),    two(0xF2C0, 0xE3FF),    "Ii*sL8"},
+{"fmoveml",    two(0xF000, 0x8000),    two(0xF1C0, 0xE3FF),    "Ii*s#8"},
+{"fmoveml",    two(0xF000, 0x8000),    two(0xF1C0, 0xE3FF),    "Ii*ss8"},
+
+/* fmovemx with register lists */
+{"fmovem",     two(0xF020, 0xE000),    two(0xF1F8, 0xFF00),    "IdL3-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+{"fmovem",     two(0xF000, 0xF000),    two(0xF1C0, 0xFF00),    "Idl3&s"},              /* fmovem.x to control, static and dynamic: */
+{"fmovem",     two(0xF018, 0xD000),    two(0xF1F8, 0xFF00),    "Id+sl3"},              /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovem",     two(0xF000, 0xD000),    two(0xF1C0, 0xFF00),    "Id&sl3"},              /* fmovem.x from control,       static and dynamic: */
+
+       /* Alternate mnemonics for GNU as and GNU CC */
+{"fmovem",     two(0xF020, 0xE000),    two(0xF1F8, 0xFF00),    "Id#3-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+{"fmovem",     two(0xF020, 0xE800),    two(0xF1F8, 0xFF8F),    "IiDk-s"},              /* fmovem.x to autodecrement,   static and dynamic */
+
+{"fmovem",     two(0xF000, 0xF000),    two(0xF1C0, 0xFF00),    "Id#3&s"},              /* fmovem.x to control, static and dynamic: */
+{"fmovem",     two(0xF000, 0xF800),    two(0xF1C0, 0xFF8F),    "IiDk&s"},              /* fmovem.x to control, static and dynamic: */
+
+{"fmovem",     two(0xF018, 0xD000),    two(0xF1F8, 0xFF00),    "Id+s#3"},              /* fmovem.x from autoincrement, static and dynamic: */
+{"fmovem",     two(0xF018, 0xD800),    two(0xF1F8, 0xFF8F),    "Ii+sDk"},              /* fmovem.x from autoincrement, static and dynamic: */
+  
+{"fmovem",     two(0xF000, 0xD000),    two(0xF1C0, 0xFF00),    "Id&s#3"},              /* fmovem.x from control,       static and dynamic: */
+{"fmovem",     two(0xF000, 0xD800),    two(0xF1C0, 0xFF8F),    "Ii&sDk"},              /* fmovem.x from control,       static and dynamic: */
+
+/* fmoveml a FP-control register */
+{"fmovem",     two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "Iis8@s"},
+{"fmovem",     two(0xF000, 0x8000),    two(0xF1C0, 0xE3FF),    "Ii*ss8"},
+
+/* fmoveml a FP-control reglist */
+{"fmovem",     two(0xF000, 0xA000),    two(0xF1C0, 0xE3FF),    "IiL8@s"},
+{"fmovem",     two(0xF000, 0x8000),    two(0xF2C0, 0xE3FF),    "Ii*sL8"},
+
+{"fmulb",      two(0xF000, 0x5823),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fmuld",      two(0xF000, 0x5423),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fmull",      two(0xF000, 0x4023),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fmulp",      two(0xF000, 0x4C23),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fmuls",      two(0xF000, 0x4423),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fmulw",      two(0xF000, 0x5023),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fmulx",      two(0xF000, 0x0023),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fmulx",      two(0xF000, 0x4823),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fmulx",   two(0xF000, 0x0023),    two(0xF1C0, 0xE07F),    "IiFt"}, JF */
+
+{"fnegb",      two(0xF000, 0x581A),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fnegd",      two(0xF000, 0x541A),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fnegl",      two(0xF000, 0x401A),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fnegp",      two(0xF000, 0x4C1A),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fnegs",      two(0xF000, 0x441A),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fnegw",      two(0xF000, 0x501A),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fnegx",      two(0xF000, 0x001A),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fnegx",      two(0xF000, 0x481A),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fnegx",      two(0xF000, 0x001A),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fnop",       two(0xF280, 0x0000),    two(0xFFFF, 0xFFFF),    "Ii"},
+
+{"fremb",      two(0xF000, 0x5825),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fremd",      two(0xF000, 0x5425),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"freml",      two(0xF000, 0x4025),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fremp",      two(0xF000, 0x4C25),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"frems",      two(0xF000, 0x4425),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fremw",      two(0xF000, 0x5025),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fremx",      two(0xF000, 0x0025),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fremx",      two(0xF000, 0x4825),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fremx",   two(0xF000, 0x0025),    two(0xF1C0, 0xE07F),    "IiFt"}, JF */
+
+{"frestore",   one(0xF140),            one(0xF1C0),            "Id&s"},
+{"frestore",   one(0xF158),            one(0xF1F8),            "Id+s"},
+{"fsave",      one(0xF100),            one(0xF1C0),            "Id&s"},
+{"fsave",      one(0xF120),            one(0xF1F8),            "Id-s"},
+
+{"fsincosb",   two(0xF000, 0x5830),    two(0xF1C0, 0xFC78),    "Ii;bF7FC"},
+{"fsincosd",   two(0xF000, 0x5430),    two(0xF1C0, 0xFC78),    "Ii;FF7FC"},
+{"fsincosl",   two(0xF000, 0x4030),    two(0xF1C0, 0xFC78),    "Ii;lF7FC"},
+{"fsincosp",   two(0xF000, 0x4C30),    two(0xF1C0, 0xFC78),    "Ii;pF7FC"},
+{"fsincoss",   two(0xF000, 0x4430),    two(0xF1C0, 0xFC78),    "Ii;fF7FC"},
+{"fsincosw",   two(0xF000, 0x5030),    two(0xF1C0, 0xFC78),    "Ii;wF7FC"},
+{"fsincosx",   two(0xF000, 0x0030),    two(0xF1C0, 0xE078),    "IiF8F7FC"},
+{"fsincosx",   two(0xF000, 0x4830),    two(0xF1C0, 0xFC78),    "Ii;xF7FC"},
+
+{"fscaleb",    two(0xF000, 0x5826),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fscaled",    two(0xF000, 0x5426),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fscalel",    two(0xF000, 0x4026),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fscalep",    two(0xF000, 0x4C26),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fscales",    two(0xF000, 0x4426),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fscalew",    two(0xF000, 0x5026),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fscalex",    two(0xF000, 0x0026),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fscalex",    two(0xF000, 0x4826),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+/* {"fscalex", two(0xF000, 0x0026),    two(0xF1C0, 0xE07F),    "IiFt"}, JF */
+
+/* $ is necessary to prevent the assembler from using PC-relative.
+   If @ were used, "label: fseq label" could produce "ftrapeq",
+   because "label" became "pc@label".  */
+{"fseq",       two(0xF040, 0x0001),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsf",                two(0xF040, 0x0000),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsge",       two(0xF040, 0x0013),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsgl",       two(0xF040, 0x0016),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsgle",      two(0xF040, 0x0017),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsgt",       two(0xF040, 0x0012),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsle",       two(0xF040, 0x0015),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fslt",       two(0xF040, 0x0014),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsne",       two(0xF040, 0x000E),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsnge",      two(0xF040, 0x001C),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsngl",      two(0xF040, 0x0019),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsngle",     two(0xF040, 0x0018),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsngt",      two(0xF040, 0x001D),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsnle",      two(0xF040, 0x001A),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsnlt",      two(0xF040, 0x001B),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsoge",      two(0xF040, 0x0003),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsogl",      two(0xF040, 0x0006),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsogt",      two(0xF040, 0x0002),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsole",      two(0xF040, 0x0005),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsolt",      two(0xF040, 0x0004),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsor",       two(0xF040, 0x0007),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsseq",      two(0xF040, 0x0011),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fssf",       two(0xF040, 0x0010),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fssne",      two(0xF040, 0x001E),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsst",       two(0xF040, 0x001F),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fst",                two(0xF040, 0x000F),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsueq",      two(0xF040, 0x0009),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsuge",      two(0xF040, 0x000B),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsugt",      two(0xF040, 0x000A),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsule",      two(0xF040, 0x000D),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsult",      two(0xF040, 0x000C),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+{"fsun",       two(0xF040, 0x0008),    two(0xF1C0, 0xFFFF),    "Ii$s"},
+
+{"fsgldivb",   two(0xF000, 0x5824),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsgldivd",   two(0xF000, 0x5424),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsgldivl",   two(0xF000, 0x4024),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsgldivp",   two(0xF000, 0x4C24),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsgldivs",   two(0xF000, 0x4424),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsgldivw",   two(0xF000, 0x5024),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsgldivx",   two(0xF000, 0x0024),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsgldivx",   two(0xF000, 0x4824),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsgldivx",   two(0xF000, 0x0024),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fsglmulb",   two(0xF000, 0x5827),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsglmuld",   two(0xF000, 0x5427),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsglmull",   two(0xF000, 0x4027),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsglmulp",   two(0xF000, 0x4C27),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsglmuls",   two(0xF000, 0x4427),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsglmulw",   two(0xF000, 0x5027),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsglmulx",   two(0xF000, 0x0027),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsglmulx",   two(0xF000, 0x4827),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsglmulx",   two(0xF000, 0x0027),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fsinb",      two(0xF000, 0x580E),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsind",      two(0xF000, 0x540E),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsinl",      two(0xF000, 0x400E),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsinp",      two(0xF000, 0x4C0E),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsins",      two(0xF000, 0x440E),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsinw",      two(0xF000, 0x500E),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsinx",      two(0xF000, 0x000E),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsinx",      two(0xF000, 0x480E),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsinx",      two(0xF000, 0x000E),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fsinhb",     two(0xF000, 0x5802),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsinhd",     two(0xF000, 0x5402),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsinhl",     two(0xF000, 0x4002),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsinhp",     two(0xF000, 0x4C02),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsinhs",     two(0xF000, 0x4402),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsinhw",     two(0xF000, 0x5002),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsinhx",     two(0xF000, 0x0002),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsinhx",     two(0xF000, 0x4802),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsinhx",     two(0xF000, 0x0002),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fsqrtb",     two(0xF000, 0x5804),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsqrtd",     two(0xF000, 0x5404),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsqrtl",     two(0xF000, 0x4004),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsqrtp",     two(0xF000, 0x4C04),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsqrts",     two(0xF000, 0x4404),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsqrtw",     two(0xF000, 0x5004),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsqrtx",     two(0xF000, 0x0004),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsqrtx",     two(0xF000, 0x4804),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsqrtx",     two(0xF000, 0x0004),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"fsubb",      two(0xF000, 0x5828),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"fsubd",      two(0xF000, 0x5428),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"fsubl",      two(0xF000, 0x4028),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"fsubp",      two(0xF000, 0x4C28),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"fsubs",      two(0xF000, 0x4428),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"fsubw",      two(0xF000, 0x5028),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"fsubx",      two(0xF000, 0x0028),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"fsubx",      two(0xF000, 0x4828),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"fsubx",      two(0xF000, 0x0028),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"ftanb",      two(0xF000, 0x580F),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"ftand",      two(0xF000, 0x540F),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"ftanl",      two(0xF000, 0x400F),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"ftanp",      two(0xF000, 0x4C0F),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"ftans",      two(0xF000, 0x440F),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"ftanw",      two(0xF000, 0x500F),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"ftanx",      two(0xF000, 0x000F),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"ftanx",      two(0xF000, 0x480F),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"ftanx",      two(0xF000, 0x000F),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"ftanhb",     two(0xF000, 0x5809),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"ftanhd",     two(0xF000, 0x5409),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"ftanhl",     two(0xF000, 0x4009),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"ftanhp",     two(0xF000, 0x4C09),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"ftanhs",     two(0xF000, 0x4409),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"ftanhw",     two(0xF000, 0x5009),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"ftanhx",     two(0xF000, 0x0009),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"ftanhx",     two(0xF000, 0x4809),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"ftanhx",     two(0xF000, 0x0009),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"ftentoxb",   two(0xF000, 0x5812),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"ftentoxd",   two(0xF000, 0x5412),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"ftentoxl",   two(0xF000, 0x4012),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"ftentoxp",   two(0xF000, 0x4C12),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"ftentoxs",   two(0xF000, 0x4412),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"ftentoxw",   two(0xF000, 0x5012),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"ftentoxx",   two(0xF000, 0x0012),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"ftentoxx",   two(0xF000, 0x4812),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"ftentoxx",   two(0xF000, 0x0012),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+{"ftrapeq",    two(0xF07C, 0x0001),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapf",     two(0xF07C, 0x0000),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapge",    two(0xF07C, 0x0013),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapgl",    two(0xF07C, 0x0016),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapgle",   two(0xF07C, 0x0017),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapgt",    two(0xF07C, 0x0012),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftraple",    two(0xF07C, 0x0015),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftraplt",    two(0xF07C, 0x0014),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapne",    two(0xF07C, 0x000E),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapnge",   two(0xF07C, 0x001C),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapngl",   two(0xF07C, 0x0019),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapngle",  two(0xF07C, 0x0018),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapngt",   two(0xF07C, 0x001D),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapnle",   two(0xF07C, 0x001A),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapnlt",   two(0xF07C, 0x001B),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapoge",   two(0xF07C, 0x0003),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapogl",   two(0xF07C, 0x0006),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapogt",   two(0xF07C, 0x0002),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapole",   two(0xF07C, 0x0005),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapolt",   two(0xF07C, 0x0004),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapor",    two(0xF07C, 0x0007),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapseq",   two(0xF07C, 0x0011),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapsf",    two(0xF07C, 0x0010),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapsne",   two(0xF07C, 0x001E),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapst",    two(0xF07C, 0x001F),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapt",     two(0xF07C, 0x000F),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapueq",   two(0xF07C, 0x0009),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapuge",   two(0xF07C, 0x000B),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapugt",   two(0xF07C, 0x000A),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapule",   two(0xF07C, 0x000D),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapult",   two(0xF07C, 0x000C),    two(0xF1FF, 0xFFFF),    "Ii"},
+{"ftrapun",    two(0xF07C, 0x0008),    two(0xF1FF, 0xFFFF),    "Ii"},
+        
+{"ftrapeqw",   two(0xF07A, 0x0001),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapfw",    two(0xF07A, 0x0000),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapgew",   two(0xF07A, 0x0013),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapglw",   two(0xF07A, 0x0016),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapglew",  two(0xF07A, 0x0017),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapgtw",   two(0xF07A, 0x0012),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftraplew",   two(0xF07A, 0x0015),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapltw",   two(0xF07A, 0x0014),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapnew",   two(0xF07A, 0x000E),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapngew",  two(0xF07A, 0x001C),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapnglw",  two(0xF07A, 0x0019),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapnglew", two(0xF07A, 0x0018),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapngtw",  two(0xF07A, 0x001D),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapnlew",  two(0xF07A, 0x001A),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapnltw",  two(0xF07A, 0x001B),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapogew",  two(0xF07A, 0x0003),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapoglw",  two(0xF07A, 0x0006),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapogtw",  two(0xF07A, 0x0002),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapolew",  two(0xF07A, 0x0005),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapoltw",  two(0xF07A, 0x0004),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftraporw",   two(0xF07A, 0x0007),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapseqw",  two(0xF07A, 0x0011),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapsfw",   two(0xF07A, 0x0010),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapsnew",  two(0xF07A, 0x001E),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapstw",   two(0xF07A, 0x001F),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftraptw",    two(0xF07A, 0x000F),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapueqw",  two(0xF07A, 0x0009),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapugew",  two(0xF07A, 0x000B),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapugtw",  two(0xF07A, 0x000A),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapulew",  two(0xF07A, 0x000D),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapultw",  two(0xF07A, 0x000C),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+{"ftrapunw",   two(0xF07A, 0x0008),    two(0xF1FF, 0xFFFF),    "Ii^w"},
+
+{"ftrapeql",   two(0xF07B, 0x0001),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapfl",    two(0xF07B, 0x0000),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapgel",   two(0xF07B, 0x0013),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapgll",   two(0xF07B, 0x0016),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapglel",  two(0xF07B, 0x0017),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapgtl",   two(0xF07B, 0x0012),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftraplel",   two(0xF07B, 0x0015),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapltl",   two(0xF07B, 0x0014),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapnel",   two(0xF07B, 0x000E),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapngel",  two(0xF07B, 0x001C),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapngll",  two(0xF07B, 0x0019),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapnglel", two(0xF07B, 0x0018),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapngtl",  two(0xF07B, 0x001D),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapnlel",  two(0xF07B, 0x001A),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapnltl",  two(0xF07B, 0x001B),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapogel",  two(0xF07B, 0x0003),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapogll",  two(0xF07B, 0x0006),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapogtl",  two(0xF07B, 0x0002),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapolel",  two(0xF07B, 0x0005),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapoltl",  two(0xF07B, 0x0004),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftraporl",   two(0xF07B, 0x0007),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapseql",  two(0xF07B, 0x0011),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapsfl",   two(0xF07B, 0x0010),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapsnel",  two(0xF07B, 0x001E),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapstl",   two(0xF07B, 0x001F),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftraptl",    two(0xF07B, 0x000F),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapueql",  two(0xF07B, 0x0009),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapugel",  two(0xF07B, 0x000B),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapugtl",  two(0xF07B, 0x000A),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapulel",  two(0xF07B, 0x000D),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapultl",  two(0xF07B, 0x000C),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+{"ftrapunl",   two(0xF07B, 0x0008),    two(0xF1FF, 0xFFFF),    "Ii^l"},
+
+{"ftstb",      two(0xF000, 0x583A),    two(0xF1C0, 0xFC7F),    "Ii;b"},
+{"ftstd",      two(0xF000, 0x543A),    two(0xF1C0, 0xFC7F),    "Ii;F"},
+{"ftstl",      two(0xF000, 0x403A),    two(0xF1C0, 0xFC7F),    "Ii;l"},
+{"ftstp",      two(0xF000, 0x4C3A),    two(0xF1C0, 0xFC7F),    "Ii;p"},
+{"ftsts",      two(0xF000, 0x443A),    two(0xF1C0, 0xFC7F),    "Ii;f"},
+{"ftstw",      two(0xF000, 0x503A),    two(0xF1C0, 0xFC7F),    "Ii;w"},
+{"ftstx",      two(0xF000, 0x003A),    two(0xF1C0, 0xE07F),    "IiF8"},
+{"ftstx",      two(0xF000, 0x483A),    two(0xF1C0, 0xFC7F),    "Ii;x"},
+
+{"ftwotoxb",   two(0xF000, 0x5811),    two(0xF1C0, 0xFC7F),    "Ii;bF7"},
+{"ftwotoxd",   two(0xF000, 0x5411),    two(0xF1C0, 0xFC7F),    "Ii;FF7"},
+{"ftwotoxl",   two(0xF000, 0x4011),    two(0xF1C0, 0xFC7F),    "Ii;lF7"},
+{"ftwotoxp",   two(0xF000, 0x4C11),    two(0xF1C0, 0xFC7F),    "Ii;pF7"},
+{"ftwotoxs",   two(0xF000, 0x4411),    two(0xF1C0, 0xFC7F),    "Ii;fF7"},
+{"ftwotoxw",   two(0xF000, 0x5011),    two(0xF1C0, 0xFC7F),    "Ii;wF7"},
+{"ftwotoxx",   two(0xF000, 0x0011),    two(0xF1C0, 0xE07F),    "IiF8F7"},
+{"ftwotoxx",   two(0xF000, 0x4811),    two(0xF1C0, 0xFC7F),    "Ii;xF7"},
+{"ftwotoxx",   two(0xF000, 0x0011),    two(0xF1C0, 0xE07F),    "IiFt"},
+
+
+{"fjeq",       one(0xF081),            one(0xF1FF),            "IdBc"},
+{"fjf",                one(0xF080),            one(0xF1FF),            "IdBc"},
+{"fjge",       one(0xF093),            one(0xF1FF),            "IdBc"},
+{"fjgl",       one(0xF096),            one(0xF1FF),            "IdBc"},
+{"fjgle",      one(0xF097),            one(0xF1FF),            "IdBc"},
+{"fjgt",       one(0xF092),            one(0xF1FF),            "IdBc"},
+{"fjle",       one(0xF095),            one(0xF1FF),            "IdBc"},
+{"fjlt",       one(0xF094),            one(0xF1FF),            "IdBc"},
+{"fjne",       one(0xF08E),            one(0xF1FF),            "IdBc"},
+{"fjnge",      one(0xF09C),            one(0xF1FF),            "IdBc"},
+{"fjngl",      one(0xF099),            one(0xF1FF),            "IdBc"},
+{"fjngle",     one(0xF098),            one(0xF1FF),            "IdBc"},
+{"fjngt",      one(0xF09D),            one(0xF1FF),            "IdBc"},
+{"fjnle",      one(0xF09A),            one(0xF1FF),            "IdBc"},
+{"fjnlt",      one(0xF09B),            one(0xF1FF),            "IdBc"},
+{"fjoge",      one(0xF083),            one(0xF1FF),            "IdBc"},
+{"fjogl",      one(0xF086),            one(0xF1FF),            "IdBc"},
+{"fjogt",      one(0xF082),            one(0xF1FF),            "IdBc"},
+{"fjole",      one(0xF085),            one(0xF1FF),            "IdBc"},
+{"fjolt",      one(0xF084),            one(0xF1FF),            "IdBc"},
+{"fjor",       one(0xF087),            one(0xF1FF),            "IdBc"},
+{"fjseq",      one(0xF091),            one(0xF1FF),            "IdBc"},
+{"fjsf",       one(0xF090),            one(0xF1FF),            "IdBc"},
+{"fjsne",      one(0xF09E),            one(0xF1FF),            "IdBc"},
+{"fjst",       one(0xF09F),            one(0xF1FF),            "IdBc"},
+{"fjt",                one(0xF08F),            one(0xF1FF),            "IdBc"},
+{"fjueq",      one(0xF089),            one(0xF1FF),            "IdBc"},
+{"fjuge",      one(0xF08B),            one(0xF1FF),            "IdBc"},
+{"fjugt",      one(0xF08A),            one(0xF1FF),            "IdBc"},
+{"fjule",      one(0xF08D),            one(0xF1FF),            "IdBc"},
+{"fjult",      one(0xF08C),            one(0xF1FF),            "IdBc"},
+{"fjun",       one(0xF088),            one(0xF1FF),            "IdBc"},
+
+/* The assembler will ignore attempts to force a short offset */
+
+{"bhis",       one(0061000),           one(0177400),           "Bg"},
+{"blss",       one(0061400),           one(0177400),           "Bg"},
+{"bccs",       one(0062000),           one(0177400),           "Bg"},
+{"bcss",       one(0062400),           one(0177400),           "Bg"},
+{"bnes",       one(0063000),           one(0177400),           "Bg"},
+{"beqs",       one(0063400),           one(0177400),           "Bg"},
+{"bvcs",       one(0064000),           one(0177400),           "Bg"},
+{"bvss",       one(0064400),           one(0177400),           "Bg"},
+{"bpls",       one(0065000),           one(0177400),           "Bg"},
+{"bmis",       one(0065400),           one(0177400),           "Bg"},
+{"bges",       one(0066000),           one(0177400),           "Bg"},
+{"blts",       one(0066400),           one(0177400),           "Bg"},
+{"bgts",       one(0067000),           one(0177400),           "Bg"},
+{"bles",       one(0067400),           one(0177400),           "Bg"},
+
+/* Alternate mnemonics for SUN */
+
+{"jbsr",       one(0060400),           one(0177400),           "Bg"},
+{"jbsr",       one(0047200),           one(0177700),           "!s"},
+{"jra",                one(0060000),           one(0177400),           "Bg"},
+{"jra",                one(0047300),           one(0177700),           "!s"},
+  
+{"jhi",                one(0061000),           one(0177400),           "Bg"},
+{"jls",                one(0061400),           one(0177400),           "Bg"},
+{"jcc",                one(0062000),           one(0177400),           "Bg"},
+{"jcs",                one(0062400),           one(0177400),           "Bg"},
+{"jne",                one(0063000),           one(0177400),           "Bg"},
+{"jeq",                one(0063400),           one(0177400),           "Bg"},
+{"jvc",                one(0064000),           one(0177400),           "Bg"},
+{"jvs",                one(0064400),           one(0177400),           "Bg"},
+{"jpl",                one(0065000),           one(0177400),           "Bg"},
+{"jmi",                one(0065400),           one(0177400),           "Bg"},
+{"jge",                one(0066000),           one(0177400),           "Bg"},
+{"jlt",                one(0066400),           one(0177400),           "Bg"},
+{"jgt",                one(0067000),           one(0177400),           "Bg"},
+{"jle",                one(0067400),           one(0177400),           "Bg"},
+
+/* Short offsets are ignored */
+
+{"jbsrs",      one(0060400),           one(0177400),           "Bg"},
+{"jras",       one(0060000),           one(0177400),           "Bg"},
+{"jhis",       one(0061000),           one(0177400),           "Bg"},
+{"jlss",       one(0061400),           one(0177400),           "Bg"},
+{"jccs",       one(0062000),           one(0177400),           "Bg"},
+{"jcss",       one(0062400),           one(0177400),           "Bg"},
+{"jnes",       one(0063000),           one(0177400),           "Bg"},
+{"jeqs",       one(0063400),           one(0177400),           "Bg"},
+{"jvcs",       one(0064000),           one(0177400),           "Bg"},
+{"jvss",       one(0064400),           one(0177400),           "Bg"},
+{"jpls",       one(0065000),           one(0177400),           "Bg"},
+{"jmis",       one(0065400),           one(0177400),           "Bg"},
+{"jges",       one(0066000),           one(0177400),           "Bg"},
+{"jlts",       one(0066400),           one(0177400),           "Bg"},
+{"jgts",       one(0067000),           one(0177400),           "Bg"},
+{"jles",       one(0067400),           one(0177400),           "Bg"},
+
+{"movql",      one(0070000),           one(0170400),           "MsDd"},
+{"moveql",     one(0070000),           one(0170400),           "MsDd"},
+{"moval",      one(0020100),           one(0170700),           "*lAd"},
+{"movaw",      one(0030100),           one(0170700),           "*wAd"},
+{"movb",       one(0010000),           one(0170000),           ";b$d"},        /* mov */
+{"movl",       one(0070000),           one(0170400),           "MsDd"},        /* movq written as mov */
+{"movl",       one(0020000),           one(0170000),           "*l$d"},
+{"movl",       one(0020100),           one(0170700),           "*lAd"},
+{"movl",       one(0047140),           one(0177770),           "AsUd"},        /* mov to USP */
+{"movl",       one(0047150),           one(0177770),           "UdAs"},        /* mov from USP */
+{"movc",       one(0047173),           one(0177777),           "R1Jj"},
+{"movc",       one(0047173),           one(0177777),           "R1#j"},
+{"movc",       one(0047172),           one(0177777),           "JjR1"},
+{"movc",       one(0047172),           one(0177777),           "#jR1"},
+{"movml",      one(0044300),           one(0177700),           "#w&s"},        /* movm reg to mem. */
+{"movml",      one(0044340),           one(0177770),           "#w-s"},        /* movm reg to autodecrement. */
+{"movml",      one(0046300),           one(0177700),           "!s#w"},        /* movm mem to reg. */
+{"movml",      one(0046330),           one(0177770),           "+s#w"},        /* movm autoinc to reg. */
+{"movml",      one(0044300),           one(0177700),           "Lw&s"},        /* movm reg to mem. */
+{"movml",      one(0044340),           one(0177770),           "lw-s"},        /* movm reg to autodecrement. */
+{"movml",      one(0046300),           one(0177700),           "!sLw"},        /* movm mem to reg. */
+{"movml",      one(0046330),           one(0177770),           "+sLw"},        /* movm autoinc to reg. */
+{"movmw",      one(0044200),           one(0177700),           "#w&s"},        /* movm reg to mem. */
+{"movmw",      one(0044240),           one(0177770),           "#w-s"},        /* movm reg to autodecrement. */
+{"movmw",      one(0046200),           one(0177700),           "!s#w"},        /* movm mem to reg. */
+{"movmw",      one(0046230),           one(0177770),           "+s#w"},        /* movm autoinc to reg. */
+{"movmw",      one(0044200),           one(0177700),           "Lw&s"},        /* movm reg to mem. */
+{"movmw",      one(0044240),           one(0177770),           "lw-s"},        /* movm reg to autodecrement. */
+{"movmw",      one(0046200),           one(0177700),           "!sLw"},        /* movm mem to reg. */
+{"movmw",      one(0046230),           one(0177770),           "+sLw"},        /* movm autoinc to reg. */
+{"movpl",      one(0000510),           one(0170770),           "dsDd"},        /* memory to register */
+{"movpl",      one(0000710),           one(0170770),           "Ddds"},        /* register to memory */
+{"movpw",      one(0000410),           one(0170770),           "dsDd"},        /* memory to register */
+{"movpw",      one(0000610),           one(0170770),           "Ddds"},        /* register to memory */
+{"movq",       one(0070000),           one(0170400),           "MsDd"},
+{"movw",       one(0030000),           one(0170000),           "*w$d"},
+{"movw",       one(0030100),           one(0170700),           "*wAd"},        /* mova,        written as mov */
+{"movw",       one(0040300),           one(0177700),           "Ss$s"},        /* Move from sr */
+{"movw",       one(0041300),           one(0177700),           "Cs$s"},        /* Move from ccr */
+{"movw",       one(0042300),           one(0177700),           ";wCd"},        /* mov to ccr */
+{"movw",       one(0043300),           one(0177700),           ";wSd"},        /* mov to sr */
+
+{"movsb",      two(0007000, 0),        two(0177700, 07777),    "~sR1"},
+{"movsb",      two(0007000, 04000),    two(0177700, 07777),    "R1~s"},
+{"movsl",      two(0007200, 0),        two(0177700, 07777),    "~sR1"},
+{"movsl",      two(0007200, 04000),    two(0177700, 07777),    "R1~s"},
+{"movsw",      two(0007100, 0),        two(0177700, 07777),    "~sR1"},
+{"movsw",      two(0007100, 04000),    two(0177700, 07777),    "R1~s"},
+
+#ifdef m68851
+ /* name */    /* opcode */            /* match */             /* args */
+
+{"pbac",       one(0xf0c7),            one(0xffbf),            "Bc"},
+{"pbacw",      one(0xf087),            one(0xffbf),            "Bc"},
+{"pbas",       one(0xf0c6),            one(0xffbf),            "Bc"},
+{"pbasw",      one(0xf086),            one(0xffbf),            "Bc"},
+{"pbbc",       one(0xf0c1),            one(0xffbf),            "Bc"},
+{"pbbcw",      one(0xf081),            one(0xffbf),            "Bc"},
+{"pbbs",       one(0xf0c0),            one(0xffbf),            "Bc"},
+{"pbbsw",      one(0xf080),            one(0xffbf),            "Bc"},
+{"pbcc",       one(0xf0cf),            one(0xffbf),            "Bc"},
+{"pbccw",      one(0xf08f),            one(0xffbf),            "Bc"},
+{"pbcs",       one(0xf0ce),            one(0xffbf),            "Bc"},
+{"pbcsw",      one(0xf08e),            one(0xffbf),            "Bc"},
+{"pbgc",       one(0xf0cd),            one(0xffbf),            "Bc"},
+{"pbgcw",      one(0xf08d),            one(0xffbf),            "Bc"},
+{"pbgs",       one(0xf0cc),            one(0xffbf),            "Bc"},
+{"pbgsw",      one(0xf08c),            one(0xffbf),            "Bc"},
+{"pbic",       one(0xf0cb),            one(0xffbf),            "Bc"},
+{"pbicw",      one(0xf08b),            one(0xffbf),            "Bc"},
+{"pbis",       one(0xf0ca),            one(0xffbf),            "Bc"},
+{"pbisw",      one(0xf08a),            one(0xffbf),            "Bc"},
+{"pblc",       one(0xf0c3),            one(0xffbf),            "Bc"},
+{"pblcw",      one(0xf083),            one(0xffbf),            "Bc"},
+{"pbls",       one(0xf0c2),            one(0xffbf),            "Bc"},
+{"pblsw",      one(0xf082),            one(0xffbf),            "Bc"},
+{"pbsc",       one(0xf0c5),            one(0xffbf),            "Bc"},
+{"pbscw",      one(0xf085),            one(0xffbf),            "Bc"},
+{"pbss",       one(0xf0c4),            one(0xffbf),            "Bc"},
+{"pbssw",      one(0xf084),            one(0xffbf),            "Bc"},
+{"pbwc",       one(0xf0c9),            one(0xffbf),            "Bc"},
+{"pbwcw",      one(0xf089),            one(0xffbf),            "Bc"},
+{"pbws",       one(0xf0c8),            one(0xffbf),            "Bc"},
+{"pbwsw",      one(0xf088),            one(0xffbf),            "Bc"},
+
+
+{"pdbac",      two(0xf048, 0x0007),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbas",      two(0xf048, 0x0006),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbbc",      two(0xf048, 0x0001),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbbs",      two(0xf048, 0x0000),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbcc",      two(0xf048, 0x000f),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbcs",      two(0xf048, 0x000e),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbgc",      two(0xf048, 0x000d),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbgs",      two(0xf048, 0x000c),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbic",      two(0xf048, 0x000b),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbis",      two(0xf048, 0x000a),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdblc",      two(0xf048, 0x0003),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbls",      two(0xf048, 0x0002),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbsc",      two(0xf048, 0x0005),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbss",      two(0xf048, 0x0004),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbwc",      two(0xf048, 0x0009),    two(0xfff8, 0xffff),    "DsBw"},
+{"pdbws",      two(0xf048, 0x0008),    two(0xfff8, 0xffff),    "DsBw"},
+
+{"pflusha",    two(0xf000, 0x2400),    two(0xffff, 0xffff),    "" },
+
+{"pflush",     two(0xf000, 0x3010),    two(0xffc0, 0xfe10),    "T3T9" },
+{"pflush",     two(0xf000, 0x3810),    two(0xffc0, 0xfe10),    "T3T9&s" },
+{"pflush",     two(0xf000, 0x3008),    two(0xffc0, 0xfe18),    "D3T9" },
+{"pflush",     two(0xf000, 0x3808),    two(0xffc0, 0xfe18),    "D3T9&s" },
+{"pflush",     two(0xf000, 0x3000),    two(0xffc0, 0xfe1e),    "f3T9" },
+{"pflush",     two(0xf000, 0x3800),    two(0xffc0, 0xfe1e),    "f3T9&s" },
+
+{"pflushs",    two(0xf000, 0x3410),    two(0xfff8, 0xfe10),    "T3T9" },
+{"pflushs",    two(0xf000, 0x3c00),    two(0xfff8, 0xfe00),    "T3T9&s" },
+{"pflushs",    two(0xf000, 0x3408),    two(0xfff8, 0xfe18),    "D3T9" },
+{"pflushs",    two(0xf000, 0x3c08),    two(0xfff8, 0xfe18),    "D3T9&s" },
+{"pflushs",    two(0xf000, 0x3400),    two(0xfff8, 0xfe1e),    "f3T9" },
+{"pflushs",    two(0xf000, 0x3c00),    two(0xfff8, 0xfe1e),    "f3T9&s"},
+
+{"pflushr",    two(0xf000, 0xa000),    two(0xffc0, 0xffff),    "|s" },
+
+{"ploadr",     two(0xf000, 0x2210),    two(0xffc0, 0xfff0),    "T3&s" },
+{"ploadr",     two(0xf000, 0x2208),    two(0xffc0, 0xfff8),    "D3&s" },
+{"ploadr",     two(0xf000, 0x2200),    two(0xffc0, 0xfffe),    "f3&s" },
+{"ploadw",     two(0xf000, 0x2010),    two(0xffc0, 0xfff0),    "T3&s" },
+{"ploadw",     two(0xf000, 0x2008),    two(0xffc0, 0xfff8),    "D3&s" },
+{"ploadw",     two(0xf000, 0x2000),    two(0xffc0, 0xfffe),    "f3&s" },
+
+/* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */
+{"pmove",      two(0xf000, 0x4000),    two(0xffc0, 0xe3ff),    "*sP8" },
+{"pmove",      two(0xf000, 0x4200),    two(0xffc0, 0xe3ff),    "P8%s" },
+{"pmove",      two(0xf000, 0x4000),    two(0xffc0, 0xe3ff),    "|sW8" },
+{"pmove",      two(0xf000, 0x4200),    two(0xffc0, 0xe3ff),    "W8~s" },
+
+/* BADx, BACx */
+{"pmove",      two(0xf000, 0x6200),    two(0xffc0, 0xe3e3),    "*sX3" },
+{"pmove",      two(0xf000, 0x6000),    two(0xffc0, 0xe3e3),    "X3%s" },
+
+/* PSR, PCSR */
+/* {"pmove",   two(0xf000, 0x6100),    two(oxffc0, oxffff),    "*sZ8" }, */
+{"pmove",      two(0xf000, 0x6000),    two(0xffc0, 0xffff),    "*sY8" },
+{"pmove",      two(0xf000, 0x6200),    two(0xffc0, 0xffff),    "Y8%s" },
+{"pmove",      two(0xf000, 0x6600),    two(0xffc0, 0xffff),    "Z8%s" },
+
+{"prestore",   one(0xf140),            one(0xffc0),            "&s"},
+{"prestore",   one(0xf158),            one(0xfff8),            "+s"},
+{"psave",      one(0xf100),            one(0xffc0),            "&s"},
+{"psave",      one(0xf100),            one(0xffc0),            "+s"},
+
+{"psac",       two(0xf040, 0x0007),    two(0xffc0, 0xffff),    "@s"},
+{"psas",       two(0xf040, 0x0006),    two(0xffc0, 0xffff),    "@s"},
+{"psbc",       two(0xf040, 0x0001),    two(0xffc0, 0xffff),    "@s"},
+{"psbs",       two(0xf040, 0x0000),    two(0xffc0, 0xffff),    "@s"},
+{"pscc",       two(0xf040, 0x000f),    two(0xffc0, 0xffff),    "@s"},
+{"pscs",       two(0xf040, 0x000e),    two(0xffc0, 0xffff),    "@s"},
+{"psgc",       two(0xf040, 0x000d),    two(0xffc0, 0xffff),    "@s"},
+{"psgs",       two(0xf040, 0x000c),    two(0xffc0, 0xffff),    "@s"},
+{"psic",       two(0xf040, 0x000b),    two(0xffc0, 0xffff),    "@s"},
+{"psis",       two(0xf040, 0x000a),    two(0xffc0, 0xffff),    "@s"},
+{"pslc",       two(0xf040, 0x0003),    two(0xffc0, 0xffff),    "@s"},
+{"psls",       two(0xf040, 0x0002),    two(0xffc0, 0xffff),    "@s"},
+{"pssc",       two(0xf040, 0x0005),    two(0xffc0, 0xffff),    "@s"},
+{"psss",       two(0xf040, 0x0004),    two(0xffc0, 0xffff),    "@s"},
+{"pswc",       two(0xf040, 0x0009),    two(0xffc0, 0xffff),    "@s"},
+{"psws",       two(0xf040, 0x0008),    two(0xffc0, 0xffff),    "@s"},
+
+{"ptestr",     two(0xf000, 0x8210),    two(0xffc0, 0xe3f0),    "T3&sQ8" },
+{"ptestr",     two(0xf000, 0x8310),    two(0xffc0, 0xe310),    "T3&sQ8A9" },
+{"ptestr",     two(0xf000, 0x8208),    two(0xffc0, 0xe3f8),    "D3&sQ8" },
+{"ptestr",     two(0xf000, 0x8308),    two(0xffc0, 0xe318),    "D3&sQ8A9" },
+{"ptestr",     two(0xf000, 0x8200),    two(0xffc0, 0xe3fe),    "f3&sQ8" },
+{"ptestr",     two(0xf000, 0x8300),    two(0xffc0, 0xe31e),    "f3&sQ8A9" },
+
+{"ptestw",     two(0xf000, 0x8010),    two(0xffc0, 0xe3f0),    "T3&sQ8" },
+{"ptestw",     two(0xf000, 0x8110),    two(0xffc0, 0xe310),    "T3&sQ8A9" },
+{"ptestw",     two(0xf000, 0x8008),    two(0xffc0, 0xe3f8),    "D3&sQ8" },
+{"ptestw",     two(0xf000, 0x8108),    two(0xffc0, 0xe318),    "D3&sQ8A9" },
+{"ptestw",     two(0xf000, 0x8000),    two(0xffc0, 0xe3fe),    "f3&sQ8" },
+{"ptestw",     two(0xf000, 0x8100),    two(0xffc0, 0xe31e),    "f3&sQ8A9" },
+
+{"ptrapacw",   two(0xf07a, 0x0007),    two(0xffff, 0xffff),    "#w"},
+{"ptrapacl",   two(0xf07b, 0x0007),    two(0xffff, 0xffff),    "#l"},
+{"ptrapac",    two(0xf07c, 0x0007),    two(0xffff, 0xffff),    ""},
+
+{"ptrapasw",   two(0xf07a, 0x0006),    two(0xffff, 0xffff),    "#w"},
+{"ptrapasl",   two(0xf07b, 0x0006),    two(0xffff, 0xffff),    "#l"},
+{"ptrapas",    two(0xf07c, 0x0006),    two(0xffff, 0xffff),    ""},
+
+{"ptrapbcw",   two(0xf07a, 0x0001),    two(0xffff, 0xffff),    "#w"},
+{"ptrapbcl",   two(0xf07b, 0x0001),    two(0xffff, 0xffff),    "#l"},
+{"ptrapbc",    two(0xf07c, 0x0001),    two(0xffff, 0xffff),    ""},
+
+{"ptrapbsw",   two(0xf07a, 0x0000),    two(0xffff, 0xffff),    "#w"},
+{"ptrapbsl",   two(0xf07b, 0x0000),    two(0xffff, 0xffff),    "#l"},
+{"ptrapbs",    two(0xf07c, 0x0000),    two(0xffff, 0xffff),    ""},
+
+{"ptrapccw",   two(0xf07a, 0x000f),    two(0xffff, 0xffff),    "#w"},
+{"ptrapccl",   two(0xf07b, 0x000f),    two(0xffff, 0xffff),    "#l"},
+{"ptrapcc",    two(0xf07c, 0x000f),    two(0xffff, 0xffff),    ""},
+
+{"ptrapcsw",   two(0xf07a, 0x000e),    two(0xffff, 0xffff),    "#w"},
+{"ptrapcsl",   two(0xf07b, 0x000e),    two(0xffff, 0xffff),    "#l"},
+{"ptrapcs",    two(0xf07c, 0x000e),    two(0xffff, 0xffff),    ""},
+
+{"ptrapgcw",   two(0xf07a, 0x000d),    two(0xffff, 0xffff),    "#w"},
+{"ptrapgcl",   two(0xf07b, 0x000d),    two(0xffff, 0xffff),    "#l"},
+{"ptrapgc",    two(0xf07c, 0x000d),    two(0xffff, 0xffff),    ""},
+
+{"ptrapgsw",   two(0xf07a, 0x000c),    two(0xffff, 0xffff),    "#w"},
+{"ptrapgsl",   two(0xf07b, 0x000c),    two(0xffff, 0xffff),    "#l"},
+{"ptrapgs",    two(0xf07c, 0x000c),    two(0xffff, 0xffff),    ""},
+
+{"ptrapicw",   two(0xf07a, 0x000b),    two(0xffff, 0xffff),    "#w"},
+{"ptrapicl",   two(0xf07b, 0x000b),    two(0xffff, 0xffff),    "#l"},
+{"ptrapic",    two(0xf07c, 0x000b),    two(0xffff, 0xffff),    ""},
+
+{"ptrapisw",   two(0xf07a, 0x000a),    two(0xffff, 0xffff),    "#w"},
+{"ptrapisl",   two(0xf07b, 0x000a),    two(0xffff, 0xffff),    "#l"},
+{"ptrapis",    two(0xf07c, 0x000a),    two(0xffff, 0xffff),    ""},
+
+{"ptraplcw",   two(0xf07a, 0x0003),    two(0xffff, 0xffff),    "#w"},
+{"ptraplcl",   two(0xf07b, 0x0003),    two(0xffff, 0xffff),    "#l"},
+{"ptraplc",    two(0xf07c, 0x0003),    two(0xffff, 0xffff),    ""},
+
+{"ptraplsw",   two(0xf07a, 0x0002),    two(0xffff, 0xffff),    "#w"},
+{"ptraplsl",   two(0xf07b, 0x0002),    two(0xffff, 0xffff),    "#l"},
+{"ptrapls",    two(0xf07c, 0x0002),    two(0xffff, 0xffff),    ""},
+
+{"ptrapscw",   two(0xf07a, 0x0005),    two(0xffff, 0xffff),    "#w"},
+{"ptrapscl",   two(0xf07b, 0x0005),    two(0xffff, 0xffff),    "#l"},
+{"ptrapsc",    two(0xf07c, 0x0005),    two(0xffff, 0xffff),    ""},
+
+{"ptrapssw",   two(0xf07a, 0x0004),    two(0xffff, 0xffff),    "#w"},
+{"ptrapssl",   two(0xf07b, 0x0004),    two(0xffff, 0xffff),    "#l"},
+{"ptrapss",    two(0xf07c, 0x0004),    two(0xffff, 0xffff),    ""},
+
+{"ptrapwcw",   two(0xf07a, 0x0009),    two(0xffff, 0xffff),    "#w"},
+{"ptrapwcl",   two(0xf07b, 0x0009),    two(0xffff, 0xffff),    "#l"},
+{"ptrapwc",    two(0xf07c, 0x0009),    two(0xffff, 0xffff),    ""},
+
+{"ptrapwsw",   two(0xf07a, 0x0008),    two(0xffff, 0xffff),    "#w"},
+{"ptrapwsl",   two(0xf07b, 0x0008),    two(0xffff, 0xffff),    "#l"},
+{"ptrapws",    two(0xf07c, 0x0008),    two(0xffff, 0xffff),    ""},
+
+{"pvalid",     two(0xf000, 0x2800),    two(0xffc0, 0xffff),    "Vs&s"},
+{"pvalid",     two(0xf000, 0x2c00),    two(0xffc0, 0xfff8),    "A3&s" },
+
+#endif /* m68851 */
+
+};
+
+int numopcodes=sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]);
+
+struct m68k_opcode *endop = m68k_opcodes+sizeof(m68k_opcodes)/sizeof(m68k_opcodes[0]);
diff --git a/gdb/m68k-pinsn.c b/gdb/m68k-pinsn.c
new file mode 100644 (file)
index 0000000..608bc25
--- /dev/null
@@ -0,0 +1,774 @@
+/* Print m68k instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "m68k-opcode.h"
+#include "gdbcore.h"
+
+/* 68k instructions are never longer than this many bytes.  */
+#define MAXLEN 22
+
+/* Number of elements in the opcode table.  */
+#define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0])
+
+extern char *reg_names[];
+char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
+                    "fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"};
+
+static unsigned char *print_insn_arg ();
+static unsigned char *print_indexed ();
+static void print_base ();
+static int fetch_arg ();
+
+#define NEXTBYTE(p)  (p += 2, ((char *)p)[-1])
+
+#define NEXTWORD(p)  \
+  (p += 2, ((((char *)p)[-2]) << 8) + p[-1])
+
+#define NEXTLONG(p)  \
+  (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
+
+#define NEXTSINGLE(p) \
+  (p += 4, *((float *)(p - 4)))
+
+#define NEXTDOUBLE(p) \
+  (p += 8, *((double *)(p - 8)))
+
+#define NEXTEXTEND(p) \
+  (p += 12, 0.0)       /* Need a function to convert from extended to double
+                          precision... */
+
+#define NEXTPACKED(p) \
+  (p += 12, 0.0)       /* Need a function to convert from packed to double
+                          precision.   Actually, it's easier to print a
+                          packed number than a double anyway, so maybe
+                          there should be a special case to handle this... */
+\f
+/* Print the m68k instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  register int i;
+  register unsigned char *p;
+  register char *d;
+  register int bestmask;
+  int best;
+
+  read_memory (memaddr, buffer, MAXLEN);
+
+  bestmask = 0;
+  best = -1;
+  for (i = 0; i < NOPCODES; i++)
+    {
+      register unsigned int opcode = m68k_opcodes[i].opcode;
+      register unsigned int match = m68k_opcodes[i].match;
+      if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
+         && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
+         && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
+         && ((0xff & buffer[3] & match) == (0xff & opcode)))
+       {
+         /* Don't use for printout the variants of divul and divsl
+            that have the same register number in two places.
+            The more general variants will match instead.  */
+         for (d = m68k_opcodes[i].args; *d; d += 2)
+           if (d[1] == 'D')
+             break;
+
+         /* Don't use for printout the variants of most floating
+            point coprocessor instructions which use the same
+            register number in two places, as above. */
+         if (*d == 0)
+           for (d = m68k_opcodes[i].args; *d; d += 2)
+             if (d[1] == 't')
+               break;
+
+         if (*d == 0 && match > bestmask)
+           {
+             best = i;
+             bestmask = match;
+           }
+       }
+    }
+
+  /* Handle undefined instructions.  */
+  if (best < 0)
+    {
+      fprintf_filtered (stream, "0%o", (buffer[0] << 8) + buffer[1]);
+      return 2;
+    }
+
+  fprintf_filtered (stream, "%s", m68k_opcodes[best].name);
+
+  /* Point at first word of argument data,
+     and at descriptor for first argument.  */
+  p = buffer + 2;
+  
+  /* Why do this this way? -MelloN */
+  for (d = m68k_opcodes[best].args; *d; d += 2)
+    {
+      if (d[0] == '#')
+       {
+         if (d[1] == 'l' && p - buffer < 6)
+           p = buffer + 6;
+         else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
+           p = buffer + 4;
+       }
+      if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)
+       p = buffer + 4;
+      if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)
+       p = buffer + 6;
+      if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
+       p = buffer + 4;
+    }
+
+  d = m68k_opcodes[best].args;
+
+  if (*d)
+    fputs_filtered (" ", stream);
+
+  while (*d)
+    {
+      p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream);
+      d += 2;
+      if (*d && *(d - 2) != 'I' && *d != 'k')
+       fputs_filtered (",", stream);
+    }
+  return p - buffer;
+}
+
+static unsigned char *
+print_insn_arg (d, buffer, p, addr, stream)
+     char *d;
+     unsigned char *buffer;
+     register unsigned char *p;
+     CORE_ADDR addr;           /* PC for this arg to be relative to */
+     FILE *stream;
+{
+  register int val;
+  register int place = d[1];
+  int regno;
+  register char *regname;
+  register unsigned char *p1;
+  register double flval;
+  int flt_p;
+
+  switch (*d)
+    {
+    case 'C':
+      fprintf_filtered (stream, "ccr");
+      break;
+
+    case 'S':
+      fprintf_filtered (stream, "sr");
+      break;
+
+    case 'U':
+      fprintf_filtered (stream, "usp");
+      break;
+
+    case 'J':
+      {
+       static struct { char *name; int value; } names[]
+         = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
+            {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
+            {"msp", 0x803}, {"isp", 0x804}};
+
+       val = fetch_arg (buffer, place, 12);
+       for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
+         if (names[regno].value == val)
+           {
+             fprintf_filtered (stream, names[regno].name);
+             break;
+           }
+       if (regno < 0)
+         fprintf_filtered (stream, "%d", val);
+      }
+      break;
+
+    case 'Q':
+      val = fetch_arg (buffer, place, 3);
+      /* 0 means 8, except for the bkpt instruction... */
+      if (val == 0 && d[1] != 's')
+       val = 8;
+      fprintf_filtered (stream, "#%d", val);
+      break;
+
+    case 'M':
+      val = fetch_arg (buffer, place, 8);
+      if (val & 0x80)
+       val = val - 0x100;
+      fprintf_filtered (stream, "#%d", val);
+      break;
+
+    case 'T':
+      val = fetch_arg (buffer, place, 4);
+      fprintf_filtered (stream, "#%d", val);
+      break;
+
+    case 'D':
+      fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);
+      break;
+
+    case 'A':
+      fprintf_filtered (stream, "%s",
+                       reg_names[fetch_arg (buffer, place, 3) + 010]);
+      break;
+
+    case 'R':
+      fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);
+      break;
+
+    case 'F':
+      fprintf_filtered (stream, "fp%d", fetch_arg (buffer, place, 3));
+      break;
+
+    case 'O':
+      val = fetch_arg (buffer, place, 6);
+      if (val & 0x20)
+       fprintf_filtered (stream, "%s", reg_names [val & 7]);
+      else
+       fprintf_filtered (stream, "%d", val);
+      break;
+
+    case '+':
+      fprintf_filtered (stream, "%s@+",
+                       reg_names[fetch_arg (buffer, place, 3) + 8]);
+      break;
+
+    case '-':
+      fprintf_filtered (stream, "%s@-",
+              reg_names[fetch_arg (buffer, place, 3) + 8]);
+      break;
+
+    case 'k':
+      if (place == 'k')
+       fprintf_filtered (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);
+      else if (place == 'C')
+       {
+         val = fetch_arg (buffer, place, 7);
+         if ( val > 63 )               /* This is a signed constant. */
+           val -= 128;
+         fprintf_filtered (stream, "{#%d}", val);
+       }
+      else
+       error ("Invalid arg format in opcode table: \"%c%c\".",
+              *d, place);
+      break;
+
+    case '#':
+    case '^':
+      p1 = buffer + (*d == '#' ? 2 : 4);
+      if (place == 's')
+       val = fetch_arg (buffer, place, 4);
+      else if (place == 'C')
+       val = fetch_arg (buffer, place, 7);
+      else if (place == '8')
+       val = fetch_arg (buffer, place, 3);
+      else if (place == '3')
+       val = fetch_arg (buffer, place, 8);
+      else if (place == 'b')
+       val = NEXTBYTE (p1);
+      else if (place == 'w')
+       val = NEXTWORD (p1);
+      else if (place == 'l')
+       val = NEXTLONG (p1);
+      else
+       error ("Invalid arg format in opcode table: \"%c%c\".",
+              *d, place);
+      fprintf_filtered (stream, "#%d", val);
+      break;
+
+    case 'B':
+      if (place == 'b')
+       val = NEXTBYTE (p);
+      else if (place == 'w')
+       val = NEXTWORD (p);
+      else if (place == 'l')
+       val = NEXTLONG (p);
+      else if (place == 'g')
+       {
+         val = ((char *)buffer)[1];
+         if (val == 0)
+           val = NEXTWORD (p);
+         else if (val == -1)
+           val = NEXTLONG (p);
+       }
+      else if (place == 'c')
+       {
+         if (buffer[1] & 0x40)         /* If bit six is one, long offset */
+           val = NEXTLONG (p);
+         else
+           val = NEXTWORD (p);
+       }
+      else
+       error ("Invalid arg format in opcode table: \"%c%c\".",
+              *d, place);
+
+      print_address (addr + val, stream);
+      break;
+
+    case 'd':
+      val = NEXTWORD (p);
+      fprintf_filtered (stream, "%s@(%d)",
+                       reg_names[fetch_arg (buffer, place, 3)], val);
+      break;
+
+    case 's':
+      fprintf_filtered (stream, "%s",
+                       fpcr_names[fetch_arg (buffer, place, 3)]);
+      break;
+
+    case 'I':
+      val = fetch_arg (buffer, 'd', 3);                  /* Get coprocessor ID... */
+      if (val != 1)                            /* Unusual coprocessor ID? */
+       fprintf_filtered (stream, "(cpid=%d) ", val);
+      if (place == 'i')
+       p += 2;                      /* Skip coprocessor extended operands */
+      break;
+
+    case '*':
+    case '~':
+    case '%':
+    case ';':
+    case '@':
+    case '!':
+    case '$':
+    case '?':
+    case '/':
+    case '&':
+
+      if (place == 'd')
+       {
+         val = fetch_arg (buffer, 'x', 6);
+         val = ((val & 7) << 3) + ((val >> 3) & 7);
+       }
+      else
+       val = fetch_arg (buffer, 's', 6);
+
+      /* Get register number assuming address register.  */
+      regno = (val & 7) + 8;
+      regname = reg_names[regno];
+      switch (val >> 3)
+       {
+       case 0:
+         fprintf_filtered (stream, "%s", reg_names[val]);
+         break;
+
+       case 1:
+         fprintf_filtered (stream, "%s", regname);
+         break;
+
+       case 2:
+         fprintf_filtered (stream, "%s@", regname);
+         break;
+
+       case 3:
+         fprintf_filtered (stream, "%s@+", regname);
+         break;
+
+       case 4:
+         fprintf_filtered (stream, "%s@-", regname);
+         break;
+
+       case 5:
+         val = NEXTWORD (p);
+         fprintf_filtered (stream, "%s@(%d)", regname, val);
+         break;
+
+       case 6:
+         p = print_indexed (regno, p, addr, stream);
+         break;
+
+       case 7:
+         switch (val & 7)
+           {
+           case 0:
+             val = NEXTWORD (p);
+             fprintf_filtered (stream, "@#");
+             print_address (val, stream);
+             break;
+
+           case 1:
+             val = NEXTLONG (p);
+             fprintf_filtered (stream, "@#");
+             print_address (val, stream);
+             break;
+
+           case 2:
+             val = NEXTWORD (p);
+             print_address (addr + val, stream);
+             break;
+
+           case 3:
+             p = print_indexed (-1, p, addr, stream);
+             break;
+
+           case 4:
+             flt_p = 1;        /* Assume it's a float... */
+             switch( place )
+             {
+               case 'b':
+                 val = NEXTBYTE (p);
+                 flt_p = 0;
+                 break;
+
+               case 'w':
+                 val = NEXTWORD (p);
+                 flt_p = 0;
+                 break;
+
+               case 'l':
+                 val = NEXTLONG (p);
+                 flt_p = 0;
+                 break;
+
+               case 'f':
+                 flval = NEXTSINGLE(p);
+                 break;
+
+               case 'F':
+                 flval = NEXTDOUBLE(p);
+                 break;
+
+               case 'x':
+                 flval = NEXTEXTEND(p);
+                 break;
+
+               case 'p':
+                 flval = NEXTPACKED(p);
+                 break;
+
+               default:
+                 error ("Invalid arg format in opcode table: \"%c%c\".",
+                      *d, place);
+             }
+             if ( flt_p )      /* Print a float? */
+               fprintf_filtered (stream, "#%g", flval);
+             else
+               fprintf_filtered (stream, "#%d", val);
+             break;
+
+           default:
+             fprintf_filtered (stream, "<invalid address mode 0%o>", val);
+           }
+       }
+      break;
+
+    case 'L':
+    case 'l':
+       if (place == 'w')
+         {
+           char doneany;
+           p1 = buffer + 2;
+           val = NEXTWORD (p1);
+           /* Move the pointer ahead if this point is farther ahead
+              than the last.  */
+           p = p1 > p ? p1 : p;
+           if (val == 0)
+             {
+               fputs_filtered ("#0", stream);
+               break;
+             }
+           if (*d == 'l')
+             {
+               register int newval = 0;
+               for (regno = 0; regno < 16; ++regno)
+                 if (val & (0x8000 >> regno))
+                   newval |= 1 << regno;
+               val = newval;
+             }
+           val &= 0xffff;
+           doneany = 0;
+           for (regno = 0; regno < 16; ++regno)
+             if (val & (1 << regno))
+               {
+                 int first_regno;
+                 if (doneany)
+                   fputs_filtered ("/", stream);
+                 doneany = 1;
+                 fprintf_filtered (stream, "%s", reg_names[regno]);
+                 first_regno = regno;
+                 while (val & (1 << (regno + 1)))
+                   ++regno;
+                 if (regno > first_regno)
+                   fprintf_filtered (stream, "-%s", reg_names[regno]);
+               }
+         }
+       else if (place == '3')
+         {
+           /* `fmovem' insn.  */
+           char doneany;
+           val = fetch_arg (buffer, place, 8);
+           if (val == 0)
+             {
+               fputs_filtered ("#0", stream);
+               break;
+             }
+           if (*d == 'l')
+             {
+               register int newval = 0;
+               for (regno = 0; regno < 8; ++regno)
+                 if (val & (0x80 >> regno))
+                   newval |= 1 << regno;
+               val = newval;
+             }
+           val &= 0xff;
+           doneany = 0;
+           for (regno = 0; regno < 8; ++regno)
+             if (val & (1 << regno))
+               {
+                 int first_regno;
+                 if (doneany)
+                   fputs_filtered ("/", stream);
+                 doneany = 1;
+                 fprintf_filtered (stream, "fp%d", regno);
+                 first_regno = regno;
+                 while (val & (1 << (regno + 1)))
+                   ++regno;
+                 if (regno > first_regno)
+                   fprintf_filtered (stream, "-fp%d", regno);
+               }
+         }
+       else
+         abort ();
+      break;
+
+    default:
+      error ("Invalid arg format in opcode table: \"%c\".", *d);
+    }
+
+  return (unsigned char *) p;
+}
+
+/* Fetch BITS bits from a position in the instruction specified by CODE.
+   CODE is a "place to put an argument", or 'x' for a destination
+   that is a general address (mode and register).
+   BUFFER contains the instruction.  */
+
+static int
+fetch_arg (buffer, code, bits)
+     unsigned char *buffer;
+     char code;
+     int bits;
+{
+  register int val;
+  switch (code)
+    {
+    case 's':
+      val = buffer[1];
+      break;
+
+    case 'd':                  /* Destination, for register or quick.  */
+      val = (buffer[0] << 8) + buffer[1];
+      val >>= 9;
+      break;
+
+    case 'x':                  /* Destination, for general arg */
+      val = (buffer[0] << 8) + buffer[1];
+      val >>= 6;
+      break;
+
+    case 'k':
+      val = (buffer[3] >> 4);
+      break;
+
+    case 'C':
+      val = buffer[3];
+      break;
+
+    case '1':
+      val = (buffer[2] << 8) + buffer[3];
+      val >>= 12;
+      break;
+
+    case '2':
+      val = (buffer[2] << 8) + buffer[3];
+      val >>= 6;
+      break;
+
+    case '3':
+    case 'j':
+      val = (buffer[2] << 8) + buffer[3];
+      break;
+
+    case '4':
+      val = (buffer[4] << 8) + buffer[5];
+      val >>= 12;
+      break;
+
+    case '5':
+      val = (buffer[4] << 8) + buffer[5];
+      val >>= 6;
+      break;
+
+    case '6':
+      val = (buffer[4] << 8) + buffer[5];
+      break;
+
+    case '7':
+      val = (buffer[2] << 8) + buffer[3];
+      val >>= 7;
+      break;
+      
+    case '8':
+      val = (buffer[2] << 8) + buffer[3];
+      val >>= 10;
+      break;
+
+    default:
+      abort ();
+    }
+
+  switch (bits)
+    {
+    case 3:
+      return val & 7;
+    case 4:
+      return val & 017;
+    case 5:
+      return val & 037;
+    case 6:
+      return val & 077;
+    case 7:
+      return val & 0177;
+    case 8:
+      return val & 0377;
+    case 12:
+      return val & 07777;
+    default:
+      abort ();
+    }
+}
+
+/* Print an indexed argument.  The base register is BASEREG (-1 for pc).
+   P points to extension word, in buffer.
+   ADDR is the nominal core address of that extension word.  */
+
+static unsigned char *
+print_indexed (basereg, p, addr, stream)
+     int basereg;
+     unsigned char *p;
+     FILE *stream;
+     CORE_ADDR addr;
+{
+  register int word;
+  static char *scales[] = {"", "*2", "*4", "*8"};
+  register int base_disp;
+  register int outer_disp;
+  char buf[40];
+
+  word = NEXTWORD (p);
+
+  /* Generate the text for the index register.
+     Where this will be output is not yet determined.  */
+  sprintf (buf, "[%s.%c%s]",
+          reg_names[(word >> 12) & 0xf],
+          (word & 0x800) ? 'l' : 'w',
+          scales[(word >> 9) & 3]);
+
+  /* Handle the 68000 style of indexing.  */
+
+  if ((word & 0x100) == 0)
+    {
+      print_base (basereg,
+                 ((word & 0x80) ? word | 0xff00 : word & 0xff)
+                 + ((basereg == -1) ? addr : 0),
+                 stream);
+      fputs_filtered (buf, stream);
+      return p;
+    }
+
+  /* Handle the generalized kind.  */
+  /* First, compute the displacement to add to the base register.  */
+
+  if (word & 0200)
+    basereg = -2;
+  if (word & 0100)
+    buf[0] = 0;
+  base_disp = 0;
+  switch ((word >> 4) & 3)
+    {
+    case 2:
+      base_disp = NEXTWORD (p);
+      break;
+    case 3:
+      base_disp = NEXTLONG (p);
+    }
+  if (basereg == -1)
+    base_disp += addr;
+
+  /* Handle single-level case (not indirect) */
+
+  if ((word & 7) == 0)
+    {
+      print_base (basereg, base_disp, stream);
+      fputs_filtered (buf, stream);
+      return p;
+    }
+
+  /* Two level.  Compute displacement to add after indirection.  */
+
+  outer_disp = 0;
+  switch (word & 3)
+    {
+    case 2:
+      outer_disp = NEXTWORD (p);
+      break;
+    case 3:
+      outer_disp = NEXTLONG (p);
+    }
+
+  fprintf_filtered (stream, "%d(", outer_disp);
+  print_base (basereg, base_disp, stream);
+
+  /* If postindexed, print the closeparen before the index.  */
+  if (word & 4)
+    fprintf_filtered (stream, ")%s", buf);
+  /* If preindexed, print the closeparen after the index.  */
+  else
+    fprintf_filtered (stream, "%s)", buf);
+
+  return p;
+}
+
+/* Print a base register REGNO and displacement DISP, on STREAM.
+   REGNO = -1 for pc, -2 for none (suppressed).  */
+
+static void
+print_base (regno, disp, stream)
+     int regno;
+     int disp;
+     FILE *stream;
+{
+  if (regno == -2)
+    fprintf_filtered (stream, "%d", disp);
+  else if (regno == -1)
+    fprintf_filtered (stream, "0x%x", disp);
+  else
+    fprintf_filtered (stream, "%d(%s)", disp, reg_names[regno]);
+}
diff --git a/gdb/mcheck.c b/gdb/mcheck.c
new file mode 100755 (executable)
index 0000000..8b63d72
--- /dev/null
@@ -0,0 +1,119 @@
+/* Standard debugging hooks for `malloc'.
+   Copyright 1990 Free Software Foundation
+                 Written May 1989 by Mike Haertel.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   The author may be reached (Email) at the address mike@ai.mit.edu,
+   or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#include "ansidecl.h"
+#include <stdlib.h>
+#include "gmalloc.h"
+
+/* Old hook values.  */
+static void EXFUN((*old_free_hook), (PTR ptr));
+static PTR EXFUN((*old_malloc_hook), (size_t size));
+static PTR EXFUN((*old_realloc_hook), (PTR ptr, size_t size));
+
+/* Function to call when something awful happens. */
+static void EXFUN((*abortfunc), (void)) = abort;
+
+/* Arbitrary magical numbers.  */
+#define MAGICWORD      0xfedabeeb
+#define MAGICBYTE      ((char) 0xd7)
+
+struct hdr
+  {
+    size_t size;               /* Exact size requested by user.  */
+    unsigned int magic;                /* Magic number to check header integrity.  */
+  };
+
+static void
+DEFUN(checkhdr, (hdr), CONST struct hdr *hdr)
+{
+  if (hdr->magic != MAGICWORD || ((char *) &hdr[1])[hdr->size] != MAGICBYTE)
+    (*abortfunc)();
+}
+
+static void
+DEFUN(freehook, (ptr), PTR ptr)
+{
+  struct hdr *hdr = ((struct hdr *) ptr) - 1;
+  checkhdr(hdr);
+  hdr->magic = 0;
+  __free_hook = old_free_hook;
+  free(hdr);
+  __free_hook = freehook;
+}
+
+static PTR
+DEFUN(mallochook, (size), size_t size)
+{
+  struct hdr *hdr;
+
+  __malloc_hook = old_malloc_hook;
+  hdr = (struct hdr *) malloc(sizeof(struct hdr) + size + 1);
+  __malloc_hook = mallochook;
+  if (hdr == NULL)
+    return NULL;
+
+  hdr->size = size;
+  hdr->magic = MAGICWORD;
+  ((char *) &hdr[1])[size] = MAGICBYTE;
+  return (PTR) (hdr + 1);
+}
+
+static PTR
+DEFUN(reallochook, (ptr, size), PTR ptr AND size_t size)
+{
+  struct hdr *hdr = ((struct hdr *) ptr) - 1;
+
+  checkhdr(hdr);
+  __free_hook = old_free_hook;
+  __malloc_hook = old_malloc_hook;
+  __realloc_hook = old_realloc_hook;
+  hdr = (struct hdr *) realloc((PTR) hdr, sizeof(struct hdr) + size + 1);
+  __free_hook = freehook;
+  __malloc_hook = mallochook;
+  __realloc_hook = reallochook;
+  if (hdr == NULL)
+    return NULL;
+
+  hdr->size = size;
+  ((char *) &hdr[1])[size] = MAGICBYTE;
+  return (PTR) (hdr + 1);
+}
+
+void
+DEFUN(mcheck, (func), void EXFUN((*func), (void)))
+{
+  static int mcheck_used = 0;
+
+  if (func)
+    abortfunc = func;
+
+  /* These hooks may not be safely inserted if malloc is already in use.  */
+  if (!__malloc_initialized && !mcheck_used)
+    {
+      old_free_hook = __free_hook;
+      __free_hook = freehook;
+      old_malloc_hook = __malloc_hook;
+      __malloc_hook = mallochook;
+      old_realloc_hook = __realloc_hook;
+      __realloc_hook = reallochook;
+      mcheck_used = 1;
+    }
+}
diff --git a/gdb/mips-opcode.h b/gdb/mips-opcode.h
new file mode 100755 (executable)
index 0000000..fd92c78
--- /dev/null
@@ -0,0 +1,363 @@
+/* Mips opcde list for GDB, the GNU debugger.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+   Contributed by Nobuyuki Hikichi(hikichi@sra.junet)
+   Made to work for little-endian machines, and debugged
+   by Per Bothner (bothner@cs.wisc.edu).
+   Many fixes contributed by Frank Yellin (fy@lucid.com).
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifdef BITS_BIG_ENDIAN
+#define BIT_FIELDS_2(a,b) a;b;
+#define BIT_FIELDS_4(a,b,c,d) a;b;c;d;
+#define BIT_FIELDS_6(a,b,c,d,e,f) a;b;c;d;e;f;
+#else
+#define BIT_FIELDS_2(a,b) b;a;
+#define BIT_FIELDS_4(a,b,c,d) d;c;b;a;
+#define BIT_FIELDS_6(a,b,c,d,e,f) f;e;d;c;b;a;
+#endif
+
+struct op_i_fmt
+{
+BIT_FIELDS_4(
+  unsigned op : 6,
+  unsigned rs : 5,
+  unsigned rt : 5,
+  unsigned immediate : 16)
+};
+
+struct op_j_fmt
+{
+BIT_FIELDS_2(
+  unsigned op : 6,
+  unsigned target : 26)
+};
+
+struct op_r_fmt
+{
+BIT_FIELDS_6(
+  unsigned op : 6,
+  unsigned rs : 5,
+  unsigned rt : 5,
+  unsigned rd : 5,
+  unsigned shamt : 5,
+  unsigned funct : 6)
+};
+
+
+struct fop_i_fmt
+{
+BIT_FIELDS_4(
+  unsigned op : 6,
+  unsigned rs : 5,
+  unsigned rt : 5,
+  unsigned immediate : 16)
+};
+
+struct op_b_fmt
+{
+BIT_FIELDS_4(
+  unsigned op : 6,
+  unsigned rs : 5,
+  unsigned rt : 5,
+  short delta : 16)
+};
+
+struct fop_r_fmt
+{
+BIT_FIELDS_6(
+  unsigned op : 6,
+  unsigned fmt : 5,
+  unsigned ft : 5,
+  unsigned fs : 5,
+  unsigned fd : 5,
+  unsigned funct : 6)
+};
+
+struct mips_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long match;
+  char *args;
+  int bdelay; /* Nonzero if delayed branch.  */
+};
+
+/* args format;
+
+   "s" rs: source register specifier
+   "t" rt: target register
+   "i" immediate
+   "a" target address
+   "c" branch condition
+   "d" rd: destination register specifier
+   "h" shamt: shift amount
+   "f" funct: function field
+
+  for fpu
+   "S" fs source 1 register
+   "T" ft source 2 register
+   "D" distination register
+*/
+
+#define one(x) (x << 26)
+#define op_func(x, y) ((x << 26) | y)
+#define op_cond(x, y) ((x << 26) | (y << 16))
+#define op_rs_func(x, y, z) ((x << 26) | (y << 21) | z)
+#define op_rs_b11(x, y, z) ((x << 26) | (y << 21) | z)
+#define op_o16(x, y) ((x << 26) | (y << 16))
+#define op_bc(x, y, z) ((x << 26) | (y << 21) | (z << 16))
+
+struct mips_opcode mips_opcodes[] = 
+{
+/* These first opcodes are special cases of the ones in the comments */
+  {"nop",      0,              0xffffffff,          /*li*/     "", 0},
+  {"li",       op_bc(9,0,0),   op_bc(0x3f,31,0),    /*addiu*/  "t,j", 0},
+  {"b",                one(4),         0xffff0000,          /*beq*/    "b", 1},
+  {"move",     op_func(0, 33), op_cond(0x3f,31)|0x7ff,/*addu*/ "d,s", 0},
+
+  {"sll",      op_func(0, 0),  op_func(0x3f, 0x3f),            "d,t,h", 0},
+  {"srl",      op_func(0, 2),  op_func(0x3f, 0x3f),            "d,t,h", 0},
+  {"sra",      op_func(0, 3),  op_func(0x3f, 0x3f),            "d,t,h", 0},
+  {"sllv",     op_func(0, 4),  op_func(0x3f, 0x7ff),           "d,t,s", 0},
+  {"srlv",     op_func(0, 6),  op_func(0x3f, 0x7ff),           "d,t,s", 0},
+  {"srav",     op_func(0, 7),  op_func(0x3f, 0x7ff),           "d,t,s", 0},
+  {"jr",       op_func(0, 8),  op_func(0x3f, 0x1fffff),        "s", 1},
+  {"jalr",     op_func(0, 9),  op_func(0x3f, 0x1f07ff),        "d,s", 1},
+  {"syscall",  op_func(0, 12), op_func(0x3f, 0x3f),            "", 0},
+  {"break",    op_func(0, 13), op_func(0x3f, 0x3f),            "", 0},
+  {"mfhi",      op_func(0, 16), op_func(0x3f, 0x03ff07ff),      "d", 0},
+  {"mthi",      op_func(0, 17), op_func(0x3f, 0x1fffff),        "s", 0},
+  {"mflo",      op_func(0, 18), op_func(0x3f, 0x03ff07ff),      "d", 0},
+  {"mtlo",      op_func(0, 19), op_func(0x3f, 0x1fffff),        "s", 0},
+  {"mult",     op_func(0, 24), op_func(0x3f, 0xffff),          "s,t", 0},
+  {"multu",    op_func(0, 25), op_func(0x3f, 0xffff),          "s,t", 0},
+  {"div",      op_func(0, 26), op_func(0x3f, 0xffff),          "s,t", 0},
+  {"divu",     op_func(0, 27), op_func(0x3f, 0xffff),          "s,t", 0},
+  {"add",      op_func(0, 32), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"addu",     op_func(0, 33), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"sub",      op_func(0, 34), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"subu",     op_func(0, 35), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"and",      op_func(0, 36), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"or",       op_func(0, 37), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"xor",      op_func(0, 38), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"nor",      op_func(0, 39), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"slt",      op_func(0, 42), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+  {"sltu",     op_func(0, 43), op_func(0x3f, 0x7ff),           "d,s,t", 0},
+
+  {"bltz",     op_cond (1, 0), op_cond(0x3f, 0x1f),            "s,b", 1},
+  {"bgez",     op_cond (1, 1), op_cond(0x3f, 0x1f),            "s,b", 1},
+  {"bltzal",   op_cond (1, 16),op_cond(0x3f, 0x1f),            "s,b", 1},
+  {"bgezal",   op_cond (1, 17),op_cond(0x3f, 0x1f),            "s,b", 1},
+
+
+  {"j",                one(2),         one(0x3f),                      "a", 1},
+  {"jal",      one(3),         one(0x3f),                      "a", 1},
+  {"beq",      one(4),         one(0x3f),                      "s,t,b", 1},
+  {"bne",      one(5),         one(0x3f),                      "s,t,b", 1},
+  {"blez",     one(6),         one(0x3f) | 0x1f0000,           "s,b", 1},
+  {"bgtz",     one(7),         one(0x3f) | 0x1f0000,           "s,b", 1},
+  {"addi",     one(8),         one(0x3f),                      "t,s,j", 0},
+  {"addiu",    one(9),         one(0x3f),                      "t,s,j", 0},
+  {"slti",     one(10),        one(0x3f),                      "t,s,j", 0},
+  {"sltiu",    one(11),        one(0x3f),                      "t,s,j", 0},
+  {"andi",     one(12),        one(0x3f),                      "t,s,i", 0},
+  {"ori",      one(13),        one(0x3f),                      "t,s,i", 0},
+  {"xori",     one(14),        one(0x3f),                      "t,s,i", 0},
+       /* rs field is don't care field? */
+  {"lui",      one(15),        one(0x3f),                      "t,i", 0},
+
+/* co processor 0 instruction */
+  {"mfc0",     op_rs_b11 (16, 0, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"cfc0",     op_rs_b11 (16, 2, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"mtc0",     op_rs_b11 (16, 4, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"ctc0",     op_rs_b11 (16, 6, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+
+  {"bc0f",     op_o16(16, 0x100),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc0f",     op_o16(16, 0x180),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc0t",     op_o16(16, 0x101),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc0t",     op_o16(16, 0x181),      op_o16(0x3f, 0x3ff),    "b", 1},
+
+  {"tlbr",     op_rs_func(16, 0x10, 1), ~0, "", 0},
+  {"tlbwi",    op_rs_func(16, 0x10, 2), ~0, "", 0},
+  {"tlbwr",    op_rs_func(16, 0x10, 6), ~0, "", 0},
+  {"tlbp",     op_rs_func(16, 0x10, 8), ~0, "", 0},
+  {"rfe",      op_rs_func(16, 0x10, 16), ~0, "", 0},
+
+  {"mfc1",     op_rs_b11 (17, 0, 0),   op_rs_b11(0x3f, 0x1f, 0),"t,S", 0},
+  {"cfc1",     op_rs_b11 (17, 2, 0),   op_rs_b11(0x3f, 0x1f, 0),"t,S", 0},
+  {"mtc1",     op_rs_b11 (17, 4, 0),   op_rs_b11(0x3f, 0x1f, 0),"t,S", 0},
+  {"ctc1",     op_rs_b11 (17, 6, 0),   op_rs_b11(0x3f, 0x1f, 0),"t,S", 0},
+
+  {"bc1f",     op_o16(17, 0x100),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc1f",     op_o16(17, 0x180),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc1t",     op_o16(17, 0x101),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc1t",     op_o16(17, 0x181),      op_o16(0x3f, 0x3ff),    "b", 1},
+
+/* fpu instruction */
+  {"add.s",    op_rs_func(17, 0x10, 0),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"add.d",    op_rs_func(17, 0x11, 0),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"sub.s",    op_rs_func(17, 0x10, 1),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"sub.d",    op_rs_func(17, 0x11, 1),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"mul.s",    op_rs_func(17, 0x10, 2),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"mul.d",    op_rs_func(17, 0x11, 2),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"div.s",    op_rs_func(17, 0x10, 3),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"div.d",    op_rs_func(17, 0x11, 3),
+                       op_rs_func(0x3f, 0x1f, 0x3f),   "D,S,T", 0},
+  {"abs.s",    op_rs_func(17, 0x10, 5),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"abs.d",    op_rs_func(17, 0x11, 5),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"mov.s",    op_rs_func(17, 0x10, 6),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"mov.d",    op_rs_func(17, 0x11, 6),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"neg.s",    op_rs_func(17, 0x10, 7),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"neg.d",    op_rs_func(17, 0x11, 7),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.s.s",  op_rs_func(17, 0x10, 32),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.s.d",  op_rs_func(17, 0x11, 32),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.s.w",  op_rs_func(17, 0x14, 32),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.d.s",  op_rs_func(17, 0x10, 33),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.d.d",  op_rs_func(17, 0x11, 33),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.d.w",  op_rs_func(17, 0x14, 33),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.w.s",  op_rs_func(17, 0x10, 36),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"cvt.w.d",  op_rs_func(17, 0x11, 36),
+                       op_rs_func(0x3f, 0x1f, 0x1f003f),       "D,S", 0},
+  {"c.f.s",    op_rs_func(17, 0x10, 48),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.f.d",    op_rs_func(17, 0x11, 48),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.un.s",   op_rs_func(17, 0x10, 49),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.un.d",   op_rs_func(17, 0x11, 49),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.eq.s",   op_rs_func(17, 0x10, 50),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.eq.d",   op_rs_func(17, 0x11, 50),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ueq.s",  op_rs_func(17, 0x10, 51),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ueq.d",  op_rs_func(17, 0x11, 51),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.olt.s",  op_rs_func(17, 0x10, 52),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.olt.d",  op_rs_func(17, 0x11, 52),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ult.s",  op_rs_func(17, 0x10, 53),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ult.d",  op_rs_func(17, 0x11, 53),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ole.s",  op_rs_func(17, 0x10, 54),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ole.d",  op_rs_func(17, 0x11, 54),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ule.s",  op_rs_func(17, 0x10, 55),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ule.d",  op_rs_func(17, 0x11, 55),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.sf.s",   op_rs_func(17, 0x10, 56),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.sf.d",   op_rs_func(17, 0x11, 56),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngle.s", op_rs_func(17, 0x10, 57),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngle.d", op_rs_func(17, 0x11, 57),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.seq.s",  op_rs_func(17, 0x10, 58),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.seq.d",  op_rs_func(17, 0x11, 58),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngl.s",  op_rs_func(17, 0x10, 59),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngl.d",  op_rs_func(17, 0x11, 59),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.lt.s",   op_rs_func(17, 0x10, 60),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.lt.d",   op_rs_func(17, 0x11, 60),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.nge.s",  op_rs_func(17, 0x10, 61),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.nge.d",  op_rs_func(17, 0x11, 61),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.le.s",   op_rs_func(17, 0x10, 62),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.le.d",   op_rs_func(17, 0x11, 62),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngt.s",  op_rs_func(17, 0x10, 63),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+  {"c.ngt.d",  op_rs_func(17, 0x11, 63),
+                       op_rs_func(0x3f, 0x1f, 0x7ff),  "S,T", 0},
+
+/* co processor 2 instruction */
+  {"mfc2",     op_rs_b11 (18, 0, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"cfc2",     op_rs_b11 (18, 2, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"mtc2",     op_rs_b11 (18, 4, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"ctc2",     op_rs_b11 (18, 6, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"bc2f",     op_o16(18, 0x100),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc2f",     op_o16(18, 0x180),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc2f",     op_o16(18, 0x101),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc2t",     op_o16(18, 0x181),      op_o16(0x3f, 0x3ff),    "b", 1},
+
+/* co processor 3 instruction */
+  {"mtc3",     op_rs_b11 (19, 0, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"cfc3",     op_rs_b11 (19, 2, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"mtc3",     op_rs_b11 (19, 4, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"ctc3",     op_rs_b11 (19, 6, 0),   op_rs_b11(0x3f, 0x1f, 0x1ffff), "t,d", 0},
+  {"bc3f",     op_o16(19, 0x100),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc3f",     op_o16(19, 0x180),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc3t",     op_o16(19, 0x101),      op_o16(0x3f, 0x3ff),    "b", 1},
+  {"bc3t",     op_o16(19, 0x181),      op_o16(0x3f, 0x3ff),    "b", 1},
+
+  {"lb",       one(32),        one(0x3f),              "t,j(s)", 0},
+  {"lh",       one(33),        one(0x3f),              "t,j(s)", 0},
+  {"lwl",      one(34),        one(0x3f),              "t,j(s)", 0},
+  {"lw",       one(35),        one(0x3f),              "t,j(s)", 0},
+  {"lbu",      one(36),        one(0x3f),              "t,j(s)", 0},
+  {"lhu",      one(37),        one(0x3f),              "t,j(s)", 0},
+  {"lwr",      one(38),        one(0x3f),              "t,j(s)", 0},
+  {"sb",       one(40),        one(0x3f),              "t,j(s)", 0},
+  {"sh",       one(41),        one(0x3f),              "t,j(s)", 0},
+  {"swl",      one(42),        one(0x3f),              "t,j(s)", 0},
+  {"swr",       one(46),        one(0x3f),              "t,j(s)", 0},
+  {"sw",       one(43),        one(0x3f),              "t,j(s)", 0},
+  {"lwc0",     one(48),        one(0x3f),              "t,j(s)", 0},
+/* for fpu */
+  {"lwc1",     one(49),        one(0x3f),              "T,j(s)", 0},
+  {"lwc2",     one(50),        one(0x3f),              "t,j(s)", 0},
+  {"lwc3",     one(51),        one(0x3f),              "t,j(s)", 0},
+  {"swc0",     one(56),        one(0x3f),              "t,j(s)", 0},
+/* for fpu */
+  {"swc1",     one(57),        one(0x3f),              "T,j(s)", 0},
+  {"swc2",     one(58),        one(0x3f),              "t,j(s)", 0},
+  {"swc3",     one(59),        one(0x3f),              "t,j(s)", 0},
+};
diff --git a/gdb/mips-pinsn.c b/gdb/mips-pinsn.c
new file mode 100644 (file)
index 0000000..b348339
--- /dev/null
@@ -0,0 +1,149 @@
+/* Print mips instructions for GDB, the GNU debugger.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+   Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp)
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "mips-opcode.h"
+
+/* Mips instructions are never longer than this many bytes.  */
+#define MAXLEN 4
+
+/* Number of elements in the opcode table.  */
+#define NOPCODES (sizeof mips_opcodes / sizeof mips_opcodes[0])
+
+#define MKLONG(p)  *(unsigned long*)p
+
+extern char *reg_names[];
+
+\f
+/* subroutine */
+static unsigned char *
+print_insn_arg (d, l, stream, pc)
+     char *d;
+     register unsigned long int *l;
+     FILE *stream;
+     CORE_ADDR pc;
+{
+  switch (*d)
+    {
+    case ',':
+    case '(':
+    case ')':
+      fputc (*d, stream);
+      break;
+
+    case 's':
+      fprintf (stream, "$%s", reg_names[((struct op_i_fmt *) l)->rs]);
+      break;
+
+    case 't':
+      fprintf (stream, "$%s", reg_names[((struct op_i_fmt *) l)->rt]);
+      break;
+
+    case 'i':
+      fprintf (stream, "%d", ((struct op_i_fmt *) l)->immediate);
+      break;
+
+    case 'j': /* same as i, but sign-extended */
+      fprintf (stream, "%d", ((struct op_b_fmt *) l)->delta);
+      break;
+
+    case 'a':
+      print_address ((pc & 0xF0000000) | (((struct op_j_fmt *)l)->target << 2),
+                    stream);
+      break;
+
+    case 'b':
+      print_address ((((struct op_b_fmt *) l)->delta << 2) + pc + 4, stream);
+      break;
+
+    case 'd':
+      fprintf (stream, "%s", reg_names[((struct op_r_fmt *) l)->rd]);
+      break;
+
+    case 'h':
+      fprintf (stream, "0x%x", ((struct op_r_fmt *) l)->shamt);
+      break;
+
+    case 'S':
+      fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->fs);
+      break;
+
+    case 'T':
+      fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->ft);
+      break;
+
+    case 'D':
+      fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->fd);
+      break;
+
+    default:
+      fprintf (stream, "# internal error, undefined modifier(%c)", *d);
+      break;
+    }
+}
+\f
+/* Print the mips instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes, which
+   is always 4.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  register int i;
+  register char *d;
+  unsigned long int l;
+
+  read_memory (memaddr, buffer, MAXLEN);
+
+  for (i = 0; i < NOPCODES; i++)
+    {
+      register unsigned int opcode = mips_opcodes[i].opcode;
+      register unsigned int match = mips_opcodes[i].match;
+      if ((*(unsigned int*)buffer & match) == opcode)
+       break;
+    }
+
+  l = MKLONG (buffer);
+  /* Handle undefined instructions.  */
+  if (i == NOPCODES)
+    {
+      fprintf (stream, "0x%x",l);
+      return 4;
+    }
+
+  fprintf (stream, "%s", mips_opcodes[i].name);
+
+  if (!(d = mips_opcodes[i].args))
+    return 4;
+
+  fputc (' ', stream);
+
+  while (*d)
+    print_insn_arg (d++, &l, stream, memaddr);
+
+  return 4;
+}
diff --git a/gdb/mips-xdep.c b/gdb/mips-xdep.c
new file mode 100644 (file)
index 0000000..7748f1c
--- /dev/null
@@ -0,0 +1,132 @@
+/* Low level MIPS interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+   Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
+   and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <mips/inst.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+/* #include <fcntl.h>  Can we live without this?  */
+
+#include "gdbcore.h"
+
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <sys/stat.h>
+
+/* Get all registers from the inferior */
+
+void
+fetch_inferior_registers ()
+{
+  register int regno;
+  register unsigned int regaddr;
+  char buf[MAX_REGISTER_RAW_SIZE];
+  register int i;
+
+  registers_fetched ();
+
+  for (regno = 1; regno < NUM_REGS; regno++)
+    {
+      regaddr = register_addr (regno, 1);
+      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
+       {
+         *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
+         regaddr += sizeof (int);
+       }
+      supply_register (regno, buf);
+    }
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  register unsigned int regaddr;
+  char buf[80];
+
+  if (regno == 0)
+    return;
+
+  if (regno > 0)
+    {
+      regaddr = register_addr (regno, 1);
+      errno = 0;
+      ptrace (6, inferior_pid, regaddr, read_register (regno));
+      if (errno != 0)
+       {
+         sprintf (buf, "writing register number %d", regno);
+         perror_with_name (buf);
+       }
+    }
+  else
+    {
+      for (regno = 1; regno < NUM_REGS; regno++)
+       {
+         if (regno == 32 || regno == 35 || regno == 36 || regno == 71)
+           continue;
+         regaddr = register_addr (regno, 1);
+         errno = 0;
+         ptrace (6, inferior_pid, regaddr, read_register (regno));
+         if (errno != 0)
+           {
+             sprintf (buf, "writing all regs, number %d", regno);
+             perror_with_name (buf);
+           }
+       }
+    }
+}
+
+void
+fetch_core_registers ()
+{
+  register int regno;
+  int val;
+
+  for (regno = 1; regno < NUM_REGS; regno++) {
+    char buf[MAX_REGISTER_RAW_SIZE];
+
+    val = bfd_seek (core_bfd, register_addr (regno, 0));
+    if (val < 0 || (val = bfd_read (core_bfd, buf, sizeof buf)) < 0) {
+      char buffer[50];
+      strcpy (buffer, "Reading register ");
+      strcat (buffer, reg_names[regno]);
+
+      perror_with_name (buffer);
+    }
+    supply_register (regno, buf);
+  }
+}
diff --git a/gdb/munch b/gdb/munch
new file mode 100755 (executable)
index 0000000..8b59ed0
--- /dev/null
+++ b/gdb/munch
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# create an initialization procedure from a list of .o files
+
+echo '/* Do not modify this file.  It is created automatically by "munch". */'
+echo 'void initialize_all_files () {'
+
+# make it easy to use a different nm, e.g. for cross-developing
+MUNCH_NM=${MUNCH_NM-nm}
+if test "`$MUNCH_NM main.o | egrep 'T _?main$'`" = "" ; then
+    # System V style nm
+    shift;
+    $MUNCH_NM $* | egrep '^(.*[^a-zA-Z_]_|_)_?initialize_.*\.text' | \
+       sed -e 's/^.*\(_initialize_[a-zA-Z0-9_]*\)[^a-zA-Z0-9_].*$/   {extern void \1 (); \1 ();}/'
+else
+    # BSD style nm
+    $MUNCH_NM -p $* | egrep 'T *_?_initialize_' | \
+       sed -e 's/^.*T *_*\(.*\)/    {extern void _\1 (); _\1 ();}/'
+fi
+
+echo '}'
diff --git a/gdb/news-xdep.c b/gdb/news-xdep.c
new file mode 100644 (file)
index 0000000..58a9191
--- /dev/null
@@ -0,0 +1,65 @@
+/* Low level interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifdef __GNUC__
+/* Bad implement execle(3). It's depend for "/bin/cc".
+
+   main()
+   {
+     printf("execle:\n");
+     execle(FILE, ARGS, envp);
+     exit(1);
+   }
+
+   GCC:
+   link a6,#0
+   pea LC5     ; call printf
+   jbsr _printf
+   ;           ; (not popd stack)
+   pea _envp   ; call execle
+   clrl sp@-
+   pea LC4
+   pea LC4
+   pea LC4
+   pea LC3
+   pea LC6
+   jbsr _execle
+   addw #32,sp ; delayed pop !!
+
+   /bin/cc:
+   link.l      fp,#L23
+   movem.l     #L24,(sp)
+   pea L26             ; call printf
+   jbsr        _printf
+   addq.l      #4,sp   ; <--- popd stack !!
+   pea _envp           ; call execle
+   clr.l       -(sp)
+   pea L32
+   
+   */
+
+execle(name, args)
+     char *name, *args;
+{
+  register char        **env = &args;
+  while (*env++)
+    ;
+  execve(name, (char **)&args, (char **)*env);
+}
+#endif
diff --git a/gdb/nindy-tdep.c b/gdb/nindy-tdep.c
new file mode 100644 (file)
index 0000000..b609fd7
--- /dev/null
@@ -0,0 +1,77 @@
+/* Target-machine dependent code for the NINDY monitor running on the Intel 960
+   Copyright (C) 1991 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Miscellaneous NINDY-dependent routines.
+   Some replace macros normally defined in "tm.h".  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "frame.h"
+
+/* 'start_frame' is a variable in the NINDY runtime startup routine
+   that contains the frame pointer of the 'start' routine (the routine
+   that calls 'main').  By reading its contents out of remote memory,
+   we can tell where the frame chain ends:  backtraces should halt before
+   they display this frame.  */
+
+int
+nindy_frame_chain_valid (chain, curframe)
+    unsigned int chain;
+    FRAME curframe;
+{
+       struct symbol *sym;
+       int i;
+
+       /* crtnindy.o is an assembler module that is assumed to be linked
+        * first in an i80960 executable.  It contains the true entry point;
+        * it performs startup up initialization and then calls 'main'.
+        *
+        * 'sf' is the name of a variable in crtnindy.o that is set
+        *      during startup to the address of the first frame.
+        *
+        * 'a' is the address of that variable in 80960 memory.
+        */
+       static char sf[] = "start_frame";
+       CORE_ADDR a;
+
+
+       chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers
+                          contain return status info in them.  */
+       if ( chain == 0 ){
+               return 0;
+       }
+
+       sym = lookup_symbol(sf, 0, VAR_NAMESPACE, (int *)NULL, 
+                                 (struct symtab **)NULL);
+       if ( sym != 0 ){
+               a = sym->value.value;
+       } else {
+               for ( i = 0; strcmp(misc_function_vector[i].name,sf); i++ ){
+                       if ( i >= misc_function_count ){
+                               return 0;
+                       }
+               }
+               a = misc_function_vector[i].address;
+       }
+
+       return ( chain != read_memory_integer(a,4) );
+}
diff --git a/gdb/np1-opcode.h b/gdb/np1-opcode.h
new file mode 100755 (executable)
index 0000000..6546825
--- /dev/null
@@ -0,0 +1,422 @@
+/* Print GOULD NPL instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+struct gld_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long mask;
+  char *args;
+  int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+   is the most any of them need.  The actual length of an instruction
+   is always at least 2 bytes, and at most four.  The length of the
+   instruction is based on the opcode.
+
+   The mask component is a mask saying which bits must match
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing characters
+   that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+   r  Register in first field
+   R  Register in second field
+   b  Base register in first field
+   B  Base register in second field
+   v  Vector register in first field
+   V  Vector register in first field
+   A  Optional address register (base register)
+   X  Optional index register
+   I  Immediate data (16bits signed)
+   O  Offset field (16bits signed)
+   h  Offset field (15bits signed)
+   d  Offset field (14bits signed)
+   S  Shift count field
+
+   any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+   all instances of the same mnemonic must be consecutive.
+   All instances of the same mnemonic with the same number of operands
+   must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "lb",                0xb4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnb",       0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lbs",       0xec080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lh",                0xb4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lnh",       0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lw",                0xb4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnw",       0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ld",                0xb4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lnd",       0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "li",                0xf8000000,     0xfc7f0000,     "r,I",          4 },
+{ "lpa",       0x50080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "la",                0x50000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "labr",      0x58080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lbp",       0x90080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lhp",       0x90000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lwp",       0x90000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ldp",       0x90000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "suabr",     0x58000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lf",                0xbc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lfbr",      0xbc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lwbr",      0x5c000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "stb",       0xd4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sth",       0xd4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stw",       0xd4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "std",       0xd4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stf",       0xdc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stfbr",     0xdc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "stwbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "zmb",       0xd8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmh",       0xd8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "zmw",       0xd8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmd",       0xd8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stbp",      0x94080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sthp",      0x94000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stwp",      0x94000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stdp",      0x94000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lil",       0xf80b0000,     0xfc7f0000,     "r,D",          4 },
+{ "lwsl1",     0xec000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwsl2",     0xfc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwsl3",     0xfc080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "lvb",       0xb0080000,     0xfc080000,     "v,xOA,X",      4 },
+{ "lvh",       0xb0000001,     0xfc080001,     "v,xOA,X",      4 },
+{ "lvw",       0xb0000000,     0xfc080000,     "v,xOA,X",      4 },
+{ "lvd",       0xb0000002,     0xfc080002,     "v,xOA,X",      4 },
+{ "liv",       0x3c040000,     0xfc0f0000,     "v,R",          2 },
+{ "livf",      0x3c080000,     0xfc0f0000,     "v,R",          2 },
+{ "stvb",      0xd0080000,     0xfc080000,     "v,xOA,X",      4 },
+{ "stvh",      0xd0000001,     0xfc080001,     "v,xOA,X",      4 },
+{ "stvw",      0xd0000000,     0xfc080000,     "v,xOA,X",      4 },
+{ "stvd",      0xd0000002,     0xfc080002,     "v,xOA,X",      4 },
+
+{ "trr",       0x2c000000,     0xfc0f0000,     "r,R",          2 },
+{ "trn",       0x2c040000,     0xfc0f0000,     "r,R",          2 },
+{ "trnd",      0x2c0c0000,     0xfc0f0000,     "r,R",          2 },
+{ "trabs",     0x2c010000,     0xfc0f0000,     "r,R",          2 },
+{ "trabsd",    0x2c090000,     0xfc0f0000,     "r,R",          2 },
+{ "trc",       0x2c030000,     0xfc0f0000,     "r,R",          2 },
+{ "xcr",       0x28040000,     0xfc0f0000,     "r,R",          2 },
+{ "cxcr",      0x2c060000,     0xfc0f0000,     "r,R",          2 },
+{ "cxcrd",     0x2c0e0000,     0xfc0f0000,     "r,R",          2 },
+{ "tbrr",      0x2c020000,     0xfc0f0000,     "r,B",          2 },
+{ "trbr",      0x28030000,     0xfc0f0000,     "b,R",          2 },
+{ "xcbr",      0x28020000,     0xfc0f0000,     "b,B",          2 },
+{ "tbrbr",     0x28010000,     0xfc0f0000,     "b,B",          2 },
+
+{ "trvv",      0x28050000,     0xfc0f0000,     "v,V",          2 },
+{ "trvvn",     0x2c050000,     0xfc0f0000,     "v,V",          2 },
+{ "trvvnd",    0x2c0d0000,     0xfc0f0000,     "v,V",          2 },
+{ "trvab",     0x2c070000,     0xfc0f0000,     "v,V",          2 },
+{ "trvabd",    0x2c0f0000,     0xfc0f0000,     "v,V",          2 },
+{ "cmpv",      0x14060000,     0xfc0f0000,     "v,V",          2 },
+{ "expv",      0x14070000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvlt",    0x10030000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvle",    0x10040000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvgt",    0x14030000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvge",    0x14040000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvveq",    0x10050000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvvne",    0x10050000,     0xfc0f0000,     "v,V",          2 },
+{ "mrvrlt",    0x100d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrle",    0x100e0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrgt",    0x140d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrge",    0x140e0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvreq",    0x100f0000,     0xfc0f0000,     "v,R",          2 },
+{ "mrvrne",    0x140f0000,     0xfc0f0000,     "v,R",          2 },
+{ "trvr",      0x140b0000,     0xfc0f0000,     "r,V",          2 },
+{ "trrv",      0x140c0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "bu",                0x40000000,     0xff880000,     "xOA,X",        4 },
+{ "bns",       0x70080000,     0xff880000,     "xOA,X",        4 },
+{ "bnco",      0x70880000,     0xff880000,     "xOA,X",        4 },
+{ "bge",       0x71080000,     0xff880000,     "xOA,X",        4 },
+{ "bne",       0x71880000,     0xff880000,     "xOA,X",        4 },
+{ "bunge",     0x72080000,     0xff880000,     "xOA,X",        4 },
+{ "bunle",     0x72880000,     0xff880000,     "xOA,X",        4 },
+{ "bgt",       0x73080000,     0xff880000,     "xOA,X",        4 },
+{ "bnany",     0x73880000,     0xff880000,     "xOA,X",        4 },
+{ "bs" ,       0x70000000,     0xff880000,     "xOA,X",        4 },
+{ "bco",       0x70800000,     0xff880000,     "xOA,X",        4 },
+{ "blt",       0x71000000,     0xff880000,     "xOA,X",        4 },
+{ "beq",       0x71800000,     0xff880000,     "xOA,X",        4 },
+{ "buge",      0x72000000,     0xff880000,     "xOA,X",        4 },
+{ "bult",      0x72800000,     0xff880000,     "xOA,X",        4 },
+{ "ble",       0x73000000,     0xff880000,     "xOA,X",        4 },
+{ "bany",      0x73800000,     0xff880000,     "xOA,X",        4 },
+{ "brlnk",     0x44000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bib",       0x48000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bih",       0x48080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "biw",       0x4c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bid",       0x4c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivb",      0x60000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivh",      0x60080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivw",      0x64000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bivd",      0x64080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsb",      0x68000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsh",      0x68080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsw",      0x6c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bvsd",      0x6c080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "camb",      0x80080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camh",      0x80000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "camw",      0x80000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camd",      0x80000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "car",       0x10000000,     0xfc0f0000,     "r,R",          2 },
+{ "card",      0x14000000,     0xfc0f0000,     "r,R",          2 },
+{ "ci",                0xf8050000,     0xfc7f0000,     "r,I",          4 },
+{ "chkbnd",    0x5c080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "cavv",      0x10010000,     0xfc0f0000,     "v,V",          2 },
+{ "cavr",      0x10020000,     0xfc0f0000,     "v,R",          2 },
+{ "cavvd",     0x10090000,     0xfc0f0000,     "v,V",          2 },
+{ "cavrd",     0x100b0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "anmb",      0x84080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmh",      0x84000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "anmw",      0x84000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmd",      0x84000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "anr",       0x04000000,     0xfc0f0000,     "r,R",          2 },
+{ "ani",       0xf8080000,     0xfc7f0000,     "r,I",          4 },
+{ "ormb",      0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormh",      0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "ormw",      0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormd",      0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "orr",       0x08000000,     0xfc0f0000,     "r,R",          2 },
+{ "oi",                0xf8090000,     0xfc7f0000,     "r,I",          4 },
+{ "eomb",      0x8c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomh",      0x8c000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "eomw",      0x8c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomd",      0x8c000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "eor",       0x0c000000,     0xfc0f0000,     "r,R",          2 },
+{ "eoi",       0xf80a0000,     0xfc7f0000,     "r,I",          4 },
+
+{ "anvv",      0x04010000,     0xfc0f0000,     "v,V",          2 },
+{ "anvr",      0x04020000,     0xfc0f0000,     "v,R",          2 },
+{ "orvv",      0x08010000,     0xfc0f0000,     "v,V",          2 },
+{ "orvr",      0x08020000,     0xfc0f0000,     "v,R",          2 },
+{ "eovv",      0x0c010000,     0xfc0f0000,     "v,V",          2 },
+{ "eovr",      0x0c020000,     0xfc0f0000,     "v,R",          2 },
+
+{ "sacz",      0x100c0000,     0xfc0f0000,     "r,R",          2 },
+{ "sla",       0x1c400000,     0xfc600000,     "r,S",          2 },
+{ "sll",       0x1c600000,     0xfc600000,     "r,S",          2 },
+{ "slc",       0x24400000,     0xfc600000,     "r,S",          2 },
+{ "slad",      0x20400000,     0xfc600000,     "r,S",          2 },
+{ "slld",      0x20600000,     0xfc600000,     "r,S",          2 },
+{ "sra",       0x1c000000,     0xfc600000,     "r,S",          2 },
+{ "srl",       0x1c200000,     0xfc600000,     "r,S",          2 },
+{ "src",       0x24000000,     0xfc600000,     "r,S",          2 },
+{ "srad",      0x20000000,     0xfc600000,     "r,S",          2 },
+{ "srld",      0x20200000,     0xfc600000,     "r,S",          2 },
+{ "sda",       0x3c030000,     0xfc0f0000,     "r,R",          2 },
+{ "sdl",       0x3c020000,     0xfc0f0000,     "r,R",          2 },
+{ "sdc",       0x3c010000,     0xfc0f0000,     "r,R",          2 },
+{ "sdad",      0x3c0b0000,     0xfc0f0000,     "r,R",          2 },
+{ "sdld",      0x3c0a0000,     0xfc0f0000,     "r,R",          2 },
+
+{ "svda",      0x3c070000,     0xfc0f0000,     "v,R",          2 },
+{ "svdl",      0x3c060000,     0xfc0f0000,     "v,R",          2 },
+{ "svdc",      0x3c050000,     0xfc0f0000,     "v,R",          2 },
+{ "svdad",     0x3c0e0000,     0xfc0f0000,     "v,R",          2 },
+{ "svdld",     0x3c0d0000,     0xfc0f0000,     "v,R",          2 },
+
+{ "sbm",       0xac080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zbm",       0xac000000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tbm",       0xa8080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "incmb",     0xa0000000,     0xfc080000,     "xOA,X",        4 },
+{ "incmh",     0xa0080000,     0xfc080000,     "xOA,X",        4 },
+{ "incmw",     0xa4000000,     0xfc080000,     "xOA,X",        4 },
+{ "incmd",     0xa4080000,     0xfc080000,     "xOA,X",        4 },
+{ "sbmd",      0x7c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zbmd",      0x7c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "tbmd",      0x78080000,     0xfc080000,     "r,xOA,X",      4 },
+
+{ "ssm",       0x9c080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zsm",       0x9c000000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tsm",       0x98080000,     0xfc080000,     "f,xOA,X",      4 },
+
+{ "admb",      0xc8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admh",      0xc8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "admw",      0xc8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admd",      0xc8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adr",       0x38000000,     0xfc0f0000,     "r,R",          2 },
+{ "armb",      0xe8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armh",      0xe8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "armw",      0xe8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armd",      0xe8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adi",       0xf8010000,     0xfc0f0000,     "r,I",          4 },
+{ "sumb",      0xcc080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumh",      0xcc000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "sumw",      0xcc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumd",      0xcc000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sur",       0x3c000000,     0xfc0f0000,     "r,R",          2 },
+{ "sui",       0xf8020000,     0xfc0f0000,     "r,I",          4 },
+{ "mpmb",      0xc0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpmh",      0xc0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "mpmw",      0xc0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpr",       0x38020000,     0xfc0f0000,     "r,R",          2 },
+{ "mprd",      0x3c0f0000,     0xfc0f0000,     "r,R",          2 },
+{ "mpi",       0xf8030000,     0xfc0f0000,     "r,I",          4 },
+{ "dvmb",      0xc4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvmh",      0xc4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "dvmw",      0xc4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvr",       0x380a0000,     0xfc0f0000,     "r,R",          2 },
+{ "dvi",       0xf8040000,     0xfc0f0000,     "r,I",          4 },
+{ "exs",       0x38080000,     0xfc0f0000,     "r,R",          2 },
+
+{ "advv",      0x30000000,     0xfc0f0000,     "v,V",          2 },
+{ "advvd",     0x30080000,     0xfc0f0000,     "v,V",          2 },
+{ "adrv",      0x34000000,     0xfc0f0000,     "v,R",          2 },
+{ "adrvd",     0x34080000,     0xfc0f0000,     "v,R",          2 },
+{ "suvv",      0x30010000,     0xfc0f0000,     "v,V",          2 },
+{ "suvvd",     0x30090000,     0xfc0f0000,     "v,V",          2 },
+{ "surv",      0x34010000,     0xfc0f0000,     "v,R",          2 },
+{ "survd",     0x34090000,     0xfc0f0000,     "v,R",          2 },
+{ "mpvv",      0x30020000,     0xfc0f0000,     "v,V",          2 },
+{ "mprv",      0x34020000,     0xfc0f0000,     "v,R",          2 },
+
+{ "adfw",      0xe0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adfd",      0xe0080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adrfw",     0x38010000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfd",     0x38090000,     0xfc0f0000,     "r,R",          2 },
+{ "surfw",     0xe0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "surfd",     0xe0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "surfw",     0x38030000,     0xfc0f0000,     "r,R",          2 },
+{ "surfd",     0x380b0000,     0xfc0f0000,     "r,R",          2 },
+{ "mpfw",      0xe4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpfd",      0xe4080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "mprfw",     0x38060000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfd",     0x380e0000,     0xfc0f0000,     "r,R",          2 },
+{ "rfw",       0xe4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "rfd",       0xe4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "rrfw",      0x0c0e0000,     0xfc0f0000,     "r",            2 },
+{ "rrfd",      0x0c0f0000,     0xfc0f0000,     "r",            2 },
+
+{ "advvfw",    0x30040000,     0xfc0f0000,     "v,V",          2 },
+{ "advvfd",    0x300c0000,     0xfc0f0000,     "v,V",          2 },
+{ "adrvfw",    0x34040000,     0xfc0f0000,     "v,R",          2 },
+{ "adrvfd",    0x340c0000,     0xfc0f0000,     "v,R",          2 },
+{ "suvvfw",    0x30050000,     0xfc0f0000,     "v,V",          2 },
+{ "suvvfd",    0x300d0000,     0xfc0f0000,     "v,V",          2 },
+{ "survfw",    0x34050000,     0xfc0f0000,     "v,R",          2 },
+{ "survfd",    0x340d0000,     0xfc0f0000,     "v,R",          2 },
+{ "mpvvfw",    0x30060000,     0xfc0f0000,     "v,V",          2 },
+{ "mpvvfd",    0x300e0000,     0xfc0f0000,     "v,V",          2 },
+{ "mprvfw",    0x34060000,     0xfc0f0000,     "v,R",          2 },
+{ "mprvfd",    0x340e0000,     0xfc0f0000,     "v,R",          2 },
+{ "rvfw",      0x30070000,     0xfc0f0000,     "v",            2 },
+{ "rvfd",      0x300f0000,     0xfc0f0000,     "v",            2 },
+
+{ "fltw",      0x38070000,     0xfc0f0000,     "r,R",          2 },
+{ "fltd",      0x380f0000,     0xfc0f0000,     "r,R",          2 },
+{ "fixw",      0x38050000,     0xfc0f0000,     "r,R",          2 },
+{ "fixd",      0x380d0000,     0xfc0f0000,     "r,R",          2 },
+{ "cfpds",     0x3c090000,     0xfc0f0000,     "r,R",          2 },
+
+{ "fltvw",     0x080d0000,     0xfc0f0000,     "v,V",          2 },
+{ "fltvd",     0x080f0000,     0xfc0f0000,     "v,V",          2 },
+{ "fixvw",     0x080c0000,     0xfc0f0000,     "v,V",          2 },
+{ "fixvd",     0x080e0000,     0xfc0f0000,     "v,V",          2 },
+{ "cfpvds",    0x0c0d0000,     0xfc0f0000,     "v,V",          2 },
+
+{ "orvrn",     0x000a0000,     0xfc0f0000,     "r,V",          2 },
+{ "andvrn",    0x00080000,     0xfc0f0000,     "r,V",          2 },
+{ "frsteq",    0x04090000,     0xfc0f0000,     "r,V",          2 },
+{ "sigma",     0x0c080000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmad",    0x0c0a0000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmf",     0x08080000,     0xfc0f0000,     "r,V",          2 },
+{ "sigmfd",    0x080a0000,     0xfc0f0000,     "r,V",          2 },
+{ "prodf",     0x04080000,     0xfc0f0000,     "r,V",          2 },
+{ "prodfd",    0x040a0000,     0xfc0f0000,     "r,V",          2 },
+{ "maxv",      0x10080000,     0xfc0f0000,     "r,V",          2 },
+{ "maxvd",     0x100a0000,     0xfc0f0000,     "r,V",          2 },
+{ "minv",      0x14080000,     0xfc0f0000,     "r,V",          2 },
+{ "minvd",     0x140a0000,     0xfc0f0000,     "r,V",          2 },
+
+{ "lpsd",      0xf0000000,     0xfc080000,     "xOA,X",        4 },
+{ "ldc",       0xf0080000,     0xfc080000,     "xOA,X",        4 },
+{ "spm",       0x040c0000,     0xfc0f0000,     "r",            2 },
+{ "rpm",       0x040d0000,     0xfc0f0000,     "r",            2 },
+{ "tritr",     0x00070000,     0xfc0f0000,     "r",            2 },
+{ "trrit",     0x00060000,     0xfc0f0000,     "r",            2 },
+{ "rpswt",     0x04080000,     0xfc0f0000,     "r",            2 },
+{ "exr",       0xf8070000,     0xfc0f0000,     "",             4 },
+{ "halt",      0x00000000,     0xfc0f0000,     "",             2 },
+{ "wait",      0x00010000,     0xfc0f0000,     "",             2 },
+{ "nop",       0x00020000,     0xfc0f0000,     "",             2 },
+{ "eiae",      0x00030000,     0xfc0f0000,     "",             2 },
+{ "efae",      0x000d0000,     0xfc0f0000,     "",             2 },
+{ "diae",      0x000e0000,     0xfc0f0000,     "",             2 },
+{ "dfae",      0x000f0000,     0xfc0f0000,     "",             2 },
+{ "spvc",      0xf8060000,     0xfc0f0000,     "r,T,N",        4 },
+{ "rdsts",     0x00090000,     0xfc0f0000,     "r",            2 },
+{ "setcpu",    0x000c0000,     0xfc0f0000,     "r",            2 },
+{ "cmc",       0x000b0000,     0xfc0f0000,     "r",            2 },
+{ "trrcu",     0x00040000,     0xfc0f0000,     "r",            2 },
+{ "attnio",    0x00050000,     0xfc0f0000,     "",             2 },
+{ "fudit",     0x28080000,     0xfc0f0000,     "",             2 },
+{ "break",     0x28090000,     0xfc0f0000,     "",             2 },
+{ "frzss",     0x280a0000,     0xfc0f0000,     "",             2 },
+{ "ripi",      0x04040000,     0xfc0f0000,     "r,R",          2 },
+{ "xcp",       0x04050000,     0xfc0f0000,     "r",            2 },
+{ "block",     0x04060000,     0xfc0f0000,     "",             2 },
+{ "unblock",   0x04070000,     0xfc0f0000,     "",             2 },
+{ "trsc",      0x08060000,     0xfc0f0000,     "r,R",          2 },
+{ "tscr",      0x08070000,     0xfc0f0000,     "r,R",          2 },
+{ "fq",                0x04080000,     0xfc0f0000,     "r",            2 },
+{ "flupte",    0x2c080000,     0xfc0f0000,     "r",            2 },
+{ "rviu",      0x040f0000,     0xfc0f0000,     "",             2 },
+{ "ldel",      0x280c0000,     0xfc0f0000,     "r,R",          2 },
+{ "ldu",       0x280d0000,     0xfc0f0000,     "r,R",          2 },
+{ "stdecc",    0x280b0000,     0xfc0f0000,     "r,R",          2 },
+{ "trpc",      0x08040000,     0xfc0f0000,     "r",            2 },
+{ "tpcr",      0x08050000,     0xfc0f0000,     "r",            2 },
+{ "ghalt",     0x0c050000,     0xfc0f0000,     "r",            2 },
+{ "grun",      0x0c040000,     0xfc0f0000,     "",             2 },
+{ "tmpr",      0x2c0a0000,     0xfc0f0000,     "r,R",          2 },
+{ "trmp",      0x2c0b0000,     0xfc0f0000,     "r,R",          2 },
+
+{ "trrve",     0x28060000,     0xfc0f0000,     "r",            2 },
+{ "trver",     0x28070000,     0xfc0f0000,     "r",            2 },
+{ "trvlr",     0x280f0000,     0xfc0f0000,     "r",            2 },
+
+{ "linkfl",    0x18000000,     0xfc0f0000,     "r,R",          2 },
+{ "linkbl",    0x18020000,     0xfc0f0000,     "r,R",          2 },
+{ "linkfp",    0x18010000,     0xfc0f0000,     "r,R",          2 },
+{ "linkbp",    0x18030000,     0xfc0f0000,     "r,R",          2 },
+{ "linkpl",    0x18040000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinkl",    0x18080000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinkp",    0x18090000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinktl",   0x180a0000,     0xfc0f0000,     "r,R",          2 },
+{ "ulinktp",   0x180b0000,     0xfc0f0000,     "r,R",          2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+                               sizeof(gld_opcodes[0]);
diff --git a/gdb/ns32k-opcode.h b/gdb/ns32k-opcode.h
new file mode 100644 (file)
index 0000000..5f336e9
--- /dev/null
@@ -0,0 +1,328 @@
+/* ns32k-opcode.h */
+
+#ifndef ns32k_opcodeT
+#define ns32k_opcodeT int
+#endif /* no ns32k_opcodeT */
+
+struct not_wot                 /* ns32k opcode table: wot to do with this */
+                               /* particular opcode */
+{
+  int obits;           /* number of opcode bits */
+  int ibits;           /* number of instruction bits */
+  ns32k_opcodeT        code;   /* op-code (may be > 8 bits!) */
+  char *args;          /* how to compile said opcode */
+};
+
+struct not                     /* ns32k opcode text */
+{
+  char *            name;      /* opcode name: lowercase string  [key]  */
+  struct not_wot    detail;    /* rest of opcode table          [datum] */
+};
+
+/* Instructions look like this:
+    
+   basic instruction--1, 2, or 3 bytes
+   index byte for operand A, if operand A is indexed--1 byte
+   index byte for operand B, if operand B is indexed--1 byte
+   addressing extension for operand A
+   addressing extension for operand B
+   implied operands
+
+   Operand A is the operand listed first in the following opcode table.
+   Operand B is the operand listed second in the following opcode table.
+   All instructions have at most 2 general operands, so this is enough.
+   The implied operands are associated with operands other than A and B.
+
+   Each operand has a digit and a letter.
+   
+   The digit gives the position in the assembly language.  The letter,
+   one of the following, tells us what kind of operand it is.  */
+
+/* F : 32 bit float
+ * L : 64 bit float
+ * B : byte
+ * W : word
+ * D : double-word
+ * Q : quad-word
+ * d : displacement
+ * q : quick
+ * i : immediate (8 bits)
+ * r : register number (3 bits)
+ * p : displacement - pc relative addressing
+*/
+static struct not
+notstrs[] =
+{
+  { "absf",    14,24,  0x35be, "1F2F" },
+  { "absl",    14,24,  0x34be, "1L2L" },
+  { "absb",    14,24,  0x304e, "1B2B" },
+  { "absw",    14,24,  0x314e, "1W2W" },
+  { "absd",    14,24,  0x334e, "1D2D" },
+  { "acbb",     7,16,  0x4c,   "2B1q3p" },
+  { "acbw",      7,16,  0x4d,   "2W1q3p" },
+  { "acbd",      7,16,  0x4f,   "2D1q3p" },
+  { "addf",    14,24,  0x01be, "1F2F" },
+  { "addl",    14,24,  0x00be, "1L2L" },
+  { "addb",     6,16,  0x00,   "1B2B" },
+  { "addw",     6,16,  0x01,   "1W2W" },
+  { "addd",     6,16,  0x03,   "1D2D" },
+  { "addcb",    6,16,  0x10,   "1B2B" },
+  { "addcw",    6,16,  0x11,   "1W2W" },
+  { "addcd",    6,16,  0x13,   "1D2D" },
+  { "addpb",   14,24,  0x3c4e, "1B2B" },
+  { "addpw",   14,24,  0x3d4e, "1W2W" },
+  { "addpd",   14,24,  0x3f4e, "1D2D" },
+  { "addqb",    7,16,  0x0c,   "2B1q" },
+  { "addqw",    7,16,  0x0d,   "2W1q" },
+  { "addqd",    7,16,  0x0f,   "2D1q" },
+  { "addr",     6,16,  0x27,   "1D2D" },
+  { "adjspb",  11,16,  0x057c, "1B" },
+  { "adjspw",  11,16,  0x057d, "1W" },
+  { "adjspd",  11,16,  0x057f, "1D" },
+  { "andb",     6,16,  0x28,   "1B2B" },
+  { "andw",     6,16,  0x29,   "1W2W" },
+  { "andd",     6,16,  0x2b,   "1D2D" },
+  { "ashb",    14,24,  0x044e, "1B2B" },
+  { "ashw",    14,24,  0x054e, "1B2W" },
+  { "ashd",    14,24,  0x074e, "1B2D" },
+  { "beq",      8,8,   0x0a,   "1p" },
+  { "bne",      8,8,   0x1a,   "1p" },
+  { "bcs",      8,8,   0x2a,   "1p" },
+  { "bcc",      8,8,   0x3a,   "1p" },
+  { "bhi",      8,8,   0x4a,   "1p" },
+  { "bls",      8,8,   0x5a,   "1p" },
+  { "bgt",      8,8,   0x6a,   "1p" },
+  { "ble",      8,8,   0x7a,   "1p" },
+  { "bfs",      8,8,   0x8a,   "1p" },
+  { "bfc",      8,8,   0x9a,   "1p" },
+  { "blo",      8,8,   0xaa,   "1p" },
+  { "bhs",      8,8,   0xba,   "1p" },
+  { "blt",      8,8,   0xca,   "1p" },
+  { "bge",      8,8,   0xda,   "1p" },
+  { "bicb",     6,16,  0x08,   "1B2B" },
+  { "bicw",     6,16,  0x09,   "1W2W" },
+  { "bicd",     6,16,  0x0b,   "1D2D" },
+  { "bicpsrb", 11,16,  0x17c,  "1B" },
+  { "bicpsrw", 11,16,  0x17d,  "1W" },
+  { "bispsrb", 11,16,  0x37c,  "1B" },
+  { "bispsrw", 11,16,  0x37d,  "1W" },
+  { "bpt",      8,8,   0xf2,   "" },
+  { "br",       8,8,   0xea,   "1p" },
+  { "bsr",      8,8,   0x02,   "1p" },
+  { "caseb",   11,16,  0x77c,  "1B" },
+  { "casew",   11,16,  0x77d,  "1W" },
+  { "cased",   11,16,  0x77f,  "1D" },
+  { "cbitb",   14,24,  0x084e, "1B2D" },
+  { "cbitw",   14,24,  0x094e, "1W2D" },
+  { "cbitd",   14,24,  0x0b4e, "1D2D" },
+  { "cbitib",  14,24,  0x0c4e, "1B2D" },
+  { "cbitiw",  14,24,  0x0d4e, "1W2D" },
+  { "cbitid",  14,24,  0x0f4e, "1D2D" },
+  { "checkb",  11,24,  0x0ee,  "2A3B1r" },
+  { "checkw",  11,24,  0x1ee,  "2A3B1r" },
+  { "checkd",  11,24,  0x3ee,  "2A3D1r" },
+  { "cmpf",    14,24,  0x09be, "1F2F" },
+  { "cmpl",    14,24,  0x08be, "1L2L" },
+  { "cmpb",     6,16,  0x04,   "1B2B" },
+  { "cmpw",     6,16,  0x05,   "1W2W" },
+  { "cmpd",     6,16,  0x07,   "1D2D" },
+  { "cmpmb",   14,24,  0x04ce, "1D2D3d" },
+  { "cmpmw",   14,24,  0x05ce, "1D2D3d" },
+  { "cmpmd",   14,24,  0x07ce, "1D2D3d" },
+  { "cmpqb",    7,16,  0x1c,   "2B1q" },
+  { "cmpqw",    7,16,  0x1d,   "2W1q" },
+  { "cmpqd",    7,16,  0x1f,   "2D1q" },
+  { "cmpsb",   16,16,  0x040e, "1i" },
+  { "cmpsw",   16,16,  0x050e, "1i" },
+  { "cmpsd",   16,16,  0x070e, "1i" },
+  { "cmpst",   16,16,  0x840e, "1i" },
+  { "comb",    14,24,  0x344e, "1B2B" },
+  { "comw",    14,24,  0x354e, "1W2W" },
+  { "comd",    14,24,  0x374e, "1D2D" },
+  { "cvtp",    11,24,  0x036e, "2D3D1r" },
+  { "cxp",      8,8,   0x22,   "1p" },
+  { "cxpd",    11,16,  0x07f,  "1D" },
+  { "deib",    14,24,  0x2cce, "1B2W" },
+  { "deiw",    14,24,  0x2dce, "1W2D" },
+  { "deid",    14,24,  0x2fce, "1D2Q" },
+  { "dia",      8,8,   0xc2,   "" },
+  { "divf",    14,24,  0x21be, "1F2F" },
+  { "divl",    14,24,  0x20be, "1L2L" },
+  { "divb",    14,24,  0x3cce, "1B2B" },
+  { "divw",    14,24,  0x3dce, "1W2W" },
+  { "divd",    14,24,  0x3fce, "1D2D" },
+  { "enter",    8,8,   0x82,   "1i2d" },
+  { "exit",     8,8,   0x92,   "1i" },
+  { "extb",    11,24,  0x02e,  "2D3B1r4d" },
+  { "extw",    11,24,  0x12e,  "2D3W1r4d" },
+  { "extd",    11,24,  0x32e,  "2D3D1r4d" },
+  { "extsb",   14,24,  0x0cce, "1D2B3i" },
+  { "extsw",   14,24,  0x0dce, "1D2W3i" },
+  { "extsd",   14,24,  0x0fce, "1D2D3i" },
+  { "ffsb",    14,24,  0x046e, "1B2B" },
+  { "ffsw",    14,24,  0x056e, "1W2B" },
+  { "ffsd",    14,24,  0x076e, "1D2B" },
+  { "flag",     8,8,   0xd2,   "" },
+  { "floorfb", 14,24,  0x3c3e, "1F2B" },
+  { "floorfw", 14,24,  0x3d3e, "1F2W" },
+  { "floorfd", 14,24,  0x3f3e, "1F2D" },
+  { "floorlb", 14,24,  0x383e, "1L2B" },
+  { "floorlw", 14,24,  0x393e, "1L2W" },
+  { "floorld", 14,24,  0x3b3e, "1L2D" },
+  { "ibitb",   14,24,  0x384e, "1B2D" },
+  { "ibitw",   14,24,  0x394e, "1W2D" },
+  { "ibitd",   14,24,  0x3b4e, "1D2D" },
+  { "indexb",  11,24,  0x42e,  "2B3B1r" },
+  { "indexw",  11,24,  0x52e,  "2W3W1r" },
+  { "indexd",  11,24,  0x72e,  "2D3D1r" },
+  { "insb",    11,24,  0x0ae,  "2B3B1r4d" },
+  { "insw",    11,24,  0x1ae,  "2W3W1r4d" },
+  { "insd",    11,24,  0x3ae,  "2D3D1r4d" },
+  { "inssb",   14,24,  0x08ce, "1B2D3i" },
+  { "inssw",   14,24,  0x09ce, "1W2D3i" },
+  { "inssd",   14,24,  0x0bce, "1D2D3i" },
+  { "jsr",     11,16,  0x67f,  "1A" },
+  { "jump",    11,16,  0x27f,  "1A" },
+  { "lfsr",    19,24,  0x00f3e,"1D" },
+  { "lmr",     15,24,  0x0b1e, "2D1q" },
+  { "lprb",     7,16,  0x6c,   "2B1q" },
+  { "lprw",     7,16,  0x6d,   "2W1q" },
+  { "lprd",     7,16,  0x6f,   "2D1q" },
+  { "lshb",    14,24,  0x144e, "1B2B" },
+  { "lshw",    14,24,  0x154e, "1B2W" },
+  { "lshd",    14,24,  0x174e, "1B2D" },
+  { "meib",    14,24,  0x24ce, "1B2W" },
+  { "meiw",    14,24,  0x25ce, "1W2D" },
+  { "meid",    14,24,  0x27ce, "1D2Q" },
+  { "modb",    14,24,  0x38ce, "1B2B" },
+  { "modw",    14,24,  0x39ce, "1W2W" },
+  { "modd",    14,24,  0x3bce, "1D2D" },
+  { "movf",    14,24,  0x05be, "1F2F" },
+  { "movl",    14,24,  0x04be, "1L2L" },
+  { "movb",     6,16,  0x14,   "1B2B" },
+  { "movw",     6,16,  0x15,   "1W2W" },
+  { "movd",     6,16,  0x17,   "1D2D" },
+  { "movbf",   14,24,  0x043e, "1B2F" },
+  { "movwf",   14,24,  0x053e, "1W2F" },
+  { "movdf",   14,24,  0x073e, "1D2F" },
+  { "movbl",   14,24,  0x003e, "1B2L" },
+  { "movwl",   14,24,  0x013e, "1W2L" },
+  { "movdl",   14,24,  0x033e, "1D2L" },
+  { "movfl",   14,24,  0x1b3e, "1F2L" },
+  { "movlf",   14,24,  0x163e, "1L2F" },
+  { "movmb",   14,24,  0x00ce, "1D2D3d" },
+  { "movmw",   14,24,  0x00de, "1D2D3d" },
+  { "movmd",   14,24,  0x00fe, "1D2D3d" },
+  { "movqb",    7,16,  0x5c,   "2B1q" },
+  { "movqw",    7,16,  0x5d,   "2B1q" },
+  { "movqd",    7,16,  0x5f,   "2B1q" },
+  { "movsb",   16,16,  0x000e, "1i" },
+  { "movsw",   16,16,  0x010e, "1i" },
+  { "movsd",   16,16,  0x030e, "1i" },
+  { "movst",   16,16,  0x800e, "1i" },
+  { "movsub",  14,24,  0x0cae, "1A1A" },
+  { "movsuw",  14,24,  0x0dae, "1A1A" },
+  { "movsud",  14,24,  0x0fae, "1A1A" },
+  { "movusb",  14,24,  0x1cae, "1A1A" },
+  { "movusw",  14,24,  0x1dae, "1A1A" },
+  { "movusd",  14,24,  0x1fae, "1A1A" },
+  { "movxbd",  14,24,  0x1cce, "1B2D" },
+  { "movxwd",  14,24,  0x1dce, "1W2D" },
+  { "movxbw",  14,24,  0x10ce, "1B2W" },
+  { "movzbd",  14,24,  0x18ce, "1B2D" },
+  { "movzwd",  14,24,  0x19ce, "1W2D" },
+  { "movzbw",  14,24,  0x14ce, "1B2W" },
+  { "mulf",    14,24,  0x31be, "1F2F" },
+  { "mull",    14,24,  0x30be, "1L2L" },
+  { "mulb",    14,24,  0x20ce, "1B2B" },
+  { "mulw",    14,24,  0x21ce, "1W2W" },
+  { "muld",    14,24,  0x23ce, "1D2D" },
+  { "negf",    14,24,  0x15be, "1F2F" },
+  { "negl",    14,24,  0x14be, "1L2L" },
+  { "negb",    14,24,  0x204e, "1B2B" },
+  { "negw",    14,24,  0x214e, "1W2W" },
+  { "negd",    14,24,  0x234e, "1D2D" },
+  { "nop",      8,8,   0xa2,   "" },
+  { "notb",    14,24,  0x244e, "1B2B" },
+  { "notw",    14,24,  0x254e, "1W2W" },
+  { "notd",    14,24,  0x274e, "1D2D" },
+  { "orb",      6,16,  0x18,   "1B1B" },
+  { "orw",      6,16,  0x19,   "1W1W" },
+  { "ord",      6,16,  0x1b,   "1D2D" },
+  { "quob",    14,24,  0x30ce, "1B2B" },
+  { "quow",    14,24,  0x31ce, "1W2W" },
+  { "quod",    14,24,  0x33ce, "1D2D" },
+  { "rdval",   19,24,  0x0031e,"1A" },
+  { "remb",    14,24,  0x34ce, "1B2B" },
+  { "remw",    14,24,  0x35ce, "1W2W" },
+  { "remd",    14,24,  0x37ce, "1D2D" },
+  { "restore",  8,8,   0x72,   "1i" },
+  { "ret",      8,8,   0x12,   "1d" },
+  { "reti",     8,8,   0x52,   "" },
+  { "rett",     8,8,   0x42,   "" },
+  { "rotb",    14,24,  0x004e, "1B2B" },
+  { "rotw",    14,24,  0x014e, "1B2W" },
+  { "rotd",    14,24,  0x034e, "1B2D" },
+  { "roundfb", 14,24,  0x243e, "1F2B" },
+  { "roundfw", 14,24,  0x253e, "1F2W" },
+  { "roundfd", 14,24,  0x273e, "1F2D" },
+  { "roundlb", 14,24,  0x203e, "1L2B" },
+  { "roundlw", 14,24,  0x213e, "1L2W" },
+  { "roundld", 14,24,  0x233e, "1L2D" },
+  { "rxp",      8,8,   0x32,   "1d" },
+  { "sCONDb",   7,16,  0x3c,   "2B1q" },
+  { "sCONDw",   7,16,  0x3d,   "2D1q" },
+  { "sCONDd",   7,16,  0x3f,   "2D1q" },
+  { "save",     8,8,   0x62,   "1i" },
+  { "sbitb",   14,24,  0x184e, "1B2A" },
+  { "sbitw",   14,24,  0x194e, "1W2A" },
+  { "sbitd",   14,24,  0x1b4e, "1D2A" },
+  { "sbitib",  14,24,  0x1c4e, "1B2A" },
+  { "sbitiw",  14,24,  0x1d4e, "1W2A" },
+  { "sbitid",  14,24,  0x1f4e, "1D2A" },
+  { "setcfg",  15,24,  0x0b0e, "5D1q" },
+  { "sfsr",    14,24,  0x673e, "5D1D" },
+  { "skpsb",   16,16,  0x0c0e, "1i" },
+  { "skpsw",   16,16,  0x0d0e, "1i" },
+  { "skpsd",   16,16,  0x0f0e, "1i" },
+  { "skpst",   16,16,  0x8c0e, "1i" },
+  { "smr",     15,24,  0x0f1e, "2D1q" },
+  { "sprb",     7,16,  0x2c,   "2B1q" },
+  { "sprw",     7,16,  0x2d,   "2W1q" },
+  { "sprd",     7,16,  0x2f,   "2D1q" },
+  { "subf",    14,24,  0x11be, "1F2F" },
+  { "subl",    14,24,  0x10be, "1L2L" },
+  { "subb",     6,16,  0x20,   "1B2B" },
+  { "subw",     6,16,  0x21,   "1W2W" },
+  { "subd",     6,16,  0x23,   "1D2D" },
+  { "subcb",    6,16,  0x30,   "1B2B" },
+  { "subcw",    6,16,  0x31,   "1W2W" },
+  { "subcd",    6,16,  0x33,   "1D2D" },
+  { "subpb",   14,24,  0x2c4e, "1B2B" },
+  { "subpw",   14,24,  0x2d4e, "1W2W" },
+  { "subpd",   14,24,  0x2f4e, "1D2D" },
+#ifndef NS32K_SVC_IMMED_OPERANDS
+  { "svc",      8,8,   0xe2,   "2i1i" }, /* not really, but unix uses it */
+#else
+  { "svc",      8,8,   0xe2,   "" }, /* not really, but unix uses it */
+#endif
+  { "tbitb",    6,16,  0x34,   "1B2A" },
+  { "tbitw",    6,16,  0x35,   "1W2A" },
+  { "tbitd",    6,16,  0x37,   "1D2A" },
+  { "truncfb", 14,24,  0x2c3e, "1F2B" },
+  { "truncfw", 14,24,  0x2d3e, "1F2W" },
+  { "truncfd", 14,24,  0x2f3e, "1F2D" },
+  { "trunclb", 14,24,  0x283e, "1L2B" },
+  { "trunclw", 14,24,  0x293e, "1L2W" },
+  { "truncld", 14,24,  0x2b3e, "1L2D" },
+  { "wait",     8,8,   0xb2,   "" },
+  { "wrval",   19,24,  0x0071e,"1A" },
+  { "xorb",     6,16,  0x38,   "1B2B" },
+  { "xorw",     6,16,  0x39,   "1W2W" },
+  { "xord",     6,16,  0x3b,   "1D2D" },
+};                             /* notstrs */
+
+/* end: ns32k.opcode.h */
+
+#define MAX_ARGS 4
+#define ARG_LEN 50
diff --git a/gdb/ns32k-pinsn.c b/gdb/ns32k-pinsn.c
new file mode 100644 (file)
index 0000000..1c558e9
--- /dev/null
@@ -0,0 +1,523 @@
+/* Print 32000 instructions for GDB, the GNU debugger.
+   Copyright (C) 1986,1988 Free Software Foundation, Inc.
+
+GDB is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY.  No author or distributor accepts responsibility to anyone
+for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing.
+Refer to the GDB General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute GDB,
+but only under the conditions described in the GDB General Public
+License.  A copy of this license is supposed to have been given to you
+along with GDB so you can know your rights and responsibilities.  It
+should be in a file named COPYING.  Among other things, the copyright
+notice and this notice must be preserved on all copies.
+
+In other words, go ahead and share GDB, but don't try to stop
+anyone else from sharing it farther.  Help stamp out software hoarding!
+*/
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "ns32k-opcode.h"
+#include "gdbcore.h"
+
+/* 32000 instructions are never longer than this.  */
+#define MAXLEN 62
+
+/* Number of elements in the opcode table.  */
+#define NOPCODES (sizeof notstrs / sizeof notstrs[0])
+
+extern char *reg_names[];
+
+#define NEXT_IS_ADDR   '|'
+
+/*
+ * extract "count" bits starting "offset" bits
+ * into buffer
+ */
+
+int
+bit_extract (buffer, offset, count)
+     char *buffer;
+     int offset;
+     int count;
+{
+  int result;
+  int mask;
+  int bit;
+
+  buffer += offset >> 3;
+  offset &= 7;
+  bit = 1;
+  result = 0;
+  while (count--) 
+    {
+      if ((*buffer & (1 << offset)))
+       result |= bit;
+      if (++offset == 8)
+       {
+         offset = 0;
+         buffer++;
+       }
+      bit <<= 1;
+    }
+  return result;
+}
+
+float
+fbit_extract (buffer, offset, count)
+{
+  union {
+    int ival;
+    float fval;
+  } foo;
+
+  foo.ival = bit_extract (buffer, offset, 32);
+  return foo.fval;
+}
+
+double
+dbit_extract (buffer, offset, count)
+{
+  union {
+    struct {int low, high; } ival;
+    double dval;
+  } foo;
+
+  foo.ival.low = bit_extract (buffer, offset, 32);
+  foo.ival.high = bit_extract (buffer, offset+32, 32);
+  return foo.dval;
+}
+
+sign_extend (value, bits)
+{
+  value = value & ((1 << bits) - 1);
+  return (value & (1 << (bits-1))
+         ? value | (~((1 << bits) - 1))
+         : value);
+}
+
+flip_bytes (ptr, count)
+     char *ptr;
+     int count;
+{
+  char tmp;
+
+  while (count > 0)
+    {
+      tmp = *ptr;
+      ptr[0] = ptr[count-1];
+      ptr[count-1] = tmp;
+      ptr++;
+      count -= 2;
+    }
+}
+\f
+/* Given a character C, does it represent a general addressing mode?  */
+#define Is_gen(c) \
+  ((c) == 'F' || (c) == 'L' || (c) == 'B' \
+   || (c) == 'W' || (c) == 'D' || (c) == 'A')
+
+/* Adressing modes.  */
+#define Adrmod_index_byte 0x1c
+#define Adrmod_index_word 0x1d
+#define Adrmod_index_doubleword 0x1e
+#define Adrmod_index_quadword 0x1f
+
+/* Is MODE an indexed addressing mode?  */
+#define Adrmod_is_index(mode) \
+  (mode == Adrmod_index_byte \
+   || mode == Adrmod_index_word \
+   || mode == Adrmod_index_doubleword \
+   || mode == Adrmod_index_quadword)
+
+\f
+/* Print the 32000 instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  register int i;
+  register unsigned char *p;
+  register char *d;
+  unsigned short first_word;
+  int gen, disp;
+  int ioffset;         /* bits into instruction */
+  int aoffset;         /* bits into arguments */
+  char arg_bufs[MAX_ARGS+1][ARG_LEN];
+  int argnum;
+  int maxarg;
+
+  read_memory (memaddr, buffer, MAXLEN);
+
+  first_word = *(unsigned short *) buffer;
+  for (i = 0; i < NOPCODES; i++)
+    if ((first_word & ((1 << notstrs[i].detail.obits) - 1))
+       == notstrs[i].detail.code)
+      break;
+
+  /* Handle undefined instructions.  */
+  if (i == NOPCODES)
+    {
+      fprintf (stream, "0%o", buffer[0]);
+      return 1;
+    }
+
+  fprintf (stream, "%s", notstrs[i].name);
+
+  ioffset = notstrs[i].detail.ibits;
+  aoffset = notstrs[i].detail.ibits;
+  d = notstrs[i].detail.args;
+
+  if (*d)
+    {
+      /* Offset in bits of the first thing beyond each index byte.
+        Element 0 is for operand A and element 1 is for operand B.
+        The rest are irrelevant, but we put them here so we don't
+        index outside the array.  */
+      int index_offset[MAX_ARGS];
+
+      /* 0 for operand A, 1 for operand B, greater for other args.  */
+      int whicharg = 0;
+      
+      fputc ('\t', stream);
+
+      maxarg = 0;
+
+      /* First we have to find and keep track of the index bytes,
+        if we are using scaled indexed addressing mode, since the index
+        bytes occur right after the basic instruction, not as part
+        of the addressing extension.  */
+      if (Is_gen(d[1]))
+       {
+         int addr_mode = bit_extract (buffer, ioffset - 5, 5);
+
+         if (Adrmod_is_index (addr_mode))
+           {
+             aoffset += 8;
+             index_offset[0] = aoffset;
+           }
+       }
+      if (d[2] && Is_gen(d[3]))
+       {
+         int addr_mode = bit_extract (buffer, ioffset - 10, 5);
+
+         if (Adrmod_is_index (addr_mode))
+           {
+             aoffset += 8;
+             index_offset[1] = aoffset;
+           }
+       }
+
+      while (*d)
+       {
+         argnum = *d - '1';
+         d++;
+         if (argnum > maxarg && argnum < MAX_ARGS)
+           maxarg = argnum;
+         ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
+                                   memaddr, arg_bufs[argnum],
+                                   index_offset[whicharg]);
+         d++;
+         whicharg++;
+       }
+      for (argnum = 0; argnum <= maxarg; argnum++)
+       {
+         CORE_ADDR addr;
+         char *ch, *index ();
+         for (ch = arg_bufs[argnum]; *ch;)
+           {
+             if (*ch == NEXT_IS_ADDR)
+               {
+                 ++ch;
+                 addr = atoi (ch);
+                 print_address (addr, stream);
+                 while (*ch && *ch != NEXT_IS_ADDR)
+                   ++ch;
+                 if (*ch)
+                   ++ch;
+               }
+             else
+               putc (*ch++, stream);
+           }
+         if (argnum < maxarg)
+           fprintf (stream, ", ");
+       }
+    }
+  return aoffset / 8;
+}
+
+/* Print an instruction operand of category given by d.  IOFFSET is
+   the bit position below which small (<1 byte) parts of the operand can
+   be found (usually in the basic instruction, but for indexed
+   addressing it can be in the index byte).  AOFFSETP is a pointer to the
+   bit position of the addressing extension.  BUFFER contains the
+   instruction.  ADDR is where BUFFER was read from.  Put the disassembled
+   version of the operand in RESULT.  INDEX_OFFSET is the bit position
+   of the index byte (it contains garbage if this operand is not a
+   general operand using scaled indexed addressing mode).  */
+
+print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
+     char d;
+     int ioffset, *aoffsetp;
+     char *buffer;
+     CORE_ADDR addr;
+     char *result;
+     int index_offset;
+{
+  int addr_mode;
+  float Fvalue;
+  double Lvalue;
+  int Ivalue;
+  int disp1, disp2;
+  int index;
+
+  switch (d)
+    {
+    case 'F':
+    case 'L':
+    case 'B':
+    case 'W':
+    case 'D':
+    case 'A':
+      addr_mode = bit_extract (buffer, ioffset-5, 5);
+      ioffset -= 5;
+      switch (addr_mode)
+       {
+       case 0x0: case 0x1: case 0x2: case 0x3:
+       case 0x4: case 0x5: case 0x6: case 0x7:
+         switch (d)
+           {
+           case 'F':
+           case 'L':
+             sprintf (result, "f%d", addr_mode);
+             break;
+           default:
+             sprintf (result, "r%d", addr_mode);
+           }
+         break;
+       case 0x8: case 0x9: case 0xa: case 0xb:
+       case 0xc: case 0xd: case 0xe: case 0xf:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
+         break;
+       case 0x10:
+       case 0x11:
+       case 0x12:
+         disp1 = get_displacement (buffer, aoffsetp);
+         disp2 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "%d(%d(%s))", disp2, disp1,
+                  addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
+         break;
+       case 0x13:
+         sprintf (result, "reserved");
+         break;
+       case 0x14:
+         switch (d)
+           {
+           case 'B':
+             Ivalue = bit_extract (buffer, *aoffsetp, 8);
+             Ivalue = sign_extend (Ivalue, 8);
+             *aoffsetp += 8;
+             sprintf (result, "$%d", Ivalue);
+             break;
+           case 'W':
+             Ivalue = bit_extract (buffer, *aoffsetp, 16);
+             flip_bytes (&Ivalue, 2);
+             *aoffsetp += 16;
+             Ivalue = sign_extend (Ivalue, 16);
+             sprintf (result, "$%d", Ivalue);
+             break;
+           case 'D':
+             Ivalue = bit_extract (buffer, *aoffsetp, 32);
+             flip_bytes (&Ivalue, 4);
+             *aoffsetp += 32;
+             sprintf (result, "$%d", Ivalue);
+             break;
+           case 'A':
+             Ivalue = bit_extract (buffer, *aoffsetp, 32);
+             flip_bytes (&Ivalue, 4);
+             *aoffsetp += 32;
+             sprintf (result, "$|%d|", Ivalue);
+             break;
+           case 'F':
+             Fvalue = fbit_extract (buffer, *aoffsetp, 32);
+             flip_bytes (&Fvalue, 4);
+             *aoffsetp += 32;
+             sprintf (result, "$%g", Fvalue);
+             break;
+           case 'L':
+             Lvalue = dbit_extract (buffer, *aoffsetp, 64);
+             flip_bytes (&Lvalue, 8);
+             *aoffsetp += 64;
+             sprintf (result, "$%g", Lvalue);
+             break;
+           }
+         break;
+       case 0x15:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "@|%d|", disp1);
+         break;
+       case 0x16:
+         disp1 = get_displacement (buffer, aoffsetp);
+         disp2 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "EXT(%d) + %d", disp1, disp2);
+         break;
+       case 0x17:
+         sprintf (result, "tos");
+         break;
+       case 0x18:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "%d(fp)", disp1);
+         break;
+       case 0x19:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "%d(sp)", disp1);
+         break;
+       case 0x1a:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "%d(sb)", disp1);
+         break;
+       case 0x1b:
+         disp1 = get_displacement (buffer, aoffsetp);
+         sprintf (result, "|%d|", addr + disp1);
+         break;
+       case 0x1c:
+       case 0x1d:
+       case 0x1e:
+       case 0x1f:
+         index = bit_extract (buffer, index_offset - 8, 3);
+         print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
+                         result, 0);
+         {
+           static char *ind[] = {"b", "w", "d", "q"};
+           char *off;
+
+           off = result + strlen (result);
+           sprintf (off, "[r%d:%s]", index,
+                    ind[addr_mode & 3]);
+         }
+         break;
+       }
+      break;
+    case 'q':
+      Ivalue = bit_extract (buffer, ioffset-4, 4);
+      Ivalue = sign_extend (Ivalue, 4);
+      sprintf (result, "%d", Ivalue);
+      ioffset -= 4;
+      break;
+    case 'r':
+      Ivalue = bit_extract (buffer, ioffset-3, 3);
+      sprintf (result, "r%d", Ivalue&7);
+      ioffset -= 3;
+      break;
+    case 'd':
+      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
+      break;
+    case 'p':
+      sprintf (result, "%c%d%c", NEXT_IS_ADDR,
+              addr + get_displacement (buffer, aoffsetp),
+              NEXT_IS_ADDR);
+      break;
+    case 'i':
+      Ivalue = bit_extract (buffer, *aoffsetp, 8);
+      *aoffsetp += 8;
+      sprintf (result, "0x%x", Ivalue);
+      break;
+    }
+  return ioffset;
+}
+
+get_displacement (buffer, aoffsetp)
+     char *buffer;
+     int *aoffsetp;
+{
+  int Ivalue;
+
+  Ivalue = bit_extract (buffer, *aoffsetp, 8);
+  switch (Ivalue & 0xc0)
+    {
+    case 0x00:
+    case 0x40:
+      Ivalue = sign_extend (Ivalue, 7);
+      *aoffsetp += 8;
+      break;
+    case 0x80:
+      Ivalue = bit_extract (buffer, *aoffsetp, 16);
+      flip_bytes (&Ivalue, 2);
+      Ivalue = sign_extend (Ivalue, 14);
+      *aoffsetp += 16;
+      break;
+    case 0xc0:
+      Ivalue = bit_extract (buffer, *aoffsetp, 32);
+      flip_bytes (&Ivalue, 4);
+      Ivalue = sign_extend (Ivalue, 30);
+      *aoffsetp += 32;
+      break;
+    }
+  return Ivalue;
+}
+\f
+/* Return the number of locals in the current frame given a pc
+   pointing to the enter instruction.  This is used in the macro
+   FRAME_FIND_SAVED_REGS.  */
+
+ns32k_localcount (enter_pc)
+     CORE_ADDR enter_pc;
+{
+  unsigned char localtype;
+  int localcount;
+
+  localtype = read_memory_integer (enter_pc+2, 1);
+  if ((localtype & 0x80) == 0)
+    localcount = localtype;
+  else if ((localtype & 0xc0) == 0x80)
+    localcount = (((localtype & 0x3f) << 8)
+                 | (read_memory_integer (enter_pc+3, 1) & 0xff));
+  else
+    localcount = (((localtype & 0x3f) << 24)
+                 | ((read_memory_integer (enter_pc+3, 1) & 0xff) << 16)
+                 | ((read_memory_integer (enter_pc+4, 1) & 0xff) << 8 )
+                 | (read_memory_integer (enter_pc+5, 1) & 0xff));
+  return localcount;
+}
+
+/*
+ * Get the address of the enter opcode for the function
+ * containing PC, if there is an enter for the function,
+ * and if the pc is between the enter and exit.
+ * Returns positive address if pc is between enter/exit,
+ * 1 if pc before enter or after exit, 0 otherwise.
+ */
+
+CORE_ADDR
+ns32k_get_enter_addr (pc)
+     CORE_ADDR pc;
+{
+  CORE_ADDR enter_addr;
+  unsigned char op;
+
+  if (ABOUT_TO_RETURN (pc))
+    return 1;          /* after exit */
+
+  enter_addr = get_pc_function_start (pc);
+
+  if (pc == enter_addr) 
+    return 1;          /* before enter */
+
+  op = read_memory_integer (enter_addr, 1);
+
+  if (op != 0x82)
+    return 0;          /* function has no enter/exit */
+
+  return enter_addr;   /* pc is between enter and exit */
+}
diff --git a/gdb/obstack.c b/gdb/obstack.c
new file mode 100755 (executable)
index 0000000..590fcaa
--- /dev/null
@@ -0,0 +1,333 @@
+/* obstack.c - subroutines used implicitly by object stack macros
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 1, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "obstack.h"
+
+#ifdef __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment.  */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+   But in fact it might be less smart and round addresses to as much as
+   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+   On some machines, copying successive ints does not work;
+   in such a case, redefine COPYING_UNIT to `long' (if that works)
+   or `char' as a last resort.  */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+/* The non-GNU-C macros copy the obstack into this global variable
+   to avoid multiple evaluation.  */
+
+struct obstack *_obstack;
+\f
+/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
+   Objects start on multiples of ALIGNMENT (0 means use default).
+   CHUNKFUN is the function to use to allocate chunks,
+   and FREEFUN the function to free them.  */
+
+void
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+     struct obstack *h;
+     int size;
+     int alignment;
+     POINTER (*chunkfun) ();
+     void (*freefun) ();
+{
+  register struct _obstack_chunk* chunk; /* points to new chunk */
+
+  if (alignment == 0)
+    alignment = DEFAULT_ALIGNMENT;
+  if (size == 0)
+    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
+    {
+      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+        Use the values for range checking, because if range checking is off,
+        the extra bytes won't be missed terribly, but if range checking is on
+        and we used a larger request, a whole extra 4096 bytes would be
+        allocated.
+
+        These number are irrelevant to the new GNU malloc.  I suspect it is
+        less sensitive to the size of the request.  */
+      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+                   + 4 + DEFAULT_ROUNDING - 1)
+                  & ~(DEFAULT_ROUNDING - 1));
+      size = 4096 - extra;
+    }
+
+  h->chunkfun = chunkfun;
+  h->freefun = freefun;
+  h->chunk_size = size;
+  h->alignment_mask = alignment - 1;
+
+  chunk        = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (h->chunk_size);
+  h->next_free = h->object_base = chunk->contents;
+  h->chunk_limit = chunk->limit
+   = (char *) chunk + h->chunk_size;
+  chunk->prev = 0;
+}
+
+/* Allocate a new current chunk for the obstack *H
+   on the assumption that LENGTH bytes need to be added
+   to the current object, or a new object of length LENGTH allocated.
+   Copies any partial object from the end of the old chunk
+   to the beginning of the new one.  
+
+   The function must be "int" so it can be used in non-ANSI C
+   compilers in a : expression.  */
+
+int
+_obstack_newchunk (h, length)
+     struct obstack *h;
+     int length;
+{
+  register struct _obstack_chunk*      old_chunk = h->chunk;
+  register struct _obstack_chunk*      new_chunk;
+  register long        new_size;
+  register int obj_size = h->next_free - h->object_base;
+  register int i;
+  int already;
+
+  /* Compute size for new chunk.  */
+  new_size = (obj_size + length) + (obj_size >> 3) + 100;
+  if (new_size < h->chunk_size)
+    new_size = h->chunk_size;
+
+  /* Allocate and initialize the new chunk.  */
+  new_chunk = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (new_size);
+  new_chunk->prev = old_chunk;
+  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+  /* Move the existing object to the new chunk.
+     Word at a time is fast and is safe if the object
+     is sufficiently aligned.  */
+  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+    {
+      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+          i >= 0; i--)
+       ((COPYING_UNIT *)new_chunk->contents)[i]
+         = ((COPYING_UNIT *)h->object_base)[i];
+      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+        but that can cross a page boundary on a machine
+        which does not do strict alignment for COPYING_UNITS.  */
+      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+    }
+  else
+    already = 0;
+  /* Copy remaining bytes one by one.  */
+  for (i = already; i < obj_size; i++)
+    new_chunk->contents[i] = h->object_base[i];
+
+  h->object_base = new_chunk->contents;
+  h->next_free = h->object_base + obj_size;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+   This is here for debugging.
+   If you use it in a program, you are probably losing.  */
+
+int
+_obstack_allocated_p (h, obj)
+     struct obstack *h;
+     POINTER obj;
+{
+  register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
+  register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
+
+  lp = (h)->chunk;
+  while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj))
+    {
+      plp = lp -> prev;
+      lp = plp;
+    }
+  return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+   more recently than OBJ.  If OBJ is zero, free everything in H.  */
+
+#ifdef __STDC__
+#undef obstack_free
+void
+obstack_free (struct obstack *h, POINTER obj)
+#else
+int
+_obstack_free (h, obj)
+     struct obstack *h;
+     POINTER obj;
+#endif
+{
+  register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
+  register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
+
+  lp = (h)->chunk;
+  /* We use >= because there cannot be an object at the beginning of a chunk.
+     But there can be an empty object at that address
+     at the end of another chunk.  */
+  while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+    {
+      plp = lp -> prev;
+      (*h->freefun) ((POINTER) lp);
+      lp = plp;
+    }
+  if (lp)
+    {
+      (h)->object_base = (h)->next_free = (char *)(obj);
+      (h)->chunk_limit = lp->limit;
+      (h)->chunk = lp;
+    }
+  else if (obj != 0)
+    /* obj is not in any of the chunks! */
+    abort ();
+}
+
+/* Let same .o link with output of gcc and other compilers.  */
+
+#ifdef __STDC__
+int
+_obstack_free (h, obj)
+     struct obstack *h;
+     POINTER obj;
+{
+  obstack_free (h, obj);
+}
+#endif
+\f
+/* #if 0 */
+/* These are now turned off because the applications do not use it
+   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
+
+/* Now define the functional versions of the obstack macros.
+   Define them to simply use the corresponding macros to do the job.  */
+
+#ifdef __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+   they won't pass through the macro names in parentheses.  */
+
+/* The function names appear in parentheses in order to prevent
+   the macro-definitions of the names from being expanded there.  */
+
+POINTER (obstack_base) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_room (obstack);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+     struct obstack *obstack;
+     int character;
+{
+  obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+     struct obstack *obstack;
+     int character;
+{
+  obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+     struct obstack *obstack;
+{
+  return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+     struct obstack *obstack;
+     int length;
+{
+  return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+     struct obstack *obstack;
+     POINTER pointer;
+     int length;
+{
+  return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+/* #endif 0 */
diff --git a/gdb/obstack.h b/gdb/obstack.h
new file mode 100755 (executable)
index 0000000..2e80c9c
--- /dev/null
@@ -0,0 +1,416 @@
+/* obstack.h - object stack macros
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 1, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects.  Each object starts life
+small, and may grow to maturity.  (Consider building a word syllable
+by syllable.)  An object can move while it is growing.  Once it has
+been "finished" it never changes address again.  So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
+by calling `obstack_chunk_free'.  You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables.  Unless you are "fascist pig with a read-only mind"
+[Gosper's immortal quote from HAKMEM item 154, out of context] you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols.  At the time you are reading a symbol you don't know
+how long it is.  One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer.  This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently.  Use one obstack for all symbol
+names.  As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it.  Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses.  When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk.  When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies.  No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk.  We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object.  This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+       We allocate large chunks.
+       We carve out one object at a time from the current chunk.
+       Once carved, an object never moves.
+       We are free to append data of any size to the currently
+         growing object.
+       Exactly one object is growing in an obstack at any one time.
+       You can run one obstack per control block.
+       You may have as many control blocks as you dare.
+       Because of the way we do it, you can `unwind' a obstack
+         back to a previous state. (You may remove objects much
+         as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once.  */
+
+#ifndef __OBSTACKS__
+#define __OBSTACKS__
+\f
+/* We use subtraction of (char *)0 instead of casting to int
+   because on word-addressable machines a simple cast to int
+   may ignore the byte-within-word field of the pointer.  */
+
+#ifndef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((P) - (char *)0)
+#endif
+
+#ifndef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((P) + (char *)0)
+#endif
+
+struct _obstack_chunk          /* Lives at front of each chunk. */
+{
+  char  *limit;                        /* 1 past end of this chunk */
+  struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+  char contents[4];            /* objects begin here */
+};
+
+struct obstack         /* control current object in current chunk */
+{
+  long chunk_size;             /* preferred size to allocate chunks in */
+  struct _obstack_chunk* chunk;        /* address of current struct obstack_chunk */
+  char *object_base;           /* address of object we are building */
+  char *next_free;             /* where to add next char to current object */
+  char *chunk_limit;           /* address of char after current chunk */
+  int  temp;                   /* Temporary for some macros.  */
+  int   alignment_mask;                /* Mask of alignment for each object. */
+#ifdef __STDC__
+  void  *(*chunkfun) ();       /* User's fcn to allocate a chunk.  */
+#else
+  char  *(*chunkfun) ();       /* User's fcn to allocate a chunk.  */
+#endif
+  void (*freefun) ();          /* User's function to free a chunk.  */
+};
+\f
+#ifdef __STDC__
+
+/* Do the function-declarations after the structs
+   but before defining the macros.  */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+void obstack_ptr_grow (struct obstack *obstack, void *data);
+void obstack_int_grow (struct obstack *obstack, int data);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+void obstack_int_grow_fast (struct obstack *obstack, int data);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+   so we do not declare them.  */
+\f
+/* Pointer to beginning of object being allocated or to be allocated next.
+   Note that this might not be the final address of the object
+   because a new chunk might be needed to hold the final size.  */
+
+#define obstack_base(h) ((h)->object_base)
+
+/* Size for allocating ordinary chunks.  */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk.  */
+
+#define obstack_next_free(h)   ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object.  */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+#define obstack_init(h) \
+  _obstack_begin ((h), 0, 0, obstack_chunk_alloc, obstack_chunk_free)
+
+#define obstack_begin(h, size) \
+  _obstack_begin ((h), (size), 0, obstack_chunk_alloc, obstack_chunk_free)
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+\f
+#if defined (__GNUC__) && defined (__STDC__)
+
+/* For GNU C, if not -traditional,
+   we can define these macros to compute all args only once
+   without using a global variable.
+   Also, we can avoid using the `temp' slot, to make faster code.  */
+
+#define obstack_object_size(OBSTACK)                                   \
+  ({ struct obstack *__o = (OBSTACK);                                  \
+     (unsigned) (__o->next_free - __o->object_base); })
+
+#define obstack_room(OBSTACK)                                          \
+  ({ struct obstack *__o = (OBSTACK);                                  \
+     (unsigned) (__o->chunk_limit - __o->next_free); })
+
+#define obstack_grow(OBSTACK,where,length)                             \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->next_free + __len > __o->chunk_limit)                                \
+    ? _obstack_newchunk (__o, __len) : 0);                             \
+   bcopy (where, __o->next_free, __len);                               \
+   __o->next_free += __len;                                            \
+   (void) 0; })
+
+#define obstack_grow0(OBSTACK,where,length)                            \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->next_free + __len + 1 > __o->chunk_limit)                    \
+    ? _obstack_newchunk (__o, __len + 1) : 0),                         \
+   bcopy (where, __o->next_free, __len),                               \
+   __o->next_free += __len,                                            \
+   *(__o->next_free)++ = 0;                                            \
+   (void) 0; })
+
+#define obstack_1grow(OBSTACK,datum)                                   \
+({ struct obstack *__o = (OBSTACK);                                    \
+   ((__o->next_free + 1 > __o->chunk_limit)                            \
+    ? _obstack_newchunk (__o, 1) : 0),                                 \
+   *(__o->next_free)++ = (datum);                                      \
+   (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers or ints,
+   and that the data added so far to the current object
+   shares that much alignment.  */
+   
+#define obstack_ptr_grow(OBSTACK,datum)                                        \
+({ struct obstack *__o = (OBSTACK);                                    \
+   ((__o->next_free + sizeof (void *) > __o->chunk_limit)              \
+    ? _obstack_newchunk (__o, sizeof (void *)) : 0),                   \
+   *(*(void ***)&__o->next_free)++ = ((void *)datum);                  \
+   (void) 0; })
+
+#define obstack_int_grow(OBSTACK,datum)                                        \
+({ struct obstack *__o = (OBSTACK);                                    \
+   ((__o->next_free + sizeof (int) > __o->chunk_limit)                 \
+    ? _obstack_newchunk (__o, sizeof (int)) : 0),                      \
+   *(*(int **)&__o->next_free)++ = ((int)datum);                               \
+   (void) 0; })
+
+#define obstack_ptr_grow_fast(h,aptr) (*(*(void ***)&(h)->next_free)++ = (void *)aptr)
+#define obstack_int_grow_fast(h,aint) (*(*(int **)&(h)->next_free)++ = (int)aint)
+
+#define obstack_blank(OBSTACK,length)                                  \
+({ struct obstack *__o = (OBSTACK);                                    \
+   int __len = (length);                                               \
+   ((__o->chunk_limit - __o->next_free < __len)                                \
+    ? _obstack_newchunk (__o, __len) : 0);                             \
+   __o->next_free += __len;                                            \
+   (void) 0; })
+
+#define obstack_alloc(OBSTACK,length)                                  \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_blank (__h, (length));                                      \
+   obstack_finish (__h); })
+
+#define obstack_copy(OBSTACK,where,length)                             \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_grow (__h, (where), (length));                              \
+   obstack_finish (__h); })
+
+#define obstack_copy0(OBSTACK,where,length)                            \
+({ struct obstack *__h = (OBSTACK);                                    \
+   obstack_grow0 (__h, (where), (length));                             \
+   obstack_finish (__h); })
+
+#define obstack_finish(OBSTACK)                                        \
+({ struct obstack *__o = (OBSTACK);                                    \
+   void *value = (void *) __o->object_base;                            \
+   __o->next_free                                                      \
+     = __INT_TO_PTR ((__PTR_TO_INT (__o->next_free)+__o->alignment_mask)\
+                    & ~ (__o->alignment_mask));                        \
+   ((__o->next_free - (char *)__o->chunk                               \
+     > __o->chunk_limit - (char *)__o->chunk)                          \
+    ? (__o->next_free = __o->chunk_limit) : 0);                                \
+   __o->object_base = __o->next_free;                                  \
+   value; })
+
+#define obstack_free(OBSTACK, OBJ)                                     \
+({ struct obstack *__o = (OBSTACK);                                    \
+   void *__obj = (OBJ);                                                        \
+   if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
+     __o->next_free = __o->object_base = __obj;                                \
+   else (obstack_free) (__o, __obj); })
+\f
+#else /* not __GNUC__ or not __STDC__ */
+
+#define obstack_object_size(h) \
+ (unsigned) ((h)->next_free - (h)->object_base)
+
+#define obstack_room(h)                \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+#define obstack_grow(h,where,length)                                   \
+( (h)->temp = (length),                                                        \
+  (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
+   ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
+  bcopy (where, (h)->next_free, (h)->temp),                            \
+  (h)->next_free += (h)->temp)
+
+#define obstack_grow0(h,where,length)                                  \
+( (h)->temp = (length),                                                        \
+  (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)                 \
+   ? _obstack_newchunk ((h), (h)->temp + 1) : 0),                      \
+  bcopy (where, (h)->next_free, (h)->temp),                            \
+  (h)->next_free += (h)->temp,                                         \
+  *((h)->next_free)++ = 0)
+
+#define obstack_1grow(h,datum)                                         \
+( (((h)->next_free + 1 > (h)->chunk_limit)                             \
+   ? _obstack_newchunk ((h), 1) : 0),                                  \
+  *((h)->next_free)++ = (datum))
+
+#define obstack_ptr_grow(h,datum)                                      \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)               \
+   ? _obstack_newchunk ((h), sizeof (char *)) : 0),                    \
+  *(*(char ***)&(h)->next_free)++ = ((char *)datum))
+
+#define obstack_int_grow(h,datum)                                      \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit)                  \
+   ? _obstack_newchunk ((h), sizeof (int)) : 0),                       \
+  *(*(int **)&(h)->next_free)++ = ((int)datum))
+
+#define obstack_ptr_grow_fast(h,aptr) (*(*(char ***)&(h)->next_free)++ = (char *)aptr)
+#define obstack_int_grow_fast(h,aint) (*(*(int **)&(h)->next_free)++ = (int)aint)
+
+#define obstack_blank(h,length)                                                \
+( (h)->temp = (length),                                                        \
+  (((h)->chunk_limit - (h)->next_free < (h)->temp)                     \
+   ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
+  (h)->next_free += (h)->temp)
+
+#define obstack_alloc(h,length)                                                \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+#define obstack_copy(h,where,length)                                   \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_copy0(h,where,length)                                  \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_finish(h)                                              \
+( (h)->temp = __PTR_TO_INT ((h)->object_base),                         \
+  (h)->next_free                                                       \
+    = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)        \
+                   & ~ ((h)->alignment_mask)),                         \
+  (((h)->next_free - (char *)(h)->chunk                                        \
+    > (h)->chunk_limit - (char *)(h)->chunk)                           \
+   ? ((h)->next_free = (h)->chunk_limit) : 0),                         \
+  (h)->object_base = (h)->next_free,                                   \
+  __INT_TO_PTR ((h)->temp))
+
+#ifdef __STDC__
+#define obstack_free(h,obj)                                            \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
+  (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+   ? (int) ((h)->next_free = (h)->object_base                          \
+           = (h)->temp + (char *) (h)->chunk)                          \
+   : ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0)))
+#else
+#define obstack_free(h,obj)                                            \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
+  (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+   ? (int) ((h)->next_free = (h)->object_base                          \
+           = (h)->temp + (char *) (h)->chunk)                          \
+   : (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk)))
+#endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+/* Declare the external functions we use; they are in obstack.c.  */
+
+#ifdef __STDC__
+  extern int _obstack_newchunk (struct obstack *h, int length);
+  extern int _obstack_free (struct obstack *h, void *obj);
+  extern void _obstack_begin (struct obstack *h, int size, int alignment,
+                             void *(*chunkfun) (), void (*freefun) ());
+#else
+  extern int _obstack_newchunk ();
+  extern int _obstack_free ();
+  extern void _obstack_begin ();
+#endif
+
+#endif /* not __OBSTACKS__ */
+
diff --git a/gdb/param-no-tm.h b/gdb/param-no-tm.h
new file mode 100755 (executable)
index 0000000..2e4af53
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (PARAM_H)
+#define PARAM_H 1
+
+/*  DO NOT #include "tm.h" -- a particular tm file has been inc'd by caller  */
+
+#include "xm.h"
+
+/* TARGET_BYTE_ORDER and HOST_BYTE_ORDER should be defined to one of these.  */
+#if !defined (BIG_ENDIAN)
+#define BIG_ENDIAN 4321
+#endif
+
+#if !defined (LITTLE_ENDIAN)
+#define LITTLE_ENDIAN 1234
+#endif
+
+/* The bit byte-order has to do just with numbering of bits in
+   debugging symbols and such.  Conceptually, it's quite separate
+   from byte/word byte order.  */
+
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+#define BITS_BIG_ENDIAN 1
+#endif
+
+#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
+/*#define BITS_BIG_ENDIAN */
+#endif
+
+/* Swap LEN bytes at BUFFER between target and host byte-order.  */
+#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
+#define SWAP_TARGET_AND_HOST(buffer,len)
+#else /* Target and host byte order differ.  */
+#define SWAP_TARGET_AND_HOST(buffer,len) \
+  {                                                                     \
+    char tmp;                                                           \
+    char *p = (char *)(buffer);                                                 \
+    char *q = ((char *)(buffer)) + len - 1;                             \
+    for (; p < q; p++, q--)                                             \
+      {                                                                         \
+        tmp = *q;                                                       \
+        *q = *p;                                                        \
+        *p = tmp;                                                       \
+      }                                                                         \
+  }
+#endif /* Target and host byte order differ.  */
+
+/* On some machines there are bits in addresses which are not really
+   part of the address, but are used by the kernel, the hardware, etc.
+   for special purposes.  ADDR_BITS_REMOVE takes out any such bits
+   so we get a "real" address such as one would find in a symbol
+   table.  ADDR_BITS_SET sets those bits the way the system wants
+   them.  */
+#if !defined (ADDR_BITS_REMOVE)
+#define ADDR_BITS_REMOVE(addr) (addr)
+#define ADDR_BITS_SET(addr) (addr)
+#endif /* No ADDR_BITS_REMOVE.  */
+
+#endif /* param.h not already included.  */
diff --git a/gdb/param.h b/gdb/param.h
new file mode 100755 (executable)
index 0000000..0a56936
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* The standard thing is to include param.h.  However, files that are
+   specific to a particular target can include that tm-xxx.h file and
+   param-no-tm.h.  Any future inclusions of param.h will be protected
+   against by the #if !defined stuff below.  */
+
+#if !defined (PARAM_H)
+#include "tm.h"
+#endif
+
+#include "param-no-tm.h"
+
+#define PARAM_H 1
diff --git a/gdb/pn-opcode.h b/gdb/pn-opcode.h
new file mode 100755 (executable)
index 0000000..fde4764
--- /dev/null
@@ -0,0 +1,282 @@
+/* Print GOULD PN (PowerNode) instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+struct gld_opcode
+{
+  char *name;
+  unsigned long opcode;
+  unsigned long mask;
+  char *args;
+  int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+   is the most any of them need.  The actual length of an instruction
+   is always at least 2 bytes, and at most four.  The length of the
+   instruction is based on the opcode.
+
+   The mask component is a mask saying which bits must match
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing characters
+   that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+   r  Register in first field
+   R  Register in second field
+   b  Base register in first field
+   B  Base register in second field
+   v  Vector register in first field
+   V  Vector register in first field
+   A  Optional address register (base register)
+   X  Optional index register
+   I  Immediate data (16bits signed)
+   O  Offset field (16bits signed)
+   h  Offset field (15bits signed)
+   d  Offset field (14bits signed)
+   S  Shift count field
+
+   any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+   all instances of the same mnemonic must be consecutive.
+   All instances of the same mnemonic with the same number of operands
+   must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "abm",       0xa0080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "abr",       0x18080000,     0xfc0c0000,     "r,f",          2 },
+{ "aci",       0xfc770000,     0xfc7f8000,     "r,I",          4 },
+{ "adfd",      0xe0080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "adfw",      0xe0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adi",       0xc8010000,     0xfc7f0000,     "r,I",          4 },
+{ "admb",      0xb8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "admd",      0xb8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "admh",      0xb8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "admw",      0xb8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "adr",       0x38000000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfd",     0x38090000,     0xfc0f0000,     "r,R",          2 },
+{ "adrfw",     0x38010000,     0xfc0f0000,     "r,R",          2 },
+{ "adrm",      0x38080000,     0xfc0f0000,     "r,R",          2 },
+{ "ai",        0xfc030000,     0xfc07ffff,     "I",            4 },
+{ "anmb",      0x84080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anmd",      0x84000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "anmh",      0x84000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "anmw",      0x84000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "anr",       0x04000000,     0xfc0f0000,     "r,R",          2 },
+{ "armb",      0xe8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "armd",      0xe8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "armh",      0xe8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "armw",      0xe8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "bcf",       0xf0000000,     0xfc080000,     "I,xOA,X",      4 },
+{ "bct",       0xec000000,     0xfc080000,     "I,xOA,X",      4 },
+{ "bei",       0x00060000,     0xffff0000,     "",             2 },
+{ "bft",       0xf0000000,     0xff880000,     "xOA,X",        4 },
+{ "bib",       0xf4000000,     0xfc780000,     "r,xOA",        4 },
+{ "bid",       0xf4600000,     0xfc780000,     "r,xOA",        4 },
+{ "bih",       0xf4200000,     0xfc780000,     "r,xOA",        4 },
+{ "biw",       0xf4400000,     0xfc780000,     "r,xOA",        4 },
+{ "bl",        0xf8800000,     0xff880000,     "xOA,X",        4 },
+{ "bsub",      0x5c080000,     0xff8f0000,     "",             2 },
+{ "bsubm",     0x28080000,     0xfc080000,     "",             4 },
+{ "bu",        0xec000000,     0xff880000,     "xOA,X",        4 },
+{ "call",      0x28080000,     0xfc0f0000,     "",             2 },
+{ "callm",     0x5c080000,     0xff880000,     "",             4 },
+{ "camb",      0x90080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "camd",      0x90000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "camh",      0x90000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "camw",      0x90000000,     0xfc080000,     "r.xOA,X",      4 },
+{ "car",       0x10000000,     0xfc0f0000,     "r,R",          2 },
+{ "cd",        0xfc060000,     0xfc070000,     "r,f",          4 },
+{ "cea",       0x000f0000,     0xffff0000,     "",             2 },
+{ "ci",        0xc8050000,     0xfc7f0000,     "r,I",          4 },
+{ "cmc",       0x040a0000,     0xfc7f0000,     "r",            2 },
+{ "cmmb",      0x94080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "cmmd",      0x94000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "cmmh",      0x94000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "cmmw",      0x94000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "cmr",       0x14000000,     0xfc0f0000,     "r,R",          2 },
+{ "daci",      0xfc7f0000,     0xfc7f8000,     "r,I",          4 },
+{ "dae",       0x000e0000,     0xffff0000,     "",             2 },
+{ "dai",       0xfc040000,     0xfc07ffff,     "I",            4 },
+{ "dci",       0xfc6f0000,     0xfc7f8000,     "r,I",          4 },
+{ "di",        0xfc010000,     0xfc07ffff,     "I",            4 },
+{ "dvfd",      0xe4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "dvfw",      0xe4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvi",       0xc8040000,     0xfc7f0000,     "r,I",          4 },
+{ "dvmb",      0xc4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvmh",      0xc4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "dvmw",      0xc4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "dvr",       0x380a0000,     0xfc0f0000,     "r,R",          2 },
+{ "dvrfd",     0x380c0000,     0xfc0f0000,     "r,R",          4 },
+{ "dvrfw",     0x38040000,     0xfc0f0000,     "r,xOA,X",      4 },
+{ "eae",       0x00080000,     0xffff0000,     "",             2 },
+{ "eci",       0xfc670000,     0xfc7f8080,     "r,I",          4 },
+{ "ecwcs",     0xfc4f0000,     0xfc7f8000,     "",             4 },
+{ "ei",        0xfc000000,     0xfc07ffff,     "I",            4 },
+{ "eomb",      0x8c080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eomd",      0x8c000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "eomh",      0x8c000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "eomw",      0x8c000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "eor",       0x0c000000,     0xfc0f0000,     "r,R",          2 },
+{ "eorm",      0x0c080000,     0xfc0f0000,     "r,R",          2 },
+{ "es",        0x00040000,     0xfc7f0000,     "r",            2 },
+{ "exm",       0xa8000000,     0xff880000,     "xOA,X",        4 },
+{ "exr",       0xc8070000,     0xfc7f0000,     "r",            2 },
+{ "exrr",      0xc8070002,     0xfc7f0002,     "r",            2 },
+{ "fixd",      0x380d0000,     0xfc0f0000,     "r,R",          2 },
+{ "fixw",      0x38050000,     0xfc0f0000,     "r,R",          2 },
+{ "fltd",      0x380f0000,     0xfc0f0000,     "r,R",          2 },
+{ "fltw",      0x38070000,     0xfc0f0000,     "r,R",          2 },
+{ "grio",      0xfc3f0000,     0xfc7f8000,     "r,I",          4 },
+{ "halt",      0x00000000,     0xffff0000,     "",             2 },
+{ "hio",       0xfc370000,     0xfc7f8000,     "r,I",          4 },
+{ "jwcs",      0xfa080000,     0xff880000,     "xOA,X",        4 },
+{ "la",        0x50000000,     0xfc000000,     "r,xOA,X",      4 },
+{ "labr",      0x58080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lb",        0xac080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lcs",       0x00030000,     0xfc7f0000,     "r",            2 },
+{ "ld",        0xac000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lear",      0x80000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lf",        0xcc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lfbr",      0xcc080000,     0xfc080000,     "b,xOA,X",      4 },
+{ "lh",        0xac000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "li",        0xc8000000,     0xfc7f0000,     "r,I",          4 },
+{ "lmap",      0x2c070000,     0xfc7f0000,     "r",            2 },
+{ "lmb",       0xb0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lmd",       0xb0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lmh",       0xb0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lmw",       0xb0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnb",       0xb4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lnd",       0xb4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "lnh",       0xb4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "lnw",       0xb4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lpsd",      0xf9800000,     0xff880000,     "r,xOA,X",      4 },
+{ "lpsdcm",    0xfa800000,     0xff880000,     "r,xOA,X",      4 },
+{ "lw",        0xac000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "lwbr",      0x5c000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "mpfd",      0xe4080002,     0xfc080002,     "r,xOA,X",      4 },
+{ "mpfw",      0xe4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpi",       0xc8030000,     0xfc7f0000,     "r,I",          4 },
+{ "mpmb",      0xc0080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpmh",      0xc0000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "mpmw",      0xc0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "mpr",       0x38020000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfd",     0x380e0000,     0xfc0f0000,     "r,R",          2 },
+{ "mprfw",     0x38060000,     0xfc0f0000,     "r,R",          2 },
+{ "nop",       0x00020000,     0xffff0000,     "",             2 },
+{ "ormb",      0x88080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "ormd",      0x88000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "ormh",      0x88000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "ormw",      0x88000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "orr",       0x08000000,     0xfc0f0000,     "r,R",          2 },
+{ "orrm",      0x08080000,     0xfc0f0000,     "r,R",          2 },
+{ "rdsts",     0x00090000,     0xfc7f0000,     "r",            2 },
+{ "return",    0x280e0000,     0xfc7f0000,     "",             2 },
+{ "ri",        0xfc020000,     0xfc07ffff,     "I",            4 },
+{ "rnd",       0x00050000,     0xfc7f0000,     "r",            2 },
+{ "rpswt",     0x040b0000,     0xfc7f0000,     "r",            2 },
+{ "rschnl",    0xfc2f0000,     0xfc7f8000,     "r,I",          4 },
+{ "rsctl",     0xfc470000,     0xfc7f8000,     "r,I",          4 },
+{ "rwcs",      0x000b0000,     0xfc0f0000,     "r,R",          2 },
+{ "sacz",      0x10080000,     0xfc0f0000,     "r,R",          2 },
+{ "sbm",       0x98080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "sbr",       0x18000000,     0xfc0c0000,     "r,f",          4 },
+{ "sea",       0x000d0000,     0xffff0000,     "",             2 },
+{ "setcpu",    0x2c090000,     0xfc7f0000,     "r",            2 },
+{ "sio",       0xfc170000,     0xfc7f8000,     "r,I",          4 },
+{ "sipu",      0x000a0000,     0xffff0000,     "",             2 },
+{ "sla",       0x1c400000,     0xfc600000,     "r,S",          2 },
+{ "slad",      0x20400000,     0xfc600000,     "r,S",          2 },
+{ "slc",       0x24400000,     0xfc600000,     "r,S",          2 },
+{ "sll",       0x1c600000,     0xfc600000,     "r,S",          2 },
+{ "slld",      0x20600000,     0xfc600000,     "r,S",          2 },
+{ "smc",       0x04070000,     0xfc070000,     "",             2 },
+{ "sra",       0x1c000000,     0xfc600000,     "r,S",          2 },
+{ "srad",      0x20000000,     0xfc600000,     "r,S",          2 },
+{ "src",       0x24000000,     0xfc600000,     "r,S",          2 },
+{ "srl",       0x1c200000,     0xfc600000,     "r,S",          2 },
+{ "srld",      0x20200000,     0xfc600000,     "r,S",          2 },
+{ "stb",       0xd4080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "std",       0xd4000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stf",       0xdc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stfbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "sth",       0xd4000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stmb",      0xd8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stmd",      0xd8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "stmh",      0xd8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "stmw",      0xd8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stpio",     0xfc270000,     0xfc7f8000,     "r,I",          4 },
+{ "stw",       0xd4000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "stwbr",     0x54000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "suabr",     0x58000000,     0xfc080000,     "b,xOA,X",      4 },
+{ "sufd",      0xe0000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sufw",      0xe0000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sui",       0xc8020000,     0xfc7f0000,     "r,I",          4 },
+{ "sumb",      0xbc080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sumd",      0xbc000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "sumh",      0xbc000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "sumw",      0xbc000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "sur",       0x3c000000,     0xfc0f0000,     "r,R",          2 },
+{ "surfd",     0x380b0000,     0xfc0f0000,     "r,xOA,X",      4 },
+{ "surfw",     0x38030000,     0xfc0f0000,     "r,R",          2 },
+{ "surm",      0x3c080000,     0xfc0f0000,     "r,R",          2 },
+{ "svc",       0xc8060000,     0xffff0000,     "",             4 },
+{ "tbm",       0xa4080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "tbr",       0x180c0000,     0xfc0c0000,     "r,f",          2 },
+{ "tbrr",      0x2c020000,     0xfc0f0000,     "r,B",          2 },
+{ "tccr",      0x28040000,     0xfc7f0000,     "",             2 },
+{ "td",        0xfc050000,     0xfc070000,     "r,f",          4 },
+{ "tio",       0xfc1f0000,     0xfc7f8000,     "r,I",          4 },
+{ "tmapr",     0x2c0a0000,     0xfc0f0000,     "r,R",          2 },
+{ "tpcbr",     0x280c0000,     0xfc7f0000,     "r",            2 },
+{ "trbr",      0x2c010000,     0xfc0f0000,     "b,R",          2 },
+{ "trc",       0x2c030000,     0xfc0f0000,     "r,R",          2 },
+{ "trcc",      0x28050000,     0xfc7f0000,     "",             2 },
+{ "trcm",      0x2c0b0000,     0xfc0f0000,     "r,R",          2 },
+{ "trn",       0x2c040000,     0xfc0f0000,     "r,R",          2 },
+{ "trnm",      0x2c0c0000,     0xfc0f0000,     "r,R",          2 },
+{ "trr",       0x2c000000,     0xfc0f0000,     "r,R",          2 },
+{ "trrm",      0x2c080000,     0xfc0f0000,     "r,R",          2 },
+{ "trsc",      0x2c0e0000,     0xfc0f0000,     "r,R",          2 },
+{ "trsw",      0x28000000,     0xfc7f0000,     "r",            2 },
+{ "tscr",      0x2c0f0000,     0xfc0f0000,     "r,R",          2 },
+{ "uei",       0x00070000,     0xffff0000,     "",             2 },
+{ "wait",      0x00010000,     0xffff0000,     "",             2 },
+{ "wcwcs",     0xfc5f0000,     0xfc7f8000,     "",             4 },
+{ "wwcs",      0x000c0000,     0xfc0f0000,     "r,R",          2 },
+{ "xcbr",      0x28020000,     0xfc0f0000,     "b,B",          2 },
+{ "xcr",       0x2c050000,     0xfc0f0000,     "r,R",          2 },
+{ "xcrm",      0x2c0d0000,     0xfc0f0000,     "r,R",          2 },
+{ "zbm",       0x9c080000,     0xfc080000,     "f,xOA,X",      4 },
+{ "zbr",       0x18040000,     0xfc0c0000,     "r,f",          2 },
+{ "zmb",       0xf8080000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zmd",       0xf8000002,     0xfc080002,     "r,xOA,X",      4 },
+{ "zmh",       0xf8000001,     0xfc080001,     "r,xOA,X",      4 },
+{ "zmw",       0xf8000000,     0xfc080000,     "r,xOA,X",      4 },
+{ "zr",        0x0c000000,     0xfc0f0000,     "r",            2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+               sizeof(gld_opcodes[0]);
diff --git a/gdb/pyr-opcode.h b/gdb/pyr-opcode.h
new file mode 100755 (executable)
index 0000000..06632b8
--- /dev/null
@@ -0,0 +1,287 @@
+/* pyramid.opcode.h -- gdb initial attempt. */
+
+/* pyramid opcode table: wot to do with this
+   particular opcode */
+
+struct pyr_datum
+{
+  char              nargs;
+  char *            args;      /* how to compile said opcode */
+  unsigned long     mask;      /* Bit vector: which operand modes are valid
+                                  for this opcode */
+  unsigned char     code;      /* op-code (always 6(?) bits */
+};
+
+typedef struct pyr_insn_format {
+    unsigned int mode :4;
+    unsigned int operator :8;
+    unsigned int index_scale :2;
+    unsigned int index_reg :6;
+    unsigned int operand_1 :6;
+    unsigned int operand_2:6;
+} pyr_insn_format;
+       
+
+/* We store four bytes of opcode for all opcodes.
+   Pyramid is sufficiently RISCy that:
+      - insns are always an integral number of words;
+      - the length of any insn can be told from the first word of
+        the insn. (ie, if there are zero, one, or two words of
+       immediate operand/offset).
+
+   
+   The args component is a string containing two characters for each
+   operand of the instruction.  The first specifies the kind of operand;
+   the second, the place it is stored. */
+
+/* Kinds of operands:
+   mask         assembler syntax       description
+   0x0001:  movw Rn,Rn         register to register
+   0x0002:  movw K,Rn          quick immediate to register
+   0x0004:  movw I,Rn          long immediate to register
+   0x0008:  movw (Rn),Rn       register indirect to register
+           movw (Rn)[x],Rn     register indirect to register
+   0x0010:  movw I(Rn),Rn      offset register indirect to register
+           movw I(Rn)[x],Rn    offset register indirect, indexed, to register
+
+   0x0020:  movw Rn,(Rn)       register to register indirect                
+   0x0040:  movw K,(Rn)                quick immediate to register indirect         
+   0x0080:  movw I,(Rn)                long immediate to register indirect          
+   0x0100:  movw (Rn),(Rn)     register indirect to-register indirect       
+   0x0100:  movw (Rn),(Rn)     register indirect to-register indirect       
+   0x0200:  movw I(Rn),(Rn)    register indirect+offset to register indirect
+   0x0200:  movw I(Rn),(Rn)    register indirect+offset to register indirect
+
+   0x0400:  movw Rn,I(Rn)      register to register indirect+offset
+   0x0800:  movw K,I(Rn)       quick immediate to register indirect+offset
+   0x1000:  movw I,I(Rn)       long immediate to register indirect+offset
+   0x1000:  movw (Rn),I(Rn)    register indirect to-register indirect+offset
+   0x1000:  movw I(Rn),I(Rn)   register indirect+offset to register indirect
+                                       +offset
+   0x0000:  (irregular)                ???
+   
+
+   Each insn has a four-bit field encoding the type(s) of its operands.
+*/
+
+/* Some common combinations
+   */
+
+/* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
+#define GEN_TO_REG (31)
+
+#define        UNKNOWN ((unsigned long)-1)
+#define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
+
+#define CONVERT (1|8|0x10|0x20|0x200)
+
+#define K_TO_REG (2)
+#define I_TO_REG (4)
+#define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
+#define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
+
+/* The assembler requires that this array be sorted as follows:
+   all instances of the same mnemonic must be consecutive.
+   All instances of the same mnemonic with the same number of operands
+   must be consecutive.
+ */
+
+struct pyr_opcode              /* pyr opcode text */
+{
+  char *            name;      /* opcode name: lowercase string  [key]  */
+  struct pyr_datum  datum;     /* rest of opcode table          [datum] */
+};
+
+#define pyr_how args
+#define pyr_nargs nargs
+#define pyr_mask mask
+#define pyr_name name
+
+struct pyr_opcode pyr_opcodes[] =
+{
+  {"movb",     { 2, "", UNKNOWN,               0x11}, },
+  {"movh",     { 2, "", UNKNOWN,               0x12} },
+  {"movw",     { 2, "", ANY,                   0x10} },
+  {"movl",     { 2, "", ANY,                   0x13} },
+  {"mnegw",    { 2, "", (0x1|0x8|0x10),        0x14} },
+  {"mnegf",    { 2, "", 0x1,                   0x15} },
+  {"mnegd",    { 2, "", 0x1,                   0x16} },
+  {"mcomw",    { 2, "", (0x1|0x8|0x10),        0x17} },
+  {"mabsw",    { 2, "", (0x1|0x8|0x10),        0x18} },
+  {"mabsf",    { 2, "", 0x1,                   0x19} },
+  {"mabsd",    { 2, "", 0x1,                   0x1a} },
+  {"mtstw",    { 2, "", (0x1|0x8|0x10),        0x1c} },
+  {"mtstf",    { 2, "", 0x1,                   0x1d} },
+  {"mtstd",    { 2, "", 0x1,                   0x1e} },
+  {"mova",     { 2, "", 0x8|0x10,              0x1f} },
+  {"movzbw",   { 2, "", (0x1|0x8|0x10),        0x20} },
+  {"movzhw",   { 2, "", (0x1|0x8|0x10),        0x21} },
+                               /* 2 insns out of order here */
+  {"movbl",    { 2, "", 1,                     0x4f} },
+  {"filbl",    { 2, "", 1,                     0x4e} },
+
+  {"cvtbw",    { 2, "", CONVERT,               0x22} },
+  {"cvthw",    { 2, "", CONVERT,               0x23} },
+  {"cvtwb",    { 2, "", CONVERT,               0x24} },
+  {"cvtwh",    { 2, "", CONVERT,               0x25} },
+  {"cvtwf",    { 2, "", CONVERT,               0x26} },
+  {"cvtwd",    { 2, "", CONVERT,               0x27} },
+  {"cvtfw",    { 2, "", CONVERT,               0x28} },
+  {"cvtfd",    { 2, "", CONVERT,               0x29} },
+  {"cvtdw",    { 2, "", CONVERT,               0x2a} },
+  {"cvtdf",    { 2, "", CONVERT,               0x2b} },
+
+  {"addw",     { 2, "", GEN_TO_REG,            0x40} },
+  {"addwc",    { 2, "", GEN_TO_REG,            0x41} },
+  {"subw",     { 2, "", GEN_TO_REG,            0x42} },
+  {"subwb",    { 2, "", GEN_TO_REG,            0x43} },
+  {"rsubw",    { 2, "", GEN_TO_REG,            0x44} },
+  {"mulw",     { 2, "", GEN_TO_REG,            0x45} },
+  {"emul",     { 2, "", GEN_TO_REG,            0x47} },
+  {"umulw",    { 2, "", GEN_TO_REG,            0x46} },
+  {"divw",     { 2, "", GEN_TO_REG,            0x48} },
+  {"ediv",     { 2, "", GEN_TO_REG,            0x4a} },
+  {"rdivw",    { 2, "", GEN_TO_REG,            0x4b} },
+  {"udivw",    { 2, "", GEN_TO_REG,            0x49} },
+  {"modw",     { 2, "", GEN_TO_REG,            0x4c} },
+  {"umodw",    { 2, "", GEN_TO_REG,            0x4d} },
+
+
+  {"addf",     { 2, "", 1,                     0x50} },
+  {"addd",     { 2, "", 1,                     0x51} },
+  {"subf",     { 2, "", 1,                     0x52} },
+  {"subd",     { 2, "", 1,                     0x53} },
+  {"mulf",     { 2, "", 1,                     0x56} },
+  {"muld",     { 2, "", 1,                     0x57} },
+  {"divf",     { 2, "", 1,                     0x58} },
+  {"divd",     { 2, "", 1,                     0x59} },
+
+
+  {"cmpb",     { 2, "", UNKNOWN,               0x61} },
+  {"cmph",     { 2, "", UNKNOWN,               0x62} },
+  {"cmpw",     { 2, "", UNKNOWN,               0x60} },
+  {"ucmpb",    { 2, "", UNKNOWN,               0x66} },
+  /* WHY no "ucmph"??? */
+  {"ucmpw",    { 2, "", UNKNOWN,               0x65} },
+  {"xchw",     { 2, "", UNKNOWN,               0x0f} },
+
+
+  {"andw",     { 2, "", GEN_TO_REG,            0x30} },
+  {"orw",      { 2, "", GEN_TO_REG,            0x31} },
+  {"xorw",     { 2, "", GEN_TO_REG,            0x32} },
+  {"bicw",     { 2, "", GEN_TO_REG,            0x33} },
+  {"lshlw",    { 2, "", GEN_TO_REG,            0x38} },
+  {"ashlw",    { 2, "", GEN_TO_REG,            0x3a} },
+  {"ashll",    { 2, "", GEN_TO_REG,            0x3c} },
+  {"ashrw",    { 2, "", GEN_TO_REG,            0x3b} },
+  {"ashrl",    { 2, "", GEN_TO_REG,            0x3d} },
+  {"rotlw",    { 2, "", GEN_TO_REG,            0x3e} },
+  {"rotrw",    { 2, "", GEN_TO_REG,            0x3f} },
+
+  /* push and pop insns are "going away next release". */
+  {"pushw",    { 2, "", GEN_TO_REG,            0x0c} },
+  {"popw",     { 2, "", (0x1|0x8|0x10),        0x0d} },
+  {"pusha",    { 2, "", (0x8|0x10),            0x0e} },
+
+  {"bitsw",    { 2, "", UNKNOWN,               0x35} },
+  {"bitcw",    { 2, "", UNKNOWN,               0x36} },
+  /* some kind of ibra/dbra insns??*/
+  {"icmpw",    { 2, "", UNKNOWN,               0x67} },
+  {"dcmpw",    { 2, "", (1|4|0x20|0x80|0x400|0x1000),  0x69} },/*FIXME*/
+  {"acmpw",    { 2, "", 1,                     0x6b} },
+
+  /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
+     insn with a 2nd op of tr14.   The assembler will have to grok this.  */
+  {"call",     { 2, "", GEN_TO_REG,            0x04} },
+  {"call",     { 1, "", GEN_TO_REG,            0x04} },
+
+  {"callk",    { 1, "", UNKNOWN,               0x06} },/* system call?*/
+  /* Ret is usually written as a 0-op insn, but gets disassembled as a
+     1-op insn. The operand is always tr15. */
+  {"ret",      { 0, "", UNKNOWN,               0x09} },
+  {"ret",      { 1, "", UNKNOWN,               0x09} },
+  {"adsf",     { 2, "", (1|2|4),               0x08} },
+  {"retd",     { 2, "", UNKNOWN,               0x0a} },
+  {"btc",      { 2, "", UNKNOWN,               0x01} },
+  {"bfc",      { 2, "", UNKNOWN,               0x02} },
+  /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
+  {"jump",     { 1, "", UNKNOWN,               0x00} },
+  {"btp",      { 2, "", UNKNOWN,               0xf00} },
+  /* read control-stack pointer is another 1-or-2 operand insn. */
+  {"rcsp",     { 2, "", UNKNOWN,               0x01f} },
+  {"rcsp",     { 1, "", UNKNOWN,               0x01f} }
+};
+
+/* end: pyramid.opcode.h */
+/* One day I will have to take the time to find out what operands
+   are valid for these insns, and guess at what they mean.
+
+   I can't imagine what the "I???" insns (iglob, etc) do.
+
+   the arithmetic-sounding insns ending in "p" sound awfully like BCD
+   arithmetic insns:
+       dshlp -> Decimal SHift Left Packed
+       dshrp -> Decimal SHift Right Packed
+   and cvtlp would be convert long to packed.
+   I have no idea how the operands are interpreted; but having them be
+   a long register with (address, length) of an in-memory packed BCD operand
+   would not be surprising.
+   They are unlikely to be a packed bcd string: 64 bits of long give
+   is only 15 digits+sign, which isn't enough for COBOL.
+ */ 
+#if 0
+  {"wcsp",     { 2, "", UNKNOWN,               0x00} }, /*write csp?*/
+  /* The OSx Operating System Porting Guide claims SSL does things
+     with tr12 (a register reserved to it) to do with static block-structure
+     references.  SSL=Set Static Link?  It's "Going away next release". */
+  {"ssl",      { 2, "", UNKNOWN,               0x00} },
+  {"ccmps",    { 2, "", UNKNOWN,               0x00} },
+  {"lcd",      { 2, "", UNKNOWN,               0x00} },
+  {"uemul",    { 2, "", UNKNOWN,               0x00} }, /*unsigned emul*/
+  {"srf",      { 2, "", UNKNOWN,               0x00} }, /*Gidget time???*/
+  {"mnegp",    { 2, "", UNKNOWN,               0x00} }, /move-neg phys?*/
+  {"ldp",      { 2, "", UNKNOWN,               0x00} }, /*load phys?*/
+  {"ldti",     { 2, "", UNKNOWN,               0x00} },
+  {"ldb",      { 2, "", UNKNOWN,               0x00} },
+  {"stp",      { 2, "", UNKNOWN,               0x00} },
+  {"stti",     { 2, "", UNKNOWN,               0x00} },
+  {"stb",      { 2, "", UNKNOWN,               0x00} },
+  {"stu",      { 2, "", UNKNOWN,               0x00} },
+  {"addp",     { 2, "", UNKNOWN,               0x00} },
+  {"subp",     { 2, "", UNKNOWN,               0x00} },
+  {"mulp",     { 2, "", UNKNOWN,               0x00} },
+  {"divp",     { 2, "", UNKNOWN,               0x00} },
+  {"dshlp",    { 2, "", UNKNOWN,               0x00} },  /* dec shl packed? */
+  {"dshrp",    { 2, "", UNKNOWN,               0x00} }, /* dec shr packed? */
+  {"movs",     { 2, "", UNKNOWN,               0x00} }, /*move (string?)?*/
+  {"cmpp",     { 2, "", UNKNOWN,               0x00} }, /* cmp phys?*/
+  {"cmps",     { 2, "", UNKNOWN,               0x00} }, /* cmp (string?)?*/
+  {"cvtlp",    { 2, "", UNKNOWN,               0x00} }, /* cvt long to p??*/
+  {"cvtpl",    { 2, "", UNKNOWN,               0x00} }, /* cvt p to l??*/
+  {"dintr",    { 2, "", UNKNOWN,               0x00} }, /* ?? intr ?*/
+  {"rphysw",   { 2, "", UNKNOWN,               0x00} }, /* read phys word?*/
+  {"wphysw",   { 2, "", UNKNOWN,               0x00} }, /* write phys word?*/
+  {"cmovs",    { 2, "", UNKNOWN,               0x00} },
+  {"rsubw",    { 2, "", UNKNOWN,               0x00} },
+  {"bicpsw",   { 2, "", UNKNOWN,               0x00} }, /* clr bit in psw? */
+  {"bispsw",   { 2, "", UNKNOWN,               0x00} }, /* set bit in psw? */
+  {"eio",      { 2, "", UNKNOWN,               0x00} }, /* ?? ?io ? */
+  {"callp",    { 2, "", UNKNOWN,               0x00} }, /* call phys?*/
+  {"callr",    { 2, "", UNKNOWN,               0x00} },
+  {"lpcxt",    { 2, "", UNKNOWN,               0x00} }, /*load proc context*/
+  {"rei",      { 2, "", UNKNOWN,               0x00} }, /*ret from intrpt*/
+  {"rport",    { 2, "", UNKNOWN,               0x00} }, /*read-port?*/
+  {"rtod",     { 2, "", UNKNOWN,               0x00} }, /*read-time-of-day?*/
+  {"ssi",      { 2, "", UNKNOWN,               0x00} },
+  {"vtpa",     { 2, "", UNKNOWN,               0x00} }, /*virt-to-phys-addr?*/
+  {"wicl",     { 2, "", UNKNOWN,               0x00} }, /* write icl ? */
+  {"wport",    { 2, "", UNKNOWN,               0x00} }, /*write-port?*/
+  {"wtod",     { 2, "", UNKNOWN,               0x00} }, /*write-time-of-day?*/
+  {"flic",     { 2, "", UNKNOWN,               0x00} },
+  {"iglob",    { 2, "", UNKNOWN,               0x00} }, /* I global? */
+  {"iphys",    { 2, "", UNKNOWN,               0x00} }, /* I physical? */
+  {"ipid",     { 2, "", UNKNOWN,               0x00} }, /* I pid? */
+  {"ivect",    { 2, "", UNKNOWN,               0x00} }, /* I vector? */
+  {"lamst",    { 2, "", UNKNOWN,               0x00} },
+  {"tio",      { 2, "", UNKNOWN,               0x00} },
+#endif
diff --git a/gdb/pyr-pinsn.c b/gdb/pyr-pinsn.c
new file mode 100644 (file)
index 0000000..d58ae47
--- /dev/null
@@ -0,0 +1,347 @@
+/* Disassembler for the Pyramid Technology 90x
+   Copyright (C) 1988,1989 Free Software Foundation, Inc.
+
+This file is part of GDB, the GNU disassembler.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "pyr-opcode.h"
+#include "gdbcore.h"
+
+\f
+/*  A couple of functions used for debugging frame-handling on
+    Pyramids. (The Pyramid-dependent handling of register values for
+    windowed registers is known to be buggy.)
+
+    When debugging, these functions supplant the normal definitions of some
+    of the macros in m-pyramid.h  The quantity of information produced
+    when these functions are used makes the gdb  unusable as a
+    debugger for user programs.  */
+    
+extern unsigned pyr_saved_pc(), pyr_frame_chain();
+
+CORE_ADDR pyr_frame_chain(frame)
+    CORE_ADDR frame;
+{
+    int foo=frame - CONTROL_STACK_FRAME_SIZE;
+    /* printf ("...following chain from %x: got %x\n", frame, foo);*/
+    return foo;
+}
+
+CORE_ADDR pyr_saved_pc(frame)
+    CORE_ADDR frame;
+{
+    int foo=0;
+    foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
+    printf ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
+           frame, 60/4, foo);
+    return foo;
+}
+\f
+
+/* Pyramid instructions are never longer than this many bytes.  */
+#define MAXLEN 24
+
+/* Number of elements in the opcode table.  */
+/*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
+#define NOPCODES (nopcodes)
+
+extern char *reg_names[];
+\f
+/* Let's be byte-independent so we can use this as a cross-assembler.
+   (will this ever be useful?
+ */
+
+#define NEXTLONG(p)  \
+  (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
+
+\f
+/* Print one instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  register int i, nargs, insn_size =4;
+  register unsigned char *p;
+  register char *d;
+  register int insn_opcode, operand_mode;
+  register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ;
+  long insn;                   /* first word of the insn, not broken down. */
+  pyr_insn_format insn_decode; /* the same, broken out into op{code,erands} */
+  long extra_1, extra_2;
+
+  read_memory (memaddr, buffer, MAXLEN);
+  insn_decode = *((pyr_insn_format *) buffer);
+  insn = * ((int *) buffer);
+  insn_opcode = insn_decode.operator;
+  operand_mode = insn_decode.mode;
+  index_multiplier = insn_decode.index_scale;
+  index_reg_regno = insn_decode.index_reg;
+  op_1_regno = insn_decode.operand_1;
+  op_2_regno = insn_decode.operand_2;
+  
+  
+  if (*((int *)buffer) == 0x0) {
+    /* "halt" looks just like an invalid "jump" to the insn decoder,
+       so is dealt with as a special case */
+    fprintf (stream, "halt");
+    return (4);
+  }
+
+  for (i = 0; i < NOPCODES; i++)
+         if (pyr_opcodes[i].datum.code == insn_opcode)
+                 break;
+
+  if (i == NOPCODES)
+         /* FIXME: Handle unrecognised instructions better.  */
+         fprintf (stream, "???\t#%08x\t(op=%x mode =%x)",
+                  insn, insn_decode.operator, insn_decode.mode);
+  else
+    {
+      /* Print the mnemonic for the instruction.  Pyramid insn operands
+         are so regular that we can deal with almost all of them
+         separately.
+        Unconditional branches are an exception: they are encoded as
+        conditional branches (branch if false condition, I think)
+        with no condition specified. The average user will not be
+        aware of this. To maintain their illusion that an
+        unconditional branch insn exists, we will have to FIXME to
+        treat the insn mnemnonic of all branch instructions here as a
+        special case: check the operands of branch insn and print an
+        appropriate mnemonic. */ 
+
+      fprintf (stream, "%s\t", pyr_opcodes[i].name);
+
+    /* Print the operands of the insn (as specified in
+       insn.operand_mode). 
+       Branch operands of branches are a special case: they are a word
+       offset, not a byte offset. */
+  
+    if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
+      register int bit_codes=(insn >> 16)&0xf;
+      register int i;
+      register int displacement = (insn & 0x0000ffff) << 2;
+
+      static char cc_bit_names[] = "cvzn";     /* z,n,c,v: strange order? */
+
+      /* Is bfc and no bits specified an unconditional branch?*/
+      for (i=0;i<4;i++) {
+       if ((bit_codes) & 0x1)
+               fputc (cc_bit_names[i], stream);
+       bit_codes >>= 1;
+      }
+
+      fprintf (stream, ",%0x",
+              displacement + memaddr);
+      return (insn_size);
+    }
+
+      switch (operand_mode) {
+      case 0:
+       fprintf (stream, "%s,%s",
+                reg_names [op_1_regno],
+                reg_names [op_2_regno]);
+       break;
+           
+      case 1:
+       fprintf (stream, " 0x%0x,%s",
+                op_1_regno,
+                reg_names [op_2_regno]);
+       break;
+       
+      case 2:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream, " $0x%0x,%s",
+                extra_1,
+                reg_names [op_2_regno]);
+       break;
+      case 3:
+       fprintf (stream, " (%s),%s",
+                reg_names [op_1_regno],
+                reg_names [op_2_regno]);
+       break;
+       
+      case 4:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream, " 0x%0x(%s),%s",
+                extra_1,
+                reg_names [op_1_regno],
+                reg_names [op_2_regno]);
+       break;
+       
+       /* S1 destination mode */
+      case 5:
+       fprintf (stream,
+                ((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
+                reg_names [op_1_regno],
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      case 6:
+       fprintf (stream,
+                ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
+                 : " $%#0x,(%s)"),
+                op_1_regno,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      case 7:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
+                 : " $%#0x,(%s)"),
+                extra_1,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      case 8:
+       fprintf (stream,
+                ((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
+                reg_names [op_1_regno],
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      case 9:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno)
+                 ? "%#0x(%s),(%s)[%s*%1d]"
+                 : "%#0x(%s),(%s)"),
+                extra_1,
+                reg_names [op_1_regno],
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+       /* S2 destination mode */
+      case 10:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
+                reg_names [op_1_regno],
+                extra_1,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+      case 11:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno) ?
+                 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
+                op_1_regno,
+                extra_1,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+      case 12:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       read_memory (memaddr+8, buffer, MAXLEN);
+       insn_size += 4;
+       extra_2 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno) ?
+                 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
+                extra_1,
+                extra_2,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      case 13:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno)
+                 ? " (%s),%#0x(%s)[%s*%1d]" 
+                 : " (%s),%#0x(%s)"),
+                reg_names [op_1_regno],
+                extra_1,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+      case 14:
+       read_memory (memaddr+4, buffer, MAXLEN);
+       insn_size += 4;
+       extra_1 = * ((int *) buffer);
+       read_memory (memaddr+8, buffer, MAXLEN);
+       insn_size += 4;
+       extra_2 = * ((int *) buffer);
+       fprintf (stream,
+                ((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
+                 : "%#0x(%s),%#0x(%s) "),
+                extra_1,
+                reg_names [op_1_regno],
+                extra_2,
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       break;
+       
+      default:
+       fprintf (stream,
+                ((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
+                reg_names [op_1_regno],
+                reg_names [op_2_regno],
+                reg_names [index_reg_regno],
+                index_multiplier);
+       fprintf (stream,
+                "\t\t# unknown mode in %08x",
+                insn);
+       break;
+      } /* switch */
+    }
+  
+  {
+    return insn_size;
+  }
+  abort ();
+}
diff --git a/gdb/pyr-tdep.c b/gdb/pyr-tdep.c
new file mode 100644 (file)
index 0000000..b79ea0c
--- /dev/null
@@ -0,0 +1,129 @@
+/* Low level interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*** Prettier register printing. ***/
+
+/* Print registers in the same format as pyramid's dbx, adb, sdb.  */
+pyr_print_registers(reg_buf, regnum)
+    long *reg_buf[];
+{
+  register int regno;
+  int usp, ksp;
+  struct user u;
+
+  for (regno = 0; regno < 16; regno++) {
+    printf/*_filtered*/ ("%6.6s: %8x  %6.6s: %8x  %6s: %8x  %6s: %8x\n",
+                    reg_names[regno], reg_buf[regno],
+                    reg_names[regno+16], reg_buf[regno+16],
+                    reg_names[regno+32], reg_buf[regno+32],
+                    reg_names[regno+48], reg_buf[regno+48]);
+  }
+  usp = ptrace (3, inferior_pid,
+                     ((char *)&u.u_pcb.pcb_usp) -
+                     ((char *)&u), 0);
+  ksp = ptrace (3, inferior_pid,
+                     ((char *)&u.u_pcb.pcb_ksp) -
+                     ((char *)&u), 0);
+  printf/*_filtered*/ ("\n%6.6s: %8x  %6.6s: %8x (%08x) %6.6s %8x\n",
+                  reg_names[CSP_REGNUM],reg_buf[CSP_REGNUM],
+                  reg_names[KSP_REGNUM], reg_buf[KSP_REGNUM], ksp,
+                  "usp", usp);
+}
+
+/* Print the register regnum, or all registers if regnum is -1. */
+
+pyr_do_registers_info (regnum)
+    int regnum;
+{
+  /* On a pyr, we know a virtual register can always fit in an long.
+     Here (and elsewhere) we take advantage of that.  Yuk.  */
+  long raw_regs[MAX_REGISTER_RAW_SIZE*NUM_REGS];
+  register int i;
+  
+  for (i = 0 ; i < 64 ; i++) {
+    read_relative_register_raw_bytes(i, raw_regs+i);
+  }
+  if (regnum == -1)
+    pyr_print_registers (raw_regs, regnum);
+  else
+    for (i = 0; i < NUM_REGS; i++)
+      if (i == regnum) {
+       long val = raw_regs[i];
+       
+       fputs_filtered (reg_names[i], stdout);
+       printf_filtered(":");
+       print_spaces_filtered (6 - strlen (reg_names[i]), stdout);
+       if (val == 0)
+         printf_filtered ("0");
+       else
+         printf_filtered ("0x%08x  %d", val, val);
+       printf_filtered("\n");
+      }
+}
+\f
+/*** Debugging editions of various macros from m-pyr.h ****/
+
+CORE_ADDR frame_locals_address (frame)
+    FRAME frame;
+{
+  register int addr = find_saved_register (frame,CFP_REGNUM);
+  register int result = read_memory_integer (addr, 4);
+#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
+  fprintf (stderr,
+          "\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
+          frame->frame,
+          reg_names[CFP_REGNUM],
+          result, addr,
+          frame->frame_cfp, (CFP_REGNUM),
+
+
+          read_register(13), read_register(29), read_register(61),
+          find_saved_register(frame, 61));
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+
+  /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
+     or at least CFP_REGNUM relative to FRAME (ie, result).
+     There seems to be a bug in the way the innermost frame is set up.  */
+
+    return ((frame->next) ? result: frame->frame_cfp);
+}
+
+CORE_ADDR frame_args_addr (frame)
+    FRAME frame;
+{
+  register int addr = find_saved_register (frame,CFP_REGNUM);
+  register int result = read_memory_integer (addr, 4);
+
+#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
+  fprintf (stderr,
+          "\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
+          frame->frame,
+          reg_names[CFP_REGNUM],
+          result, addr,
+          frame->frame_cfp, read_register(CFP_REGNUM),
+
+          read_register(13), read_register(29), read_register(61),
+          find_saved_register(frame, 61));
+#endif /*  PYRAMID_CONTROL_FRAME_DEBUGGING */
+
+  /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
+     or at least CFP_REGNUM relative to FRAME (ie, result).
+     There seems to be a bug in the way the innermost frame is set up.  */
+    return ((frame->next) ? result: frame->frame_cfp);
+}
diff --git a/gdb/pyr-xdep.c b/gdb/pyr-xdep.c
new file mode 100644 (file)
index 0000000..5ba4a8d
--- /dev/null
@@ -0,0 +1,366 @@
+/* Low level Pyramid interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+/* #include <fcntl.h>  Can we live without this?  */
+
+#include "gdbcore.h"
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <sys/stat.h>
+\f
+void
+fetch_inferior_registers ()
+{
+  register int regno, datum;
+  register unsigned int regaddr;
+  int reg_buf[NUM_REGS+1];
+  struct user u;
+  register int skipped_frames = 0;
+
+  registers_fetched ();
+  
+  for (regno = 0; regno < 64; regno++) {
+    reg_buf[regno] = ptrace (3, inferior_pid, regno, 0);
+    
+#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
+    printf ("Fetching %s from inferior, got %0x\n",
+           reg_names[regno],
+           reg_buf[regno]);
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+    
+    if (reg_buf[regno] == -1 && errno == EIO) {
+      printf("fetch_interior_registers: fetching %s from inferior\n",
+            reg_names[regno]);
+      errno = 0;
+    }
+    supply_register (regno, reg_buf+regno);
+  }
+  /* that leaves regs 64, 65, and 66 */
+  datum = ptrace (3, inferior_pid,
+                 ((char *)&u.u_pcb.pcb_csp) -
+                 ((char *)&u), 0);
+  
+  
+  
+  /* FIXME: Find the Current Frame Pointer (CFP). CFP is a global
+     register (ie, NOT windowed), that gets saved in a frame iff
+     the code for that frame has a prologue (ie, "adsf N").  If
+     there is a prologue, the adsf insn saves the old cfp in
+     pr13, cfp is set to sp, and N bytes of locals are allocated
+     (sp is decremented by n).
+     This makes finding CFP hard. I guess the right way to do it
+     is: 
+     - If this is the innermost frame, believe ptrace() or
+     the core area.
+     - Otherwise:
+     Find the first insn of the current frame.
+     - find the saved pc;
+     - find the call insn that saved it;
+     - figure out where the call is to;
+     - if the first insn is an adsf, we got a frame
+     pointer. */
+  
+  
+  /* Normal processors have separate stack pointers for user and
+     kernel mode. Getting the last user mode frame on such
+     machines is easy: the kernel context of the ptrace()'d
+     process is on the kernel stack, and the USP points to what
+     we want. But Pyramids only have a single cfp for both user and
+     kernel mode.  And processes being ptrace()'d have some
+     kernel-context control frames on their stack.
+     To avoid tracing back into the kernel context of an inferior,
+     we skip 0 or more contiguous control frames where the pc is
+     in the kernel. */ 
+  
+  while (1) {
+    register int inferior_saved_pc;
+    inferior_saved_pc = ptrace (1, inferior_pid, datum+((32+15)*4), 0);
+    if (inferior_saved_pc > 0) break;
+#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
+    printf("skipping kernel frame %08x, pc=%08x\n", datum,
+          inferior_saved_pc);
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+    skipped_frames++;
+    datum -= CONTROL_STACK_FRAME_SIZE;
+  }
+  
+  reg_buf[CSP_REGNUM] = datum;
+  supply_register(CSP_REGNUM, reg_buf+CSP_REGNUM);
+#ifdef  PYRAMID_CONTROL_FRAME_DEBUGGING
+  if (skipped_frames) {
+    fprintf (stderr,
+            "skipped %d frames from %x to %x; cfp was %x, now %x\n",
+            skipped_frames, reg_buf[CSP_REGNUM]);
+  }
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  register unsigned int regaddr;
+  char buf[80];
+
+  if (regno >= 0)
+    {
+      if ((0 <= regno) && (regno < 64)) {
+       /*regaddr = register_addr (regno, offset);*/
+       regaddr = regno;
+       errno = 0;
+       ptrace (6, inferior_pid, regaddr, read_register (regno));
+       if (errno != 0)
+         {
+           sprintf (buf, "writing register number %d", regno);
+           perror_with_name (buf);
+         }
+      }
+    }
+  else
+    {
+      for (regno = 0; regno < NUM_REGS; regno++)
+       {
+         /*regaddr = register_addr (regno, offset);*/
+         regaddr = regno;
+         errno = 0;
+         ptrace (6, inferior_pid, regaddr, read_register (regno));
+         if (errno != 0)
+           {
+             sprintf (buf, "writing all regs, number %d", regno);
+             perror_with_name (buf);
+           }
+       }
+}
+\f
+/*** Extensions to  core and dump files, for GDB. */
+
+extern unsigned int last_frame_offset;
+
+#ifdef PYRAMID_CORE
+
+/* Can't make definitions here static, since core.c needs them
+   to do bounds checking on the core-file areas. O well. */
+
+/* have two stacks: one for data, one for register windows. */
+extern CORE_ADDR reg_stack_start;
+extern CORE_ADDR reg_stack_end;
+
+/* need this so we can find the global registers: they never get saved. */
+CORE_ADDR global_reg_offset;
+static CORE_ADDR last_frame_address;
+CORE_ADDR last_frame_offset;
+
+
+/* Address in core file of start of register window stack area.
+   Don't know if is this any of meaningful, useful or necessary.   */
+extern int reg_stack_offset;
+
+#endif /* PYRAMID_CORE */  
+
+\f
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+#ifdef PYRAMID_CORE
+  reg_stack_start = CONTROL_STACK_ADDR;
+  reg_stack_end = CONTROL_STACK_ADDR;  /* this isn't strictly true...*/
+#endif /* PYRAMID_CORE */
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct user u;
+
+       unsigned int reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name ("Not a core file: reading upage");
+       if (val != sizeof u)
+         error ("Not a core file: could only read %d bytes", val);
+       data_start = exec_data_start;
+
+       data_end = data_start + NBPG * u.u_dsize;
+       data_offset = NBPG * UPAGES;
+       stack_offset = NBPG * (UPAGES + u.u_dsize);
+
+       /* find registers in core file */
+#ifdef PYRAMID_PTRACE
+       stack_start = stack_end - NBPG * u.u_ussize;
+       reg_stack_offset = stack_offset + (NBPG *u.u_ussize);
+       reg_stack_end = reg_stack_start + NBPG * u.u_cssize;
+
+       last_frame_address = ((int) u.u_pcb.pcb_csp);
+       last_frame_offset = reg_stack_offset + last_frame_address
+               - CONTROL_STACK_ADDR ;
+       global_reg_offset = (char *)&u - (char *)&u.u_pcb.pcb_gr0 ;
+
+       /* skip any control-stack frames that were executed in the
+          kernel. */
+
+       while (1) {
+           char buf[4];
+           val = lseek (corechan, last_frame_offset+(47*4), 0);
+           if (val < 0)
+                   perror_with_name (filename);
+           val = myread (corechan, buf, sizeof buf);
+           if (val < 0)
+                   perror_with_name (filename);
+
+           if (*(int *)buf >= 0)
+                   break;
+           printf ("skipping frame %0x\n", last_frame_address);
+           last_frame_offset -= CONTROL_STACK_FRAME_SIZE;
+           last_frame_address -= CONTROL_STACK_FRAME_SIZE;
+       }
+       reg_offset = last_frame_offset;
+
+#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
+       printf ("Control stack pointer = 0x%08x\n",
+               u.u_pcb.pcb_csp);
+       printf ("offset to control stack %d outermost frame %d (%0x)\n",
+             reg_stack_offset, reg_offset, last_frame_address);
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+
+#else /* not PYRAMID_CORE */
+       stack_start = stack_end - NBPG * u.u_ssize;
+        reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
+#endif /* not PYRAMID_CORE */
+
+#ifdef __not_on_pyr_yet
+       /* Some machines put an absolute address in here and some put
+          the offset in the upage of the regs.  */
+       reg_offset = (int) u.u_ar0;
+       if (reg_offset > NBPG * UPAGES)
+         reg_offset -= KERNEL_U_ADDR;
+#endif
+
+       /* I don't know where to find this info.
+          So, for now, mark it as not available.  */
+       N_SET_MAGIC (core_aouthdr, 0);
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < 64; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             val = lseek (corechan, register_addr (regno, reg_offset), 0);
+             if (val < 0
+                 || (val = myread (corechan, buf, sizeof buf)) < 0)
+               {
+                 char * buffer = (char *) alloca (strlen (reg_names[regno])
+                                                  + 30);
+                 strcpy (buffer, "Reading register ");
+                 strcat (buffer, reg_names[regno]);
+                                                  
+                 perror_with_name (buffer);
+               }
+
+             if (val < 0)
+               perror_with_name (filename);
+#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
+      printf ("[reg %s(%d), offset in file %s=0x%0x, addr =0x%0x, =%0x]\n",
+             reg_names[regno], regno, filename,
+             register_addr(regno, reg_offset),
+             regno * 4 + last_frame_address,
+             *((int *)buf));
+#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
+      printf ("Providing CSP (%0x) as nominal address of current frame.\n",
+             last_frame_address);
+#endif PYRAMID_CONTROL_FRAME_DEBUGGING
+      /* FIXME: Which of the following is correct? */
+#if 0
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+#else
+      set_current_frame ( create_new_frame (last_frame_address,
+                                           read_pc ()));
+#endif
+
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
diff --git a/gdb/regex.c b/gdb/regex.c
new file mode 100644 (file)
index 0000000..45c3478
--- /dev/null
@@ -0,0 +1,1738 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  */
+
+
+/* To test, compile with -Dtest.
+ This Dtestable feature turns this into a self-contained program
+ which reads a pattern, describes how it compiles,
+ then reads a string and searches for it.  */
+
+#ifdef emacs
+
+/* The `emacs' switch turns on certain special matching commands
+ that make sense only in emacs. */
+
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+#else  /* not emacs */
+
+#ifdef USG
+#ifndef BSTRING
+#define bcopy(s,d,n)   memcpy((d),(s),(n))
+#define bcmp(s1,s2,n)  memcmp((s1),(s2),(n))
+#define bzero(s,n)     memset((s),0,(n))
+#endif
+#endif
+
+/* Make alloca work the best possible way.  */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef sparc
+#include <alloca.h>
+#endif
+#endif
+
+/*
+ * Define the syntax stuff, so we can do the \<...\> things.
+ */
+
+#ifndef Sword /* must be non-zero in some of the tests below... */
+#define Sword 1
+#endif
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#ifdef SYNTAX_TABLE
+
+char *re_syntax_table;
+
+#else
+
+static char re_syntax_table[256];
+
+static void
+init_syntax_once ()
+{
+   register int c;
+   static int done = 0;
+
+   if (done)
+     return;
+
+   bzero (re_syntax_table, sizeof re_syntax_table);
+
+   for (c = 'a'; c <= 'z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = 'A'; c <= 'Z'; c++)
+     re_syntax_table[c] = Sword;
+
+   for (c = '0'; c <= '9'; c++)
+     re_syntax_table[c] = Sword;
+
+   done = 1;
+}
+
+#endif /* SYNTAX_TABLE */
+#endif /* not emacs */
+
+#include "regex.h"
+
+/* Number of failure points to allocate space for initially,
+ when matching.  If this number is exceeded, more space is allocated,
+ so it is not a hard limit.  */
+
+#ifndef NFAILURES
+#define NFAILURES 80
+#endif /* NFAILURES */
+
+/* width of a byte in bits */
+
+#define BYTEWIDTH 8
+
+#ifndef SIGN_EXTEND_CHAR
+#define SIGN_EXTEND_CHAR(x) (x)
+#endif
+\f
+static int obscure_syntax = 0;
+
+/* Specify the precise syntax of regexp for compilation.
+   This provides for compatibility for various utilities
+   which historically have different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit-mask containing the two bits
+   RE_NO_BK_PARENS and RE_NO_BK_VBAR.  */
+
+int
+re_set_syntax (syntax)
+{
+  int ret;
+
+  ret = obscure_syntax;
+  obscure_syntax = syntax;
+  return ret;
+}
+\f
+/* re_compile_pattern takes a regular-expression string
+   and converts it into a buffer full of byte commands for matching.
+
+  PATTERN   is the address of the pattern string
+  SIZE      is the length of it.
+  BUFP     is a  struct re_pattern_buffer *  which points to the info
+           on where to store the byte commands.
+           This structure contains a  char *  which points to the
+           actual space, which should have been obtained with malloc.
+           re_compile_pattern may use  realloc  to grow the buffer space.
+
+  The number of bytes of commands can be found out by looking in
+  the  struct re_pattern_buffer  that bufp pointed to,
+  after re_compile_pattern returns.
+*/
+
+#define PATPUSH(ch) (*b++ = (char) (ch))
+
+#define PATFETCH(c) \
+ {if (p == pend) goto end_of_pattern; \
+  c = * (unsigned char *) p++; \
+  if (translate) c = translate[c]; }
+
+#define PATFETCH_RAW(c) \
+ {if (p == pend) goto end_of_pattern; \
+  c = * (unsigned char *) p++; }
+
+#define PATUNFETCH p--
+
+#define EXTEND_BUFFER \
+  { char *old_buffer = bufp->buffer; \
+    if (bufp->allocated == (1<<16)) goto too_big; \
+    bufp->allocated *= 2; \
+    if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
+    if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
+      goto memory_exhausted; \
+    c = bufp->buffer - old_buffer; \
+    b += c; \
+    if (fixup_jump) \
+      fixup_jump += c; \
+    if (laststart) \
+      laststart += c; \
+    begalt += c; \
+    if (pending_exact) \
+      pending_exact += c; \
+  }
+
+static int store_jump (), insert_jump ();
+
+char *
+re_compile_pattern (pattern, size, bufp)
+     char *pattern;
+     int size;
+     struct re_pattern_buffer *bufp;
+{
+  register char *b = bufp->buffer;
+  register char *p = pattern;
+  char *pend = pattern + size;
+  register unsigned c, c1;
+  char *p1;
+  unsigned char *translate = (unsigned char *) bufp->translate;
+
+  /* address of the count-byte of the most recently inserted "exactn" command.
+    This makes it possible to tell whether a new exact-match character
+    can be added to that command or requires a new "exactn" command. */
+     
+  char *pending_exact = 0;
+
+  /* address of the place where a forward-jump should go
+    to the end of the containing expression.
+    Each alternative of an "or", except the last, ends with a forward-jump
+    of this sort. */
+
+  char *fixup_jump = 0;
+
+  /* address of start of the most recently finished expression.
+    This tells postfix * where to find the start of its operand. */
+
+  char *laststart = 0;
+
+  /* In processing a repeat, 1 means zero matches is allowed */
+
+  char zero_times_ok;
+
+  /* In processing a repeat, 1 means many matches is allowed */
+
+  char many_times_ok;
+
+  /* address of beginning of regexp, or inside of last \( */
+
+  char *begalt = b;
+
+  /* Stack of information saved by \( and restored by \).
+     Four stack elements are pushed by each \(:
+       First, the value of b.
+       Second, the value of fixup_jump.
+       Third, the value of regnum.
+       Fourth, the value of begalt.  */
+
+  int stackb[40];
+  int *stackp = stackb;
+  int *stacke = stackb + 40;
+  int *stackt;
+
+  /* Counts \('s as they are encountered.  Remembered for the matching \),
+     where it becomes the "register number" to put in the stop_memory command */
+
+  int regnum = 1;
+
+  bufp->fastmap_accurate = 0;
+
+#ifndef emacs
+#ifndef SYNTAX_TABLE
+  /*
+   * Initialize the syntax table.
+   */
+   init_syntax_once();
+#endif
+#endif
+
+  if (bufp->allocated == 0)
+    {
+      bufp->allocated = 28;
+      if (bufp->buffer)
+       /* EXTEND_BUFFER loses when bufp->allocated is 0 */
+       bufp->buffer = (char *) realloc (bufp->buffer, 28);
+      else
+       /* Caller did not allocate a buffer.  Do it for him */
+       bufp->buffer = (char *) malloc (28);
+      if (!bufp->buffer) goto memory_exhausted;
+      begalt = b = bufp->buffer;
+    }
+
+  while (p != pend)
+    {
+      if (b - bufp->buffer > bufp->allocated - 10)
+       /* Note that EXTEND_BUFFER clobbers c */
+       EXTEND_BUFFER;
+
+      PATFETCH (c);
+
+      switch (c)
+       {
+       case '$':
+         if (obscure_syntax & RE_TIGHT_VBAR)
+           {
+             if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
+               goto normal_char;
+             /* Make operand of last vbar end before this `$'.  */
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             fixup_jump = 0;
+             PATPUSH (endline);
+             break;
+           }
+
+         /* $ means succeed if at end of line, but only in special contexts.
+           If randomly in the middle of a pattern, it is a normal character. */
+         if (p == pend || *p == '\n'
+             || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
+             || (obscure_syntax & RE_NO_BK_PARENS
+                 ? *p == ')'
+                 : *p == '\\' && p[1] == ')')
+             || (obscure_syntax & RE_NO_BK_VBAR
+                 ? *p == '|'
+                 : *p == '\\' && p[1] == '|'))
+           {
+             PATPUSH (endline);
+             break;
+           }
+         goto normal_char;
+
+       case '^':
+         /* ^ means succeed if at beg of line, but only if no preceding pattern. */
+
+         if (laststart && p[-2] != '\n'
+             && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+           goto normal_char;
+         if (obscure_syntax & RE_TIGHT_VBAR)
+           {
+             if (p != pattern + 1
+                 && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+               goto normal_char;
+             PATPUSH (begline);
+             begalt = b;
+           }
+         else
+           PATPUSH (begline);
+         break;
+
+       case '+':
+       case '?':
+         if (obscure_syntax & RE_BK_PLUS_QM)
+           goto normal_char;
+       handle_plus:
+       case '*':
+         /* If there is no previous pattern, char not special. */
+         if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+           goto normal_char;
+         /* If there is a sequence of repetition chars,
+            collapse it down to equivalent to just one.  */
+         zero_times_ok = 0;
+         many_times_ok = 0;
+         while (1)
+           {
+             zero_times_ok |= c != '+';
+             many_times_ok |= c != '?';
+             if (p == pend)
+               break;
+             PATFETCH (c);
+             if (c == '*')
+               ;
+             else if (!(obscure_syntax & RE_BK_PLUS_QM)
+                      && (c == '+' || c == '?'))
+               ;
+             else if ((obscure_syntax & RE_BK_PLUS_QM)
+                      && c == '\\')
+               {
+                 int c1;
+                 PATFETCH (c1);
+                 if (!(c1 == '+' || c1 == '?'))
+                   {
+                     PATUNFETCH;
+                     PATUNFETCH;
+                     break;
+                   }
+                 c = c1;
+               }
+             else
+               {
+                 PATUNFETCH;
+                 break;
+               }
+           }
+
+         /* Star, etc. applied to an empty pattern is equivalent
+            to an empty pattern.  */
+         if (!laststart)
+           break;
+
+         /* Now we know whether 0 matches is allowed,
+            and whether 2 or more matches is allowed.  */
+         if (many_times_ok)
+           {
+             /* If more than one repetition is allowed,
+                put in a backward jump at the end.  */
+             store_jump (b, maybe_finalize_jump, laststart - 3);
+             b += 3;
+           }
+         insert_jump (on_failure_jump, laststart, b + 3, b);
+         pending_exact = 0;
+         b += 3;
+         if (!zero_times_ok)
+           {
+             /* At least one repetition required: insert before the loop
+                a skip over the initial on-failure-jump instruction */
+             insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
+             b += 3;
+           }
+         break;
+
+       case '.':
+         laststart = b;
+         PATPUSH (anychar);
+         break;
+
+       case '[':
+         while (b - bufp->buffer
+                > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
+           /* Note that EXTEND_BUFFER clobbers c */
+           EXTEND_BUFFER;
+
+         laststart = b;
+         if (*p == '^')
+           PATPUSH (charset_not), p++;
+         else
+           PATPUSH (charset);
+         p1 = p;
+
+         PATPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+         /* Clear the whole map */
+         bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+         /* Read in characters and ranges, setting map bits */
+         while (1)
+           {
+             PATFETCH (c);
+             if (c == ']' && p != p1 + 1) break;
+             if (*p == '-' && p[1] != ']')
+               {
+                 PATFETCH (c1);
+                 PATFETCH (c1);
+                 while (c <= c1)
+                   b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH), c++;
+               }
+             else
+               {
+                 b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH);
+               }
+           }
+         /* Discard any bitmap bytes that are all 0 at the end of the map.
+            Decrement the map-length byte too. */
+         while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+           b[-1]--;
+         b += b[-1];
+         break;
+
+       case '(':
+         if (! (obscure_syntax & RE_NO_BK_PARENS))
+           goto normal_char;
+         else
+           goto handle_open;
+
+       case ')':
+         if (! (obscure_syntax & RE_NO_BK_PARENS))
+           goto normal_char;
+         else
+           goto handle_close;
+
+       case '\n':
+         if (! (obscure_syntax & RE_NEWLINE_OR))
+           goto normal_char;
+         else
+           goto handle_bar;
+
+       case '|':
+         if (! (obscure_syntax & RE_NO_BK_VBAR))
+           goto normal_char;
+         else
+           goto handle_bar;
+
+        case '\\':
+         if (p == pend) goto invalid_pattern;
+         PATFETCH_RAW (c);
+         switch (c)
+           {
+           case '(':
+             if (obscure_syntax & RE_NO_BK_PARENS)
+               goto normal_backsl;
+           handle_open:
+             if (stackp == stacke) goto nesting_too_deep;
+             if (regnum < RE_NREGS)
+               {
+                 PATPUSH (start_memory);
+                 PATPUSH (regnum);
+               }
+             *stackp++ = b - bufp->buffer;
+             *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
+             *stackp++ = regnum++;
+             *stackp++ = begalt - bufp->buffer;
+             fixup_jump = 0;
+             laststart = 0;
+             begalt = b;
+             break;
+
+           case ')':
+             if (obscure_syntax & RE_NO_BK_PARENS)
+               goto normal_backsl;
+           handle_close:
+             if (stackp == stackb) goto unmatched_close;
+             begalt = *--stackp + bufp->buffer;
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             if (stackp[-1] < RE_NREGS)
+               {
+                 PATPUSH (stop_memory);
+                 PATPUSH (stackp[-1]);
+               }
+             stackp -= 2;
+             fixup_jump = 0;
+             if (*stackp)
+               fixup_jump = *stackp + bufp->buffer - 1;
+             laststart = *--stackp + bufp->buffer;
+             break;
+
+           case '|':
+             if (obscure_syntax & RE_NO_BK_VBAR)
+               goto normal_backsl;
+           handle_bar:
+             insert_jump (on_failure_jump, begalt, b + 6, b);
+             pending_exact = 0;
+             b += 3;
+             if (fixup_jump)
+               store_jump (fixup_jump, jump, b);
+             fixup_jump = b;
+             b += 3;
+             laststart = 0;
+             begalt = b;
+             break;
+
+#ifdef emacs
+           case '=':
+             PATPUSH (at_dot);
+             break;
+
+           case 's':   
+             laststart = b;
+             PATPUSH (syntaxspec);
+             PATFETCH (c);
+             PATPUSH (syntax_spec_code[c]);
+             break;
+
+           case 'S':
+             laststart = b;
+             PATPUSH (notsyntaxspec);
+             PATFETCH (c);
+             PATPUSH (syntax_spec_code[c]);
+             break;
+#endif /* emacs */
+
+           case 'w':
+             laststart = b;
+             PATPUSH (wordchar);
+             break;
+
+           case 'W':
+             laststart = b;
+             PATPUSH (notwordchar);
+             break;
+
+           case '<':
+             PATPUSH (wordbeg);
+             break;
+
+           case '>':
+             PATPUSH (wordend);
+             break;
+
+           case 'b':
+             PATPUSH (wordbound);
+             break;
+
+           case 'B':
+             PATPUSH (notwordbound);
+             break;
+
+           case '`':
+             PATPUSH (begbuf);
+             break;
+
+           case '\'':
+             PATPUSH (endbuf);
+             break;
+
+           case '1':
+           case '2':
+           case '3':
+           case '4':
+           case '5':
+           case '6':
+           case '7':
+           case '8':
+           case '9':
+             c1 = c - '0';
+             if (c1 >= regnum)
+               goto normal_char;
+             for (stackt = stackp - 2;  stackt > stackb;  stackt -= 4)
+               if (*stackt == c1)
+                 goto normal_char;
+             laststart = b;
+             PATPUSH (duplicate);
+             PATPUSH (c1);
+             break;
+
+           case '+':
+           case '?':
+             if (obscure_syntax & RE_BK_PLUS_QM)
+               goto handle_plus;
+
+           default:
+           normal_backsl:
+             /* You might think it would be useful for \ to mean
+                not to translate; but if we don't translate it
+                it will never match anything.  */
+             if (translate) c = translate[c];
+             goto normal_char;
+           }
+         break;
+
+       default:
+       normal_char:
+         if (!pending_exact || pending_exact + *pending_exact + 1 != b
+             || *pending_exact == 0177 || *p == '*' || *p == '^'
+             || ((obscure_syntax & RE_BK_PLUS_QM)
+                 ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+                 : (*p == '+' || *p == '?')))
+           {
+             laststart = b;
+             PATPUSH (exactn);
+             pending_exact = b;
+             PATPUSH (0);
+           }
+         PATPUSH (c);
+         (*pending_exact)++;
+       }
+    }
+
+  if (fixup_jump)
+    store_jump (fixup_jump, jump, b);
+
+  if (stackp != stackb) goto unmatched_open;
+
+  bufp->used = b - bufp->buffer;
+  return 0;
+
+ invalid_pattern:
+  return "Invalid regular expression";
+
+ unmatched_open:
+  return "Unmatched \\(";
+
+ unmatched_close:
+  return "Unmatched \\)";
+
+ end_of_pattern:
+  return "Premature end of regular expression";
+
+ nesting_too_deep:
+  return "Nesting too deep";
+
+ too_big:
+  return "Regular expression too big";
+
+ memory_exhausted:
+  return "Memory exhausted";
+}
+
+/* Store where `from' points a jump operation to jump to where `to' points.
+  `opcode' is the opcode to store. */
+
+static int
+store_jump (from, opcode, to)
+     char *from, *to;
+     char opcode;
+{
+  from[0] = opcode;
+  from[1] = (to - (from + 3)) & 0377;
+  from[2] = (to - (from + 3)) >> 8;
+}
+
+/* Open up space at char FROM, and insert there a jump to TO.
+   CURRENT_END gives te end of the storage no in use,
+   so we know how much data to copy up.
+   OP is the opcode of the jump to insert.
+
+   If you call this function, you must zero out pending_exact.  */
+
+static int
+insert_jump (op, from, to, current_end)
+     char op;
+     char *from, *to, *current_end;
+{
+  register char *pto = current_end + 3;
+  register char *pfrom = current_end;
+  while (pfrom != from)
+    *--pto = *--pfrom;
+  store_jump (from, op, to);
+}
+\f
+/* Given a pattern, compute a fastmap from it.
+ The fastmap records which of the (1 << BYTEWIDTH) possible characters
+ can start a string that matches the pattern.
+ This fastmap is used by re_search to skip quickly over totally implausible text.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data area
+ as bufp->fastmap.
+ The other components of bufp describe the pattern to be used.  */
+
+void
+re_compile_fastmap (bufp)
+     struct re_pattern_buffer *bufp;
+{
+  unsigned char *pattern = (unsigned char *) bufp->buffer;
+  int size = bufp->used;
+  register char *fastmap = bufp->fastmap;
+  register unsigned char *p = pattern;
+  register unsigned char *pend = pattern + size;
+  register int j, k;
+  unsigned char *translate = (unsigned char *) bufp->translate;
+
+  unsigned char *stackb[NFAILURES];
+  unsigned char **stackp = stackb;
+
+  bzero (fastmap, (1 << BYTEWIDTH));
+  bufp->fastmap_accurate = 1;
+  bufp->can_be_null = 0;
+      
+  while (p)
+    {
+      if (p == pend)
+       {
+         bufp->can_be_null = 1;
+         break;
+       }
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((enum regexpcode) *p++))
+#else
+      switch ((enum regexpcode) *p++)
+#endif
+       {
+       case exactn:
+         if (translate)
+           fastmap[translate[p[1]]] = 1;
+         else
+           fastmap[p[1]] = 1;
+         break;
+
+        case begline:
+        case before_dot:
+       case at_dot:
+       case after_dot:
+       case begbuf:
+       case endbuf:
+       case wordbound:
+       case notwordbound:
+       case wordbeg:
+       case wordend:
+         continue;
+
+       case endline:
+         if (translate)
+           fastmap[translate['\n']] = 1;
+         else
+           fastmap['\n'] = 1;
+         if (bufp->can_be_null != 1)
+           bufp->can_be_null = 2;
+         break;
+
+       case finalize_jump:
+       case maybe_finalize_jump:
+       case jump:
+       case dummy_failure_jump:
+         bufp->can_be_null = 1;
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += j + 1;           /* The 1 compensates for missing ++ above */
+         if (j > 0)
+           continue;
+         /* Jump backward reached implies we just went through
+            the body of a loop and matched nothing.
+            Opcode jumped to should be an on_failure_jump.
+            Just treat it like an ordinary jump.
+            For a * loop, it has pushed its failure point already;
+            if so, discard that as redundant.  */
+         if ((enum regexpcode) *p != on_failure_jump)
+           continue;
+         p++;
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += j + 1;           /* The 1 compensates for missing ++ above */
+         if (stackp != stackb && *stackp == p)
+           stackp--;
+         continue;
+         
+       case on_failure_jump:
+         j = *p++ & 0377;
+         j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         *++stackp = p + j;
+         continue;
+
+       case start_memory:
+       case stop_memory:
+         p++;
+         continue;
+
+       case duplicate:
+         bufp->can_be_null = 1;
+         fastmap['\n'] = 1;
+       case anychar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (j != '\n')
+             fastmap[j] = 1;
+         if (bufp->can_be_null)
+           return;
+         /* Don't return; check the alternative paths
+            so we can set can_be_null if appropriate.  */
+         break;
+
+       case wordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == Sword)
+             fastmap[j] = 1;
+         break;
+
+       case notwordchar:
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != Sword)
+             fastmap[j] = 1;
+         break;
+
+#ifdef emacs
+       case syntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) == (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+
+       case notsyntaxspec:
+         k = *p++;
+         for (j = 0; j < (1 << BYTEWIDTH); j++)
+           if (SYNTAX (j) != (enum syntaxcode) k)
+             fastmap[j] = 1;
+         break;
+#endif /* emacs */
+
+       case charset:
+         for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+             {
+               if (translate)
+                 fastmap[translate[j]] = 1;
+               else
+                 fastmap[j] = 1;
+             }
+         break;
+
+       case charset_not:
+         /* Chars beyond end of map must be allowed */
+         for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+           if (translate)
+             fastmap[translate[j]] = 1;
+           else
+             fastmap[j] = 1;
+
+         for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+           if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+             {
+               if (translate)
+                 fastmap[translate[j]] = 1;
+               else
+                 fastmap[j] = 1;
+             }
+         break;
+       }
+
+      /* Get here means we have successfully found the possible starting characters
+        of one path of the pattern.  We need not follow this path any farther.
+        Instead, look at the next alternative remembered in the stack. */
+      if (stackp != stackb)
+       p = *stackp--;
+      else
+       break;
+    }
+}
+\f
+/* Like re_search_2, below, but only one string is specified. */
+
+int
+re_search (pbufp, string, size, startpos, range, regs)
+     struct re_pattern_buffer *pbufp;
+     char *string;
+     int size, startpos, range;
+     struct re_registers *regs;
+{
+  return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
+}
+
+/* Like re_match_2 but tries first a match starting at index STARTPOS,
+   then at STARTPOS + 1, and so on.
+   RANGE is the number of places to try before giving up.
+   If RANGE is negative, the starting positions tried are
+    STARTPOS, STARTPOS - 1, etc.
+   It is up to the caller to make sure that range is not so large
+   as to take the starting position outside of the input strings.
+
+The value returned is the position at which the match was found,
+ or -1 if no match was found,
+ or -2 if error (such as failure stack overflow).  */
+
+int
+re_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop)
+     struct re_pattern_buffer *pbufp;
+     char *string1, *string2;
+     int size1, size2;
+     int startpos;
+     register int range;
+     struct re_registers *regs;
+     int mstop;
+{
+  register char *fastmap = pbufp->fastmap;
+  register unsigned char *translate = (unsigned char *) pbufp->translate;
+  int total = size1 + size2;
+  int val;
+
+  /* Update the fastmap now if not correct already */
+  if (fastmap && !pbufp->fastmap_accurate)
+    re_compile_fastmap (pbufp);
+  
+  /* Don't waste time in a long search for a pattern
+     that says it is anchored.  */
+  if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
+      && range > 0)
+    {
+      if (startpos > 0)
+       return -1;
+      else
+       range = 1;
+    }
+
+  while (1)
+    {
+      /* If a fastmap is supplied, skip quickly over characters
+        that cannot possibly be the start of a match.
+        Note, however, that if the pattern can possibly match
+        the null string, we must test it at each starting point
+        so that we take the first null string we get.  */
+
+      if (fastmap && startpos < total && pbufp->can_be_null != 1)
+       {
+         if (range > 0)
+           {
+             register int lim = 0;
+             register unsigned char *p;
+             int irange = range;
+             if (startpos < size1 && startpos + range >= size1)
+               lim = range - (size1 - startpos);
+
+             p = ((unsigned char *)
+                  &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
+
+             if (translate)
+               {
+                 while (range > lim && !fastmap[translate[*p++]])
+                   range--;
+               }
+             else
+               {
+                 while (range > lim && !fastmap[*p++])
+                   range--;
+               }
+             startpos += irange - range;
+           }
+         else
+           {
+             register unsigned char c;
+             if (startpos >= size1)
+               c = string2[startpos - size1];
+             else
+               c = string1[startpos];
+             c &= 0xff;
+             if (translate ? !fastmap[translate[c]] : !fastmap[c])
+               goto advance;
+           }
+       }
+
+      if (range >= 0 && startpos == total
+         && fastmap && pbufp->can_be_null == 0)
+       return -1;
+
+      val = re_match_2 (pbufp, string1, size1, string2, size2, startpos, regs, mstop);
+      if (0 <= val)
+       {
+         if (val == -2)
+           return -2;
+         return startpos;
+       }
+
+#ifdef C_ALLOCA
+      alloca (0);
+#endif /* C_ALLOCA */
+
+    advance:
+      if (!range) break;
+      if (range > 0) range--, startpos++; else range++, startpos--;
+    }
+  return -1;
+}
+\f
+#ifndef emacs   /* emacs never uses this */
+int
+re_match (pbufp, string, size, pos, regs)
+     struct re_pattern_buffer *pbufp;
+     char *string;
+     int size, pos;
+     struct re_registers *regs;
+{
+  return re_match_2 (pbufp, 0, 0, string, size, pos, regs, size);
+}
+#endif /* emacs */
+
+/* Maximum size of failure stack.  Beyond this, overflow is an error.  */
+
+int re_max_failures = 2000;
+
+static int bcmp_translate();
+/* Match the pattern described by PBUFP
+   against data which is the virtual concatenation of STRING1 and STRING2.
+   SIZE1 and SIZE2 are the sizes of the two data strings.
+   Start the match at position POS.
+   Do not consider matching past the position MSTOP.
+
+   If pbufp->fastmap is nonzero, then it had better be up to date.
+
+   The reason that the data to match are specified as two components
+   which are to be regarded as concatenated
+   is so this function can be used directly on the contents of an Emacs buffer.
+
+   -1 is returned if there is no match.  -2 is returned if there is
+   an error (such as match stack overflow).  Otherwise the value is the length
+   of the substring which was matched.  */
+
+int
+re_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
+     struct re_pattern_buffer *pbufp;
+     unsigned char *string1, *string2;
+     int size1, size2;
+     int pos;
+     struct re_registers *regs;
+     int mstop;
+{
+  register unsigned char *p = (unsigned char *) pbufp->buffer;
+  register unsigned char *pend = p + pbufp->used;
+  /* End of first string */
+  unsigned char *end1;
+  /* End of second string */
+  unsigned char *end2;
+  /* Pointer just past last char to consider matching */
+  unsigned char *end_match_1, *end_match_2;
+  register unsigned char *d, *dend;
+  register int mcnt;
+  unsigned char *translate = (unsigned char *) pbufp->translate;
+
+ /* Failure point stack.  Each place that can handle a failure further down the line
+    pushes a failure point on this stack.  It consists of two char *'s.
+    The first one pushed is where to resume scanning the pattern;
+    the second pushed is where to resume scanning the strings.
+    If the latter is zero, the failure point is a "dummy".
+    If a failure happens and the innermost failure point is dormant,
+    it discards that failure point and tries the next one. */
+
+  unsigned char *initial_stack[2 * NFAILURES];
+  unsigned char **stackb = initial_stack;
+  unsigned char **stackp = stackb, **stacke = &stackb[2 * NFAILURES];
+
+  /* Information on the "contents" of registers.
+     These are pointers into the input strings; they record
+     just what was matched (on this attempt) by some part of the pattern.
+     The start_memory command stores the start of a register's contents
+     and the stop_memory command stores the end.
+
+     At that point, regstart[regnum] points to the first character in the register,
+     regend[regnum] points to the first character beyond the end of the register,
+     regstart_seg1[regnum] is true iff regstart[regnum] points into string1,
+     and regend_seg1[regnum] is true iff regend[regnum] points into string1.  */
+
+  unsigned char *regstart[RE_NREGS];
+  unsigned char *regend[RE_NREGS];
+  unsigned char regstart_seg1[RE_NREGS], regend_seg1[RE_NREGS];
+
+  /* Set up pointers to ends of strings.
+     Don't allow the second string to be empty unless both are empty.  */
+  if (!size2)
+    {
+      string2 = string1;
+      size2 = size1;
+      string1 = 0;
+      size1 = 0;
+    }
+  end1 = string1 + size1;
+  end2 = string2 + size2;
+
+  /* Compute where to stop matching, within the two strings */
+  if (mstop <= size1)
+    {
+      end_match_1 = string1 + mstop;
+      end_match_2 = string2;
+    }
+  else
+    {
+      end_match_1 = end1;
+      end_match_2 = string2 + mstop - size1;
+    }
+
+  /* Initialize \) text positions to -1
+     to mark ones that no \( or \) has been seen for.  */
+
+  for (mcnt = 0; mcnt < sizeof (regend) / sizeof (*regend); mcnt++)
+    regend[mcnt] = (unsigned char *) -1;
+
+  /* `p' scans through the pattern as `d' scans through the data.
+     `dend' is the end of the input string that `d' points within.
+     `d' is advanced into the following input string whenever necessary,
+     but this happens before fetching;
+     therefore, at the beginning of the loop,
+     `d' can be pointing at the end of a string,
+     but it cannot equal string2.  */
+
+  if (pos <= size1)
+    d = string1 + pos, dend = end_match_1;
+  else
+    d = string2 + pos - size1, dend = end_match_2;
+
+/* Write PREFETCH; just before fetching a character with *d.  */
+#define PREFETCH \
+ while (d == dend)                                                 \
+  { if (dend == end_match_2) goto fail;  /* end of string2 => failure */   \
+    d = string2;  /* end of string1 => advance to string2. */       \
+    dend = end_match_2; }
+
+  /* This loop loops over pattern commands.
+     It exits by returning from the function if match is complete,
+     or it drops through if match fails at this starting point in the input data. */
+
+  while (1)
+    {
+      if (p == pend)
+       /* End of pattern means we have succeeded! */
+       {
+         /* If caller wants register contents data back, convert it to indices */
+         if (regs)
+           {
+             regs->start[0] = pos;
+             if (dend == end_match_1)
+               regs->end[0] = d - string1;
+             else
+               regs->end[0] = d - string2 + size1;
+             for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+               {
+                 if (regend[mcnt] == (unsigned char *) -1)
+                   {
+                     regs->start[mcnt] = -1;
+                     regs->end[mcnt] = -1;
+                     continue;
+                   }
+                 if (regstart_seg1[mcnt])
+                   regs->start[mcnt] = regstart[mcnt] - string1;
+                 else
+                   regs->start[mcnt] = regstart[mcnt] - string2 + size1;
+                 if (regend_seg1[mcnt])
+                   regs->end[mcnt] = regend[mcnt] - string1;
+                 else
+                   regs->end[mcnt] = regend[mcnt] - string2 + size1;
+               }
+           }
+         if (dend == end_match_1)
+           return (d - string1 - pos);
+         else
+           return d - string2 + size1 - pos;
+       }
+
+      /* Otherwise match next pattern command */
+#ifdef SWITCH_ENUM_BUG
+      switch ((int) ((enum regexpcode) *p++))
+#else
+      switch ((enum regexpcode) *p++)
+#endif
+       {
+
+       /* \( is represented by a start_memory, \) by a stop_memory.
+           Both of those commands contain a "register number" argument.
+           The text matched within the \( and \) is recorded under that number.
+           Then, \<digit> turns into a `duplicate' command which
+           is followed by the numeric value of <digit> as the register number. */
+
+       case start_memory:
+         regstart[*p] = d;
+         regstart_seg1[*p++] = (dend == end_match_1);
+         break;
+
+       case stop_memory:
+         regend[*p] = d;
+         regend_seg1[*p++] = (dend == end_match_1);
+         break;
+
+       case duplicate:
+         {
+           int regno = *p++;   /* Get which register to match against */
+           register unsigned char *d2, *dend2;
+
+           d2 = regstart[regno];
+           dend2 = ((regstart_seg1[regno] == regend_seg1[regno])
+                    ? regend[regno] : end_match_1);
+           while (1)
+             {
+               /* Advance to next segment in register contents, if necessary */
+               while (d2 == dend2)
+                 {
+                   if (dend2 == end_match_2) break;
+                   if (dend2 == regend[regno]) break;
+                   d2 = string2, dend2 = regend[regno];  /* end of string1 => advance to string2. */
+                 }
+               /* At end of register contents => success */
+               if (d2 == dend2) break;
+
+               /* Advance to next segment in data being matched, if necessary */
+               PREFETCH;
+
+               /* mcnt gets # consecutive chars to compare */
+               mcnt = dend - d;
+               if (mcnt > dend2 - d2)
+                 mcnt = dend2 - d2;
+               /* Compare that many; failure if mismatch, else skip them. */
+               if (translate ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt))
+                 goto fail;
+               d += mcnt, d2 += mcnt;
+             }
+         }
+         break;
+
+       case anychar:
+         /* fetch a data character */
+         PREFETCH;
+         /* Match anything but a newline.  */
+         if ((translate ? translate[*d++] : *d++) == '\n')
+           goto fail;
+         break;
+
+       case charset:
+       case charset_not:
+         {
+           /* Nonzero for charset_not */
+           int not = 0;
+           register int c;
+           if (*(p - 1) == (unsigned char) charset_not)
+             not = 1;
+
+           /* fetch a data character */
+           PREFETCH;
+
+           if (translate)
+             c = translate [*d];
+           else
+             c = *d;
+
+           if (c < *p * BYTEWIDTH
+               && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+             not = !not;
+
+           p += 1 + *p;
+
+           if (!not) goto fail;
+           d++;
+           break;
+         }
+
+       case begline:
+         if (d == string1 || d[-1] == '\n')
+           break;
+         goto fail;
+
+       case endline:
+         if (d == end2
+             || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
+           break;
+         goto fail;
+
+       /* "or" constructs ("|") are handled by starting each alternative
+           with an on_failure_jump that points to the start of the next alternative.
+           Each alternative except the last ends with a jump to the joining point.
+           (Actually, each jump except for the last one really jumps
+            to the following jump, because tensioning the jumps is a hassle.) */
+
+       /* The start of a stupid repeat has an on_failure_jump that points
+          past the end of the repeat text.
+          This makes a failure point so that, on failure to match a repetition,
+          matching restarts past as many repetitions have been found
+          with no way to fail and look for another one.  */
+
+       /* A smart repeat is similar but loops back to the on_failure_jump
+          so that each repetition makes another failure point. */
+
+       case on_failure_jump:
+         if (stackp == stacke)
+           {
+             unsigned char **stackx;
+             if (stacke - stackb > re_max_failures * 2)
+               return -2;
+             stackx = (unsigned char **) alloca (2 * (stacke - stackb)
+                                        * sizeof (char *));
+             bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
+             stackp = stackx + (stackp - stackb);
+             stacke = stackx + 2 * (stacke - stackb);
+             stackb = stackx;
+           }
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         *stackp++ = mcnt + p;
+         *stackp++ = d;
+         break;
+
+       /* The end of a smart repeat has an maybe_finalize_jump back.
+          Change it either to a finalize_jump or an ordinary jump. */
+
+       case maybe_finalize_jump:
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p++;
+         {
+           register unsigned char *p2 = p;
+           /* Compare what follows with the begining of the repeat.
+              If we can establish that there is nothing that they would
+              both match, we can change to finalize_jump */
+           while (p2 != pend
+                  && (*p2 == (unsigned char) stop_memory
+                      || *p2 == (unsigned char) start_memory))
+             p2++;
+           if (p2 == pend)
+             p[-3] = (unsigned char) finalize_jump;
+           else if (*p2 == (unsigned char) exactn
+                    || *p2 == (unsigned char) endline)
+             {
+               register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
+               register unsigned char *p1 = p + mcnt;
+               /* p1[0] ... p1[2] are an on_failure_jump.
+                  Examine what follows that */
+               if (p1[3] == (unsigned char) exactn && p1[5] != c)
+                 p[-3] = (unsigned char) finalize_jump;
+               else if (p1[3] == (unsigned char) charset
+                        || p1[3] == (unsigned char) charset_not)
+                 {
+                   int not = p1[3] == (unsigned char) charset_not;
+                   if (c < p1[4] * BYTEWIDTH
+                       && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+                     not = !not;
+                   /* not is 1 if c would match */
+                   /* That means it is not safe to finalize */
+                   if (!not)
+                     p[-3] = (unsigned char) finalize_jump;
+                 }
+             }
+         }
+         p -= 2;
+         if (p[-1] != (unsigned char) finalize_jump)
+           {
+             p[-1] = (unsigned char) jump;
+             goto nofinalize;
+           }
+
+       /* The end of a stupid repeat has a finalize-jump
+          back to the start, where another failure point will be made
+          which will point after all the repetitions found so far. */
+
+       case finalize_jump:
+         stackp -= 2;
+
+       case jump:
+       nofinalize:
+         mcnt = *p++ & 0377;
+         mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
+         p += mcnt + 1;        /* The 1 compensates for missing ++ above */
+         break;
+
+       case dummy_failure_jump:
+         if (stackp == stacke)
+           {
+             unsigned char **stackx
+               = (unsigned char **) alloca (2 * (stacke - stackb)
+                                            * sizeof (char *));
+             bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
+             stackp = stackx + (stackp - stackb);
+             stacke = stackx + 2 * (stacke - stackb);
+             stackb = stackx;
+           }
+         *stackp++ = 0;
+         *stackp++ = 0;
+         goto nofinalize;
+
+       case wordbound:
+         if (d == string1  /* Points to first char */
+             || d == end2  /* Points to end */
+             || (d == end1 && size2 == 0)) /* Points to end */
+           break;
+         if ((SYNTAX (d[-1]) == Sword)
+             != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+           break;
+         goto fail;
+
+       case notwordbound:
+         if (d == string1  /* Points to first char */
+             || d == end2  /* Points to end */
+             || (d == end1 && size2 == 0)) /* Points to end */
+           goto fail;
+         if ((SYNTAX (d[-1]) == Sword)
+             != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
+           goto fail;
+         break;
+
+       case wordbeg:
+         if (d == end2  /* Points to end */
+             || (d == end1 && size2 == 0) /* Points to end */
+             || SYNTAX (* (d == end1 ? string2 : d)) != Sword) /* Next char not a letter */
+           goto fail;
+         if (d == string1  /* Points to first char */
+             || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
+           break;
+         goto fail;
+
+       case wordend:
+         if (d == string1  /* Points to first char */
+             || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
+           goto fail;
+         if (d == end2  /* Points to end */
+             || (d == end1 && size2 == 0) /* Points to end */
+             || SYNTAX (d == end1 ? *string2 : *d) != Sword) /* Next char not a letter */
+           break;
+         goto fail;
+
+#ifdef emacs
+       case before_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             <= point)
+           goto fail;
+         break;
+
+       case at_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             == point)
+           goto fail;
+         break;
+
+       case after_dot:
+         if (((d - string2 <= (unsigned) size2)
+              ? d - bf_p2 : d - bf_p1)
+             >= point)
+           goto fail;
+         break;
+
+       case wordchar:
+         mcnt = (int) Sword;
+         goto matchsyntax;
+
+       case syntaxspec:
+         mcnt = *p++;
+       matchsyntax:
+         PREFETCH;
+         if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
+         break;
+         
+       case notwordchar:
+         mcnt = (int) Sword;
+         goto matchnotsyntax;
+
+       case notsyntaxspec:
+         mcnt = *p++;
+       matchnotsyntax:
+         PREFETCH;
+         if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
+         break;
+#else
+       case wordchar:
+         PREFETCH;
+         if (SYNTAX (*d++) == 0) goto fail;
+         break;
+         
+       case notwordchar:
+         PREFETCH;
+         if (SYNTAX (*d++) != 0) goto fail;
+         break;
+#endif /* not emacs */
+
+       case begbuf:
+         if (d == string1)     /* Note, d cannot equal string2 */
+           break;              /* unless string1 == string2.  */
+         goto fail;
+
+       case endbuf:
+         if (d == end2 || (d == end1 && size2 == 0))
+           break;
+         goto fail;
+
+       case exactn:
+         /* Match the next few pattern characters exactly.
+            mcnt is how many characters to match. */
+         mcnt = *p++;
+         if (translate)
+           {
+             do
+               {
+                 PREFETCH;
+                 if (translate[*d++] != *p++) goto fail;
+               }
+             while (--mcnt);
+           }
+         else
+           {
+             do
+               {
+                 PREFETCH;
+                 if (*d++ != *p++) goto fail;
+               }
+             while (--mcnt);
+           }
+         break;
+       }
+      continue;    /* Successfully matched one pattern command; keep matching */
+
+      /* Jump here if any matching operation fails. */
+    fail:
+      if (stackp != stackb)
+       /* A restart point is known.  Restart there and pop it. */
+       {
+         if (!stackp[-2])
+           {   /* If innermost failure point is dormant, flush it and keep looking */
+             stackp -= 2;
+             goto fail;
+           }
+         d = *--stackp;
+         p = *--stackp;
+         if (d >= string1 && d <= end1)
+           dend = end_match_1;
+       }
+      else break;   /* Matching at this starting point really fails! */
+    }
+  return -1;         /* Failure to match */
+}
+
+static int
+bcmp_translate (s1, s2, len, translate)
+     unsigned char *s1, *s2;
+     register int len;
+     unsigned char *translate;
+{
+  register unsigned char *p1 = s1, *p2 = s2;
+  while (len)
+    {
+      if (translate [*p1++] != translate [*p2++]) return 1;
+      len--;
+    }
+  return 0;
+}
+\f
+/* Entry points compatible with bsd4.2 regex library */
+
+#ifndef emacs
+
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+     char *s;
+{
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+       return "No previous regular expression";
+      return 0;
+    }
+
+  if (!re_comp_buf.buffer)
+    {
+      if (!(re_comp_buf.buffer = (char *) malloc (200)))
+       return "Memory exhausted";
+      re_comp_buf.allocated = 200;
+      if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
+       return "Memory exhausted";
+    }
+  return re_compile_pattern (s, strlen (s), &re_comp_buf);
+}
+
+int
+re_exec (s)
+     char *s;
+{
+  int len = strlen (s);
+  return 0 <= re_search (&re_comp_buf, s, len, 0, len, 0);
+}
+
+#endif /* emacs */
+\f
+#ifdef test
+
+#include <stdio.h>
+
+/* Indexed by a character, gives the upper case equivalent of the character */
+
+static char upcase[0400] = 
+  { 000, 001, 002, 003, 004, 005, 006, 007,
+    010, 011, 012, 013, 014, 015, 016, 017,
+    020, 021, 022, 023, 024, 025, 026, 027,
+    030, 031, 032, 033, 034, 035, 036, 037,
+    040, 041, 042, 043, 044, 045, 046, 047,
+    050, 051, 052, 053, 054, 055, 056, 057,
+    060, 061, 062, 063, 064, 065, 066, 067,
+    070, 071, 072, 073, 074, 075, 076, 077,
+    0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+    0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+    0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+    0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+    0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+    0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+    0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+    0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+    0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+    0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+    0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+    0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+    0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+    0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+    0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+    0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+    0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+    0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+    0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+    0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+  };
+
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  char pat[80];
+  struct re_pattern_buffer buf;
+  int i;
+  char c;
+  char fastmap[(1 << BYTEWIDTH)];
+
+  /* Allow a command argument to specify the style of syntax.  */
+  if (argc > 1)
+    obscure_syntax = atoi (argv[1]);
+
+  buf.allocated = 40;
+  buf.buffer = (char *) malloc (buf.allocated);
+  buf.fastmap = fastmap;
+  buf.translate = upcase;
+
+  while (1)
+    {
+      gets (pat);
+
+      if (*pat)
+       {
+          re_compile_pattern (pat, strlen(pat), &buf);
+
+         for (i = 0; i < buf.used; i++)
+           printchar (buf.buffer[i]);
+
+         putchar ('\n');
+
+         printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
+
+         re_compile_fastmap (&buf);
+         printf ("Allowed by fastmap: ");
+         for (i = 0; i < (1 << BYTEWIDTH); i++)
+           if (fastmap[i]) printchar (i);
+         putchar ('\n');
+       }
+
+      gets (pat);      /* Now read the string to match against */
+
+      i = re_match (&buf, pat, strlen (pat), 0, 0);
+      printf ("Match value %d.\n", i);
+    }
+}
+
+#ifdef NOTDEF
+print_buf (bufp)
+     struct re_pattern_buffer *bufp;
+{
+  int i;
+
+  printf ("buf is :\n----------------\n");
+  for (i = 0; i < bufp->used; i++)
+    printchar (bufp->buffer[i]);
+  
+  printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
+  
+  printf ("Allowed by fastmap: ");
+  for (i = 0; i < (1 << BYTEWIDTH); i++)
+    if (bufp->fastmap[i])
+      printchar (i);
+  printf ("\nAllowed by translate: ");
+  if (bufp->translate)
+    for (i = 0; i < (1 << BYTEWIDTH); i++)
+      if (bufp->translate[i])
+       printchar (i);
+  printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
+  printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
+}
+#endif
+
+printchar (c)
+     char c;
+{
+  if (c < 041 || c >= 0177)
+    {
+      putchar ('\\');
+      putchar (((c >> 6) & 3) + '0');
+      putchar (((c >> 3) & 7) + '0');
+      putchar ((c & 7) + '0');
+    }
+  else
+    putchar (c);
+}
+
+error (string)
+     char *string;
+{
+  puts (string);
+  exit (1);
+}
+
+#endif /* test */
diff --git a/gdb/regex.h b/gdb/regex.h
new file mode 100644 (file)
index 0000000..d0d8a82
--- /dev/null
@@ -0,0 +1,185 @@
+/* Definitions for data structures callers pass the regex library.
+   Copyright (C) 1985, 1989 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  */
+
+
+/* Define number of parens for which we record the beginnings and ends.
+   This affects how much space the `struct re_registers' type takes up.  */
+#ifndef RE_NREGS
+#define RE_NREGS 10
+#endif
+
+/* These bits are used in the obscure_syntax variable to choose among
+   alternative regexp syntaxes.  */
+
+/* 1 means plain parentheses serve as grouping, and backslash
+     parentheses are needed for literal searching.
+   0 means backslash-parentheses are grouping, and plain parentheses
+     are for literal searching.  */
+#define RE_NO_BK_PARENS 1
+
+/* 1 means plain | serves as the "or"-operator, and \| is a literal.
+   0 means \| serves as the "or"-operator, and | is a literal.  */
+#define RE_NO_BK_VBAR 2
+
+/* 0 means plain + or ? serves as an operator, and \+, \? are literals.
+   1 means \+, \? are operators and plain +, ? are literals.  */
+#define RE_BK_PLUS_QM 4
+
+/* 1 means | binds tighter than ^ or $.
+   0 means the contrary.  */
+#define RE_TIGHT_VBAR 8
+
+/* 1 means treat \n as an _OR operator
+   0 means treat it as a normal character */
+#define RE_NEWLINE_OR 16
+
+/* 0 means that a special characters (such as *, ^, and $) always have
+     their special meaning regardless of the surrounding context.
+   1 means that special characters may act as normal characters in some
+     contexts.  Specifically, this applies to:
+       ^ - only special at the beginning, or after ( or |
+       $ - only special at the end, or before ) or |
+       *, +, ? - only special when not after the beginning, (, or | */
+#define RE_CONTEXT_INDEP_OPS 32
+
+/* Now define combinations of bits for the standard possibilities.  */
+#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS)
+#define RE_SYNTAX_EGREP (RE_SYNTAX_AWK | RE_NEWLINE_OR)
+#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+#define RE_SYNTAX_EMACS 0
+
+/* This data structure is used to represent a compiled pattern. */
+
+struct re_pattern_buffer
+  {
+    char *buffer;      /* Space holding the compiled pattern commands. */
+    int allocated;     /* Size of space that  buffer  points to */
+    int used;          /* Length of portion of buffer actually occupied */
+    char *fastmap;     /* Pointer to fastmap, if any, or zero if none. */
+                       /* re_search uses the fastmap, if there is one,
+                          to skip quickly over totally implausible characters */
+    char *translate;   /* Translate table to apply to all characters before comparing.
+                          Or zero for no translation.
+                          The translation is applied to a pattern when it is compiled
+                          and to data when it is matched. */
+    char fastmap_accurate;
+                       /* Set to zero when a new pattern is stored,
+                          set to one when the fastmap is updated from it. */
+    char can_be_null;   /* Set to one by compiling fastmap
+                          if this pattern might match the null string.
+                          It does not necessarily match the null string
+                          in that case, but if this is zero, it cannot.
+                          2 as value means can match null string
+                          but at end of range or before a character
+                          listed in the fastmap.  */
+  };
+
+/* Structure to store "register" contents data in.
+
+   Pass the address of such a structure as an argument to re_match, etc.,
+   if you want this information back.
+
+   start[i] and end[i] record the string matched by \( ... \) grouping i,
+   for i from 1 to RE_NREGS - 1.
+   start[0] and end[0] record the entire string matched. */
+
+struct re_registers
+  {
+    int start[RE_NREGS];
+    int end[RE_NREGS];
+  };
+
+/* These are the command codes that appear in compiled regular expressions, one per byte.
+  Some command codes are followed by argument bytes.
+  A command code can specify any interpretation whatever for its arguments.
+  Zero-bytes may appear in the compiled regular expression. */
+
+enum regexpcode
+  {
+    unused,
+    exactn,    /* followed by one byte giving n, and then by n literal bytes */
+    begline,   /* fails unless at beginning of line */
+    endline,   /* fails unless at end of line */
+    jump,       /* followed by two bytes giving relative address to jump to */
+    on_failure_jump,    /* followed by two bytes giving relative address of place
+                           to resume at in case of failure. */
+    finalize_jump,      /* Throw away latest failure point and then jump to address. */
+    maybe_finalize_jump, /* Like jump but finalize if safe to do so.
+                           This is used to jump back to the beginning
+                           of a repeat.  If the command that follows
+                           this jump is clearly incompatible with the
+                           one at the beginning of the repeat, such that
+                           we can be sure that there is no use backtracking
+                           out of repetitions already completed,
+                           then we finalize. */
+    dummy_failure_jump,  /* jump, and push a dummy failure point.
+                           This failure point will be thrown away
+                           if an attempt is made to use it for a failure.
+                           A + construct makes this before the first repeat.  */
+    anychar,    /* matches any one character */
+    charset,     /* matches any one char belonging to specified set.
+                   First following byte is # bitmap bytes.
+                   Then come bytes for a bit-map saying which chars are in.
+                   Bits in each byte are ordered low-bit-first.
+                   A character is in the set if its bit is 1.
+                   A character too large to have a bit in the map
+                   is automatically not in the set */
+    charset_not, /* similar but match any character that is NOT one of those specified */
+    start_memory, /* starts remembering the text that is matched
+                   and stores it in a memory register.
+                   followed by one byte containing the register number.
+                   Register numbers must be in the range 0 through NREGS. */
+    stop_memory, /* stops remembering the text that is matched
+                   and stores it in a memory register.
+                   followed by one byte containing the register number.
+                   Register numbers must be in the range 0 through NREGS. */
+    duplicate,    /* match a duplicate of something remembered.
+                   Followed by one byte containing the index of the memory register. */
+    before_dot,         /* Succeeds if before dot */
+    at_dot,     /* Succeeds if at dot */
+    after_dot,  /* Succeeds if after dot */
+    begbuf,      /* Succeeds if at beginning of buffer */
+    endbuf,      /* Succeeds if at end of buffer */
+    wordchar,    /* Matches any word-constituent character */
+    notwordchar, /* Matches any char that is not a word-constituent */
+    wordbeg,    /* Succeeds if at word beginning */
+    wordend,    /* Succeeds if at word end */
+    wordbound,   /* Succeeds if at a word boundary */
+    notwordbound, /* Succeeds if not at a word boundary */
+    syntaxspec,  /* Matches any character whose syntax is specified.
+                   followed by a byte which contains a syntax code, Sword or such like */
+    notsyntaxspec /* Matches any character whose syntax differs from the specified. */
+  };
+\f
+extern char *re_compile_pattern ();
+/* Is this really advertised? */
+extern void re_compile_fastmap ();
+extern int re_search (), re_search_2 ();
+extern int re_match (), re_match_2 ();
+
+/* 4.2 bsd compatibility (yuck) */
+extern char *re_comp ();
+extern int re_exec ();
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#endif
diff --git a/gdb/remote-eb.c b/gdb/remote-eb.c
new file mode 100644 (file)
index 0000000..a140905
--- /dev/null
@@ -0,0 +1,932 @@
+/* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB.
+   Copyright 1990-1991 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is like remote.c but is for an esoteric situation--
+   having a 29k board in a PC hooked up to a unix machine with
+   a serial line, and running ctty com1 on the PC, through which
+   the unix machine can run ebmon.  Not to mention that the PC
+   has PC/NFS, so it can access the same executables that gdb can,
+   over the net in real time.  */
+
+#include <stdio.h>
+#include <string.h>
+#include "defs.h"
+#include "tm-29k.h"
+#include "param-no-tm.h"
+#include "inferior.h"
+#include "wait.h"
+#include "value.h"
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include "terminal.h"
+#include "target.h"
+
+extern void add_syms_addr_command ();
+extern struct value *call_function_by_hand();
+
+extern struct target_ops eb_ops;               /* Forward declaration */
+
+#define LOG_FILE "eb.log"
+#if defined (LOG_FILE)
+FILE *log_file;
+#endif
+
+static int timeout = 5;
+
+/* Descriptor for I/O to remote machine.  Initialize it to -1 so that
+   eb_open knows that we don't have a file open when the program
+   starts.  */
+int eb_desc = -1;
+
+/* stream which is fdopen'd from eb_desc.  Only valid when
+   eb_desc != -1.  */
+FILE *eb_stream;
+
+/* Read a character from the remote system, doing all the fancy
+   timeout stuff.  */
+static int
+readchar ()
+{
+  char buf;
+
+  buf = '\0';
+#ifdef HAVE_TERMIO
+  /* termio does the timeout for us.  */
+  read (eb_desc, &buf, 1);
+#else
+  alarm (timeout);
+  if (read (eb_desc, &buf, 1) < 0)
+    {
+      if (errno == EINTR)
+       error ("Timeout reading from remote system.");
+      else
+       perror_with_name ("remote");
+    }
+  alarm (0);
+#endif
+
+  if (buf == '\0')
+    error ("Timeout reading from remote system.");
+#if defined (LOG_FILE)
+  putc (buf & 0x7f, log_file);
+#endif
+  return buf & 0x7f;
+}
+
+/* Keep discarding input from the remote system, until STRING is found. 
+   Let the user break out immediately.  */
+static void
+expect (string)
+     char *string;
+{
+  char *p = string;
+
+  immediate_quit = 1;
+  while (1)
+    {
+      if (readchar() == *p)
+       {
+         p++;
+         if (*p == '\0')
+           {
+             immediate_quit = 0;
+             return;
+           }
+       }
+      else
+       p = string;
+    }
+}
+
+/* Keep discarding input until we see the ebmon prompt.
+
+   The convention for dealing with the prompt is that you
+   o give your command
+   o *then* wait for the prompt.
+
+   Thus the last thing that a procedure does with the serial line
+   will be an expect_prompt().  Exception:  eb_resume does not
+   wait for the prompt, because the terminal is being handed over
+   to the inferior.  However, the next thing which happens after that
+   is a eb_wait which does wait for the prompt.
+   Note that this includes abnormal exit, e.g. error().  This is
+   necessary to prevent getting into states from which we can't
+   recover.  */
+static void
+expect_prompt ()
+{
+#if defined (LOG_FILE)
+  /* This is a convenient place to do this.  The idea is to do it often
+     enough that we never lose much data if we terminate abnormally.  */
+  fflush (log_file);
+#endif
+  expect ("\n# ");
+}
+
+/* Get a hex digit from the remote system & return its value.
+   If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
+static int
+get_hex_digit (ignore_space)
+     int ignore_space;
+{
+  int ch;
+  while (1)
+    {
+      ch = readchar ();
+      if (ch >= '0' && ch <= '9')
+       return ch - '0';
+      else if (ch >= 'A' && ch <= 'F')
+       return ch - 'A' + 10;
+      else if (ch >= 'a' && ch <= 'f')
+       return ch - 'a' + 10;
+      else if (ch == ' ' && ignore_space)
+       ;
+      else
+       {
+         expect_prompt ();
+         error ("Invalid hex digit from remote system.");
+       }
+    }
+}
+
+/* Get a byte from eb_desc and put it in *BYT.  Accept any number
+   leading spaces.  */
+static void
+get_hex_byte (byt)
+     char *byt;
+{
+  int val;
+
+  val = get_hex_digit (1) << 4;
+  val |= get_hex_digit (0);
+  *byt = val;
+}
+
+/* Get N 32-bit words from remote, each preceded by a space,
+   and put them in registers starting at REGNO.  */
+static void
+get_hex_regs (n, regno)
+     int n;
+     int regno;
+{
+  long val;
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      int j;
+      
+      val = 0;
+      for (j = 0; j < 8; j++)
+       val = (val << 4) + get_hex_digit (j == 0);
+      supply_register (regno++, &val);
+    }
+}
+
+/* Called when SIGALRM signal sent due to alarm() timeout.  */
+#ifndef HAVE_TERMIO
+
+#ifndef __STDC__
+#define volatile /**/
+#endif
+volatile int n_alarms;
+
+void
+eb_timer ()
+{
+#if 0
+  if (kiodebug)
+    printf ("eb_timer called\n");
+#endif
+  n_alarms++;
+}
+#endif
+
+/* malloc'd name of the program on the remote system.  */
+static char *prog_name = NULL;
+
+/* Nonzero if we have loaded the file ("yc") and not yet issued a "gi"
+   command.  "gi" is supposed to happen exactly once for each "yc".  */
+static int need_gi = 0;
+
+/* Number of SIGTRAPs we need to simulate.  That is, the next
+   NEED_ARTIFICIAL_TRAP calls to eb_wait should just return
+   SIGTRAP without actually waiting for anything.  */
+
+static int need_artificial_trap = 0;
+
+/* This is called not only when we first attach, but also when the
+   user types "run" after having attached.  */
+void
+eb_start (inferior_args)
+char *inferior_args;
+{
+  /* OK, now read in the file.  Y=read, C=COFF, D=no symbols
+     0=start address, %s=filename.  */
+
+  fprintf (eb_stream, "YC D,0:%s", prog_name);
+
+  if (inferior_args != NULL)
+      fprintf(eb_stream, " %s", inferior_args);
+
+  fprintf (eb_stream, "\n");
+  fflush (eb_stream);
+
+  expect_prompt ();
+
+  need_gi = 1;
+}
+
+/* Translate baud rates from integers to damn B_codes.  Unix should
+   have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
+
+#ifndef B19200
+#define B19200 EXTA
+#endif
+#ifndef B38400
+#define B38400 EXTB
+#endif
+
+struct {int rate, damn_b;} baudtab[] = {
+       {0, B0},
+       {50, B50},
+       {75, B75},
+       {110, B110},
+       {134, B134},
+       {150, B150},
+       {200, B200},
+       {300, B300},
+       {600, B600},
+       {1200, B1200},
+       {1800, B1800},
+       {2400, B2400},
+       {4800, B4800},
+       {9600, B9600},
+       {19200, B19200},
+       {38400, B38400},
+       {-1, -1},
+};
+
+int damn_b (rate)
+     int rate;
+{
+  int i;
+
+  for (i = 0; baudtab[i].rate != -1; i++)
+    if (rate == baudtab[i].rate) return baudtab[i].damn_b;
+  return B38400;       /* Random */
+}
+
+
+/* Open a connection to a remote debugger.
+   NAME is the filename used for communication, then a space,
+   then the name of the program as we should name it to EBMON.  */
+
+static int baudrate = 9600;
+static char *dev_name;
+void
+eb_open (name, from_tty)
+     char *name;
+     int from_tty;
+{
+  TERMINAL sg;
+
+  char *p;
+
+  /* Find the first whitespace character, it separates dev_name from
+     prog_name.  */
+  if (name == 0)
+    goto erroid;
+
+  for (p = name;
+       *p != '\0' && !isspace (*p); p++)
+    ;
+  if (*p == '\0')
+erroid:
+    error ("\
+Please include the name of the device for the serial port,\n\
+the baud rate, and the name of the program to run on the remote system.");
+  dev_name = alloca (p - name + 1);
+  strncpy (dev_name, name, p - name);
+  dev_name[p - name] = '\0';
+
+  /* Skip over the whitespace after dev_name */
+  for (; isspace (*p); p++)
+    /*EMPTY*/;
+  
+  if (1 != sscanf (p, "%d ", &baudrate))
+    goto erroid;
+
+  /* Skip the number and then the spaces */
+  for (; isdigit (*p); p++)
+    /*EMPTY*/;
+  for (; isspace (*p); p++)
+    /*EMPTY*/;
+  
+  if (prog_name != NULL)
+    free (prog_name);
+  prog_name = savestring (p, strlen (p));
+
+  eb_close (0);
+
+  eb_desc = open (dev_name, O_RDWR);
+  if (eb_desc < 0)
+    perror_with_name (dev_name);
+  ioctl (eb_desc, TIOCGETP, &sg);
+#ifdef HAVE_TERMIO
+  sg.c_cc[VMIN] = 0;           /* read with timeout.  */
+  sg.c_cc[VTIME] = timeout * 10;
+  sg.c_lflag &= ~(ICANON | ECHO);
+  sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
+#else
+  sg.sg_ispeed = damn_b (baudrate);
+  sg.sg_ospeed = damn_b (baudrate);
+  sg.sg_flags |= RAW | ANYP;
+  sg.sg_flags &= ~ECHO;
+#endif
+
+  ioctl (eb_desc, TIOCSETP, &sg);
+  eb_stream = fdopen (eb_desc, "r+");
+
+  push_target (&eb_ops);
+  if (from_tty)
+    printf ("Remote %s debugging %s using %s\n", target_shortname,
+           prog_name, dev_name);
+
+#ifndef HAVE_TERMIO
+#ifndef NO_SIGINTERRUPT
+  /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
+     the read.  */
+  if (siginterrupt (SIGALRM, 1) != 0)
+    perror ("eb_open: error in siginterrupt");
+#endif
+
+  /* Set up read timeout timer.  */
+  if ((void (*)) signal (SIGALRM, eb_timer) == (void (*)) -1)
+    perror ("eb_open: error in signal");
+#endif
+
+#if defined (LOG_FILE)
+  log_file = fopen (LOG_FILE, "w");
+  if (log_file == NULL)
+    perror_with_name (LOG_FILE);
+#endif
+
+  /* Hello?  Are you there?  */
+  write (eb_desc, "\n", 1);
+  
+  expect_prompt ();
+}
+
+/* Close out all files and local state before this target loses control. */
+
+void
+eb_close (quitting)
+     int quitting;
+{
+
+  /* Due to a bug in Unix, fclose closes not only the stdio stream,
+     but also the file descriptor.  So we don't actually close
+     eb_desc.  */
+  if (eb_stream)
+    fclose (eb_stream);        /* This also closes eb_desc */
+  if (eb_desc >= 0)
+    /* close (eb_desc); */
+
+  /* Do not try to close eb_desc again, later in the program.  */
+  eb_stream = NULL;
+  eb_desc = -1;
+
+#if defined (LOG_FILE)
+  if (ferror (log_file))
+    printf ("Error writing log file.\n");
+  if (fclose (log_file) != 0)
+    printf ("Error closing log file.\n");
+#endif
+}
+
+/* Terminate the open connection to the remote debugger.
+   Use this when you want to detach and do something else
+   with your gdb.  */
+void
+eb_detach (from_tty)
+     int from_tty;
+{
+  pop_target();                /* calls eb_close to do the real work */
+  if (from_tty)
+    printf ("Ending remote %s debugging\n", target_shortname);
+}
+/* Tell the remote machine to resume.  */
+
+void
+eb_resume (step, sig)
+     int step, sig;
+{
+  if (step)
+    {
+      write (eb_desc, "t 1,s\n", 6);
+      /* Wait for the echo.  */
+      expect ("t 1,s\r");
+      /* Then comes a line containing the instruction we stepped to.  */
+      expect ("\n@");
+      /* Then we get the prompt.  */
+      expect_prompt ();
+
+      /* Force the next eb_wait to return a trap.  Not doing anything
+         about I/O from the target means that the user has to type
+         "continue" to see any.  This should be fixed.  */
+      need_artificial_trap = 1;
+    }
+  else
+    {
+      if (need_gi)
+       {
+         need_gi = 0;
+         write (eb_desc, "gi\n", 3);
+         
+         /* Swallow the echo of "gi".  */
+         expect ("gi\r");
+       }
+      else
+       {
+         write (eb_desc, "GR\n", 3);
+         /* Swallow the echo.  */
+         expect ("GR\r");
+       }
+    }
+}
+
+/* Wait until the remote machine stops, then return,
+   storing status in STATUS just as `wait' would.  */
+
+int
+eb_wait (status)
+     WAITTYPE *status;
+{
+  /* Strings to look for.  '?' means match any single character.  
+     Note that with the algorithm we use, the initial character
+     of the string cannot recur in the string, or we will not
+     find some cases of the string in the input.  */
+  
+  static char bpt[] = "Invalid interrupt taken - #0x50 - ";
+  /* It would be tempting to look for "\n[__exit + 0x8]\n"
+     but that requires loading symbols with "yc i" and even if
+     we did do that we don't know that the file has symbols.  */
+  static char exitmsg[] = "\n@????????I    JMPTI     GR121,LR0";
+  char *bp = bpt;
+  char *ep = exitmsg;
+
+  /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
+  char swallowed[50];
+  /* Current position in swallowed.  */
+  char *swallowed_p = swallowed;
+
+  int ch;
+  int ch_handled;
+
+  int old_timeout = timeout;
+
+  WSETEXIT ((*status), 0);
+
+  if (need_artificial_trap != 0)
+    {
+      WSETSTOP ((*status), SIGTRAP);
+      need_artificial_trap--;
+      return 0;
+    }
+
+  timeout = 0;         /* Don't time out -- user program is running. */
+  while (1)
+    {
+      ch_handled = 0;
+      ch = readchar ();
+      if (ch == *bp)
+       {
+         bp++;
+         if (*bp == '\0')
+           break;
+         ch_handled = 1;
+
+         *swallowed_p++ = ch;
+       }
+      else
+       bp = bpt;
+
+      if (ch == *ep || *ep == '?')
+       {
+         ep++;
+         if (*ep == '\0')
+           break;
+
+         if (!ch_handled)
+           *swallowed_p++ = ch;
+         ch_handled = 1;
+       }
+      else
+       ep = exitmsg;
+
+      if (!ch_handled)
+       {
+         char *p;
+
+         /* Print out any characters which have been swallowed.  */
+         for (p = swallowed; p < swallowed_p; ++p)
+           putc (*p, stdout);
+         swallowed_p = swallowed;
+         
+         putc (ch, stdout);
+       }
+    }
+  expect_prompt ();
+  if (*bp== '\0')
+    WSETSTOP ((*status), SIGTRAP);
+  else
+    WSETEXIT ((*status), 0);
+  timeout = old_timeout;
+
+  return 0;
+}
+
+/* Return the name of register number REGNO
+   in the form input and output by EBMON.
+
+   Returns a pointer to a static buffer containing the answer.  */
+static char *
+get_reg_name (regno)
+     int regno;
+{
+  static char buf[80];
+  if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
+    sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
+  else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
+    sprintf (buf, "LR%03d", regno - LR0_REGNUM);
+  else if (regno == Q_REGNUM)
+    strcpy (buf, "SR131");
+  else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
+    sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
+  else if (regno == ALU_REGNUM)
+    strcpy (buf, "SR132");
+  else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
+    sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
+  else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
+    sprintf (buf, "SR%03d", regno - VAB_REGNUM);
+  else if (regno == GR1_REGNUM)
+    strcpy (buf, "GR001");
+  return buf;
+}
+
+/* Read the remote registers into the block REGS.  */
+
+static void
+eb_fetch_registers ()
+{
+  int reg_index;
+  int regnum_index;
+  char tempbuf[10];
+  int i;
+
+#if 0
+  /* This should not be necessary, because one is supposed to read the
+     registers only when the inferior is stopped (at least with
+     ptrace() and why not make it the same for remote?).  */
+  /* ^A is the "normal character" used to make sure we are talking to EBMON
+     and not to the program being debugged.  */
+  write (eb_desc, "\001\n");
+  expect_prompt ();
+#endif
+
+  write (eb_desc, "dw gr96,gr127\n", 14);
+  for (reg_index = 96, regnum_index = GR96_REGNUM;
+       reg_index < 128;
+       reg_index += 4, regnum_index += 4)
+    {
+      sprintf (tempbuf, "GR%03d ", reg_index);
+      expect (tempbuf);
+      get_hex_regs (4, regnum_index);
+      expect ("\n");
+    }
+
+  for (i = 0; i < 128; i += 32)
+    {
+      /* The PC has a tendency to hang if we get these
+        all in one fell swoop ("dw lr0,lr127").  */
+      sprintf (tempbuf, "dw lr%d\n", i);
+      write (eb_desc, tempbuf, strlen (tempbuf));
+      for (reg_index = i, regnum_index = LR0_REGNUM + i;
+          reg_index < i + 32;
+          reg_index += 4, regnum_index += 4)
+       {
+         sprintf (tempbuf, "LR%03d ", reg_index);
+         expect (tempbuf);
+         get_hex_regs (4, regnum_index);
+         expect ("\n");
+       }
+    }
+
+  write (eb_desc, "dw sr133,sr133\n", 15);
+  expect ("SR133          ");
+  get_hex_regs (1, BP_REGNUM);
+  expect ("\n");
+
+  write (eb_desc, "dw sr134,sr134\n", 15);
+  expect ("SR134                   ");
+  get_hex_regs (1, FC_REGNUM);
+  expect ("\n");
+
+  write (eb_desc, "dw sr135,sr135\n", 15);
+  expect ("SR135                            ");
+  get_hex_regs (1, CR_REGNUM);
+  expect ("\n");
+
+  write (eb_desc, "dw sr131,sr131\n", 15);
+  expect ("SR131                            ");
+  get_hex_regs (1, Q_REGNUM);
+  expect ("\n");
+
+  write (eb_desc, "dw sr0,sr14\n", 12);
+  for (reg_index = 0, regnum_index = VAB_REGNUM;
+       regnum_index <= LRU_REGNUM;
+       regnum_index += 4, reg_index += 4)
+    {
+      sprintf (tempbuf, "SR%03d ", reg_index);
+      expect (tempbuf);
+      get_hex_regs (reg_index == 12 ? 3 : 4, regnum_index);
+      expect ("\n");
+    }
+
+  /* There doesn't seem to be any way to get these.  */
+  {
+    int val = -1;
+    supply_register (FPE_REGNUM, &val);
+    supply_register (INT_REGNUM, &val);
+    supply_register (FPS_REGNUM, &val);
+    supply_register (EXO_REGNUM, &val);
+  }
+
+  write (eb_desc, "dw gr1,gr1\n", 11);
+  expect ("GR001 ");
+  get_hex_regs (1, GR1_REGNUM);
+  expect_prompt ();
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1.
+   Returns errno value.  */
+int
+eb_fetch_register (regno)
+     int regno;
+{
+  if (regno == -1)
+    eb_fetch_registers ();
+  else
+    {
+      char *name = get_reg_name (regno);
+      fprintf (eb_stream, "dw %s,%s\n", name, name);
+      expect (name);
+      expect (" ");
+      get_hex_regs (1, regno);
+      expect_prompt ();
+    }
+  return 0;
+}
+
+/* Store the remote registers from the contents of the block REGS.  */
+
+static void
+eb_store_registers ()
+{
+  int i, j;
+  fprintf (eb_stream, "s gr1,%x\n", read_register (GR1_REGNUM));
+  expect_prompt ();
+
+  for (j = 0; j < 32; j += 16)
+    {
+      fprintf (eb_stream, "s gr%d,", j + 96);
+      for (i = 0; i < 15; ++i)
+       fprintf (eb_stream, "%x,", read_register (GR96_REGNUM + j + i));
+      fprintf (eb_stream, "%x\n", read_register (GR96_REGNUM + j + 15));
+      expect_prompt ();
+    }
+
+  for (j = 0; j < 128; j += 16)
+    {
+      fprintf (eb_stream, "s lr%d,", j);
+      for (i = 0; i < 15; ++i)
+       fprintf (eb_stream, "%x,", read_register (LR0_REGNUM + j + i));
+      fprintf (eb_stream, "%x\n", read_register (LR0_REGNUM + j + 15));
+      expect_prompt ();
+    }
+
+  fprintf (eb_stream, "s sr133,%x,%x,%x\n", read_register (BP_REGNUM),
+          read_register (FC_REGNUM), read_register (CR_REGNUM));
+  expect_prompt ();
+  fprintf (eb_stream, "s sr131,%x\n", read_register (Q_REGNUM));
+  expect_prompt ();
+  fprintf (eb_stream, "s sr0,");
+  for (i = 0; i < 11; ++i)
+    fprintf (eb_stream, "%x,", read_register (VAB_REGNUM + i));
+  fprintf (eb_stream, "%x\n", read_register (VAB_REGNUM + 11));
+  expect_prompt ();
+}
+
+/* Store register REGNO, or all if REGNO == 0.
+   Return errno value.  */
+int
+eb_store_register (regno)
+     int regno;
+{
+  if (regno == -1)
+    eb_store_registers ();
+  else
+    {
+      char *name = get_reg_name (regno);
+      fprintf (eb_stream, "s %s,%x\n", name, read_register (regno));
+      /* Setting GR1 changes the numbers of all the locals, so
+        invalidate the register cache.  Do this *after* calling
+        read_register, because we want read_register to return the
+        value that write_register has just stuffed into the registers
+        array, not the value of the register fetched from the
+        inferior.  */
+      if (regno == GR1_REGNUM)
+       registers_changed ();
+      expect_prompt ();
+    }
+  return 0;
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+void
+eb_prepare_to_store ()
+{
+  /* Do nothing, since we can store individual regs */
+}
+
+/* FIXME!  Merge these two.  */
+int
+eb_xfer_inferior_memory (memaddr, myaddr, len, write)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int write;
+{
+  if (write)
+    return eb_write_inferior_memory (memaddr, myaddr, len);
+  else
+    return eb_write_inferior_memory (memaddr, myaddr, len);
+}
+
+void
+eb_files_info ()
+{
+  printf ("\tAttached to %s at %d baud and running program %s.\n",
+         dev_name, baudrate, prog_name);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+   to inferior's memory at MEMADDR.  Returns errno value.  */
+int
+eb_write_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      if ((i % 16) == 0)
+       fprintf (eb_stream, "sb %x,", memaddr + i);
+      if ((i % 16) == 15 || i == len - 1)
+       {
+         fprintf (eb_stream, "%x\n", ((unsigned char *)myaddr)[i]);
+         expect_prompt ();
+       }
+      else
+       fprintf (eb_stream, "%x,", ((unsigned char *)myaddr)[i]);
+    }
+  return 0;
+}
+
+/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
+   at debugger address MYADDR.  Returns errno value.  */
+int
+eb_read_inferior_memory(memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int i;
+
+  /* Number of bytes read so far.  */
+  int count;
+
+  /* Starting address of this pass.  */
+  unsigned long startaddr;
+
+  /* Number of bytes to read in this pass.  */
+  int len_this_pass;
+
+  /* Note that this code works correctly if startaddr is just less
+     than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
+     thing).  That is, something like
+     eb_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+     works--it never adds len to memaddr and gets 0.  */
+  /* However, something like
+     eb_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+     doesn't need to work.  Detect it and give up if there's an attempt
+     to do that.  */
+  if (((memaddr - 1) + len) < memaddr)
+    return EIO;
+  
+  startaddr = memaddr;
+  count = 0;
+  while (count < len)
+    {
+      len_this_pass = 16;
+      if ((startaddr % 16) != 0)
+       len_this_pass -= startaddr % 16;
+      if (len_this_pass > (len - count))
+       len_this_pass = (len - count);
+
+      fprintf (eb_stream, "db %x,%x\n", startaddr,
+              (startaddr - 1) + len_this_pass);
+      expect ("\n");
+
+      /* Look for 8 hex digits.  */
+      i = 0;
+      while (1)
+       {
+         if (isxdigit (readchar ()))
+           ++i;
+         else
+           {
+             expect_prompt ();
+             error ("Hex digit expected from remote system.");
+           }
+         if (i >= 8)
+           break;
+       }
+
+      expect ("  ");
+
+      for (i = 0; i < len_this_pass; i++)
+       get_hex_byte (&myaddr[count++]);
+
+      expect_prompt ();
+
+      startaddr += len_this_pass;
+    }
+  return 0;
+}
+
+/* Define the target subroutine names */
+
+struct target_ops eb_ops = {
+       "amd-eb", "Remote serial AMD EBMON target",
+       eb_open, eb_close, 
+       0, eb_detach, eb_resume, eb_wait,
+       eb_fetch_register, eb_store_register,
+       eb_prepare_to_store, 0, 0,      /* conv_to, conv_from */
+       eb_xfer_inferior_memory, eb_files_info,
+       0, 0,   /* Breakpoints */
+       0, 0, 0, 0, 0,  /* Terminal handling */
+       0,      /* FIXME, kill */
+       0, add_syms_addr_command,       /* load */
+       call_function_by_hand,
+       0, /* lookup_symbol */
+       0, /* create_inferior FIXME, eb_start here or something? */
+       0, /* mourn_inferior FIXME */
+       process_stratum, 0, /* next */
+       1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
+       OPS_MAGIC,              /* Always the last thing */
+};
+
+void
+_initialize_remote_eb ()
+{
+  add_target (&eb_ops);
+}
diff --git a/gdb/remote-multi.shar b/gdb/remote-multi.shar
new file mode 100755 (executable)
index 0000000..86c9cf0
--- /dev/null
@@ -0,0 +1,1313 @@
+#!/bin/sh
+#      This is a shell archive.
+#      Run the file through sh to extract its contents.
+# shar:        Shell Archiver
+#      Run the following text with /bin/sh to create:
+#      Remote_Makefile
+#      remote_gutils.c
+#      remote_inflow.c
+#      remote_server.c
+#      remote_utils.c
+# This archive created: Fri Jun 23 17:06:55 1989
+cat << \SHAR_EOF > Remote_Makefile
+#    Makefile for the remote server for GDB, the GNU debugger.
+#    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+# 
+# This file is part of GDB.
+# 
+# GDB is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+# 
+# GDB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GDB; see the file COPYING.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+CFLAGS = -g 
+CC = cc
+
+SERVER = remote_server.o\
+                remote_inflow.o\
+                remote_utils.o\
+                remote_gutils.o 
+
+prog : $(SERVER)
+       $(CC) -g -o serve $(SERVER) 
+SHAR_EOF
+cat << \SHAR_EOF > remote_gutils.c
+/* General utility routines for the remote server for GDB, the GNU debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include "defs.h"
+
+void error ();
+void fatal ();
+
+/* Chain of cleanup actions established with make_cleanup,
+   to be executed if an error happens.  */
+
+static struct cleanup *cleanup_chain;
+
+/* Nonzero means a quit has been requested.  */
+
+int quit_flag;
+
+/* Nonzero means quit immediately if Control-C is typed now,
+   rather than waiting until QUIT is executed.  */
+
+int immediate_quit;
+\f
+/* Add a new cleanup to the cleanup_chain,
+   and return the previous chain pointer
+   to be passed later to do_cleanups or discard_cleanups.
+   Args are FUNCTION to clean up with, and ARG to pass to it.  */
+
+struct cleanup *
+make_cleanup (function, arg)
+     void (*function) ();
+     int arg;
+{
+  register struct cleanup *new
+    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
+  register struct cleanup *old_chain = cleanup_chain;
+
+  new->next = cleanup_chain;
+  new->function = function;
+  new->arg = arg;
+  cleanup_chain = new;
+
+  return old_chain;
+}
+
+/* Discard cleanups and do the actions they describe
+   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
+
+void
+do_cleanups (old_chain)
+     register struct cleanup *old_chain;
+{
+  register struct cleanup *ptr;
+  while ((ptr = cleanup_chain) != old_chain)
+    {
+      (*ptr->function) (ptr->arg);
+      cleanup_chain = ptr->next;
+      free (ptr);
+    }
+}
+
+/* Discard cleanups, not doing the actions they describe,
+   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
+
+void
+discard_cleanups (old_chain)
+     register struct cleanup *old_chain;
+{
+  register struct cleanup *ptr;
+  while ((ptr = cleanup_chain) != old_chain)
+    {
+      cleanup_chain = ptr->next;
+      free (ptr);
+    }
+}
+
+/* This function is useful for cleanups.
+   Do
+
+     foo = xmalloc (...);
+     old_chain = make_cleanup (free_current_contents, &foo);
+
+   to arrange to free the object thus allocated.  */
+
+void
+free_current_contents (location)
+     char **location;
+{
+  free (*location);
+}
+\f
+/* Generally useful subroutines used throughout the program.  */
+
+/* Like malloc but get error if no storage available.  */
+
+char *
+xmalloc (size)
+     long size;
+{
+  register char *val = (char *) malloc (size);
+  if (!val)
+    fatal ("virtual memory exhausted.", 0);
+  return val;
+}
+
+/* Like realloc but get error if no storage available.  */
+
+char *
+xrealloc (ptr, size)
+     char *ptr;
+     long size;
+{
+  register char *val = (char *) realloc (ptr, size);
+  if (!val)
+    fatal ("virtual memory exhausted.", 0);
+  return val;
+}
+
+/* Print the system error message for errno, and also mention STRING
+   as the file name for which the error was encountered.
+   Then return to command level.  */
+
+void
+perror_with_name (string)
+     char *string;
+{
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+  extern int errno;
+  char *err;
+  char *combined;
+
+  if (errno < sys_nerr)
+    err = sys_errlist[errno];
+  else
+    err = "unknown error";
+
+  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+  strcpy (combined, string);
+  strcat (combined, ": ");
+  strcat (combined, err);
+
+  error ("%s.", combined);
+}
+
+/* Print the system error message for ERRCODE, and also mention STRING
+   as the file name for which the error was encountered.  */
+
+void
+print_sys_errmsg (string, errcode)
+     char *string;
+     int errcode;
+{
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+  char *err;
+  char *combined;
+
+  if (errcode < sys_nerr)
+    err = sys_errlist[errcode];
+  else
+    err = "unknown error";
+
+  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+  strcpy (combined, string);
+  strcat (combined, ": ");
+  strcat (combined, err);
+
+  printf ("%s.\n", combined);
+}
+
+void
+quit ()
+{
+  fflush (stdout);
+  ioctl (fileno (stdout), TIOCFLUSH, 0);
+  error ("Quit");
+}
+
+/* Control C comes here */
+
+void
+request_quit ()
+{
+  quit_flag = 1;
+  if (immediate_quit)
+    quit ();
+}
+
+/* Print an error message and return to command level.
+   STRING is the error message, used as a fprintf string,
+   and ARG is passed as an argument to it.  */
+
+void
+error (string, arg1, arg2, arg3)
+     char *string;
+     int arg1, arg2, arg3;
+{
+  fflush (stdout);
+  fprintf (stderr, string, arg1, arg2, arg3);
+  fprintf (stderr, "\n");
+  /************return_to_top_level ();************/ 
+}
+
+/* Print an error message and exit reporting failure.
+   This is for a error that we cannot continue from.
+   STRING and ARG are passed to fprintf.  */
+
+void
+fatal (string, arg)
+     char *string;
+     int arg;
+{
+  fprintf (stderr, "gdb: ");
+  fprintf (stderr, string, arg);
+  fprintf (stderr, "\n");
+  exit (1);
+}
+
+/* Make a copy of the string at PTR with SIZE characters
+   (and add a null character at the end in the copy).
+   Uses malloc to get the space.  Returns the address of the copy.  */
+
+char *
+savestring (ptr, size)
+     char *ptr;
+     int size;
+{
+  register char *p = (char *) xmalloc (size + 1);
+  bcopy (ptr, p, size);
+  p[size] = 0;
+  return p;
+}
+
+char *
+concat (s1, s2, s3)
+     char *s1, *s2, *s3;
+{
+  register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
+  register char *val = (char *) xmalloc (len);
+  strcpy (val, s1);
+  strcat (val, s2);
+  strcat (val, s3);
+  return val;
+}
+
+void
+print_spaces (n, file)
+     register int n;
+     register FILE *file;
+{
+  while (n-- > 0)
+    fputc (' ', file);
+}
+
+/* Ask user a y-or-n question and return 1 iff answer is yes.
+   Takes three args which are given to printf to print the question.
+   The first, a control string, should end in "? ".
+   It should not say how to answer, because we do that.  */
+
+int
+query (ctlstr, arg1, arg2)
+     char *ctlstr;
+{
+  register int answer;
+
+  /* Automatically answer "yes" if input is not from a terminal.  */
+  /***********if (!input_from_terminal_p ())
+    return 1; *************************/ 
+
+  while (1)
+    {
+      printf (ctlstr, arg1, arg2);
+      printf ("(y or n) ");
+      fflush (stdout);
+      answer = fgetc (stdin);
+      clearerr (stdin);                /* in case of C-d */
+      if (answer != '\n')
+       while (fgetc (stdin) != '\n') clearerr (stdin);
+      if (answer >= 'a')
+       answer -= 040;
+      if (answer == 'Y')
+       return 1;
+      if (answer == 'N')
+       return 0;
+      printf ("Please answer y or n.\n");
+    }
+}
+\f
+/* Parse a C escape sequence.  STRING_PTR points to a variable
+   containing a pointer to the string to parse.  That pointer
+   is updated past the characters we use.  The value of the
+   escape sequence is returned.
+
+   A negative value means the sequence \ newline was seen,
+   which is supposed to be equivalent to nothing at all.
+
+   If \ is followed by a null character, we return a negative
+   value and leave the string pointer pointing at the null character.
+
+   If \ is followed by 000, we return 0 and leave the string pointer
+   after the zeros.  A value of 0 does not mean end of string.  */
+
+int
+parse_escape (string_ptr)
+     char **string_ptr;
+{
+  register int c = *(*string_ptr)++;
+  switch (c)
+    {
+    case 'a':
+      return '\a';
+    case 'b':
+      return '\b';
+    case 'e':
+      return 033;
+    case 'f':
+      return '\f';
+    case 'n':
+      return '\n';
+    case 'r':
+      return '\r';
+    case 't':
+      return '\t';
+    case 'v':
+      return '\v';
+    case '\n':
+      return -2;
+    case 0:
+      (*string_ptr)--;
+      return 0;
+    case '^':
+      c = *(*string_ptr)++;
+      if (c == '\\')
+       c = parse_escape (string_ptr);
+      if (c == '?')
+       return 0177;
+      return (c & 0200) | (c & 037);
+      
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+      {
+       register int i = c - '0';
+       register int count = 0;
+       while (++count < 3)
+         {
+           if ((c = *(*string_ptr)++) >= '0' && c <= '7')
+             {
+               i *= 8;
+               i += c - '0';
+             }
+           else
+             {
+               (*string_ptr)--;
+               break;
+             }
+         }
+       return i;
+      }
+    default:
+      return c;
+    }
+}
+\f
+void
+printchar (ch, stream)
+     unsigned char ch;
+     FILE *stream;
+{
+  register int c = ch;
+  if (c < 040 || c >= 0177)
+    {
+      if (c == '\n')
+       fprintf (stream, "\\n");
+      else if (c == '\b')
+       fprintf (stream, "\\b");
+      else if (c == '\t')
+       fprintf (stream, "\\t");
+      else if (c == '\f')
+       fprintf (stream, "\\f");
+      else if (c == '\r')
+       fprintf (stream, "\\r");
+      else if (c == 033)
+       fprintf (stream, "\\e");
+      else if (c == '\a')
+       fprintf (stream, "\\a");
+      else
+       fprintf (stream, "\\%03o", c);
+    }
+  else
+    {
+      if (c == '\\' || c == '"' || c == '\'')
+       fputc ('\\', stream);
+      fputc (c, stream);
+    }
+}
+SHAR_EOF
+cat << \SHAR_EOF > remote_inflow.c
+/* Low level interface to ptrace, for GDB when running under Unix.
+   Copyright (C) 1986, 1987 Free Software Foundation, Inc.
+*/
+
+#include "defs.h"
+#include "param.h"
+#include "wait.h"
+#include "frame.h"
+#include "inferior.h"
+/***************************
+#include "initialize.h"
+****************************/ 
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+
+/***************Begin MY defs*********************/ 
+int quit_flag = 0; 
+char registers[REGISTER_BYTES]; 
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+
+char buf2[MAX_REGISTER_RAW_SIZE];
+/***************End MY defs*********************/ 
+
+#ifdef NEW_SUN_PTRACE
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+#endif
+
+extern char **environ; 
+extern int errno;
+extern int inferior_pid; 
+void error(), quit(), perror_with_name();
+int query(); 
+void supply_register(), write_register(); 
+CORE_ADDR read_register(); 
+
+/* Nonzero if we are debugging an attached outside process
+   rather than an inferior.  */
+
+
+/* Start an inferior process and returns its pid.
+   ALLARGS is a vector of program-name and args.
+   ENV is the environment vector to pass.  */
+
+int
+create_inferior (allargs, env)
+     char **allargs;
+     char **env;
+{
+  int pid;
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+  extern int errno;
+
+  /* exec is said to fail if the executable is open.  */
+  /****************close_exec_file ();*****************/ 
+
+  pid = vfork ();
+  if (pid < 0)
+    perror_with_name ("vfork");
+
+  if (pid == 0)
+    {
+      /* Run inferior in a separate process group.  */
+      setpgrp (getpid (), getpid ());
+
+/* Not needed on Sun, at least, and loses there
+   because it clobbers the superior.  */
+/*???      signal (SIGQUIT, SIG_DFL);
+      signal (SIGINT, SIG_DFL);  */
+
+         errno = 0; 
+      ptrace (0);
+
+      execle ("/bin/sh", "sh", "-c", allargs, 0, env);
+
+      fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
+              errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+      fflush (stderr);
+      _exit (0177);
+    }
+  return pid;
+}
+
+/* Kill the inferior process.  Make us have no inferior.  */
+
+kill_inferior ()
+{
+  if (inferior_pid == 0)
+    return;
+  ptrace (8, inferior_pid, 0, 0);
+  wait (0);
+  /*************inferior_died ();****VK**************/ 
+}
+
+/* Resume execution of the inferior process.
+   If STEP is nonzero, single-step it.
+   If SIGNAL is nonzero, give it that signal.  */
+
+unsigned char
+resume (step, signal,status)
+     int step;
+     int signal;
+        char *status; 
+{
+       int pid ; 
+       WAITTYPE w; 
+
+       errno = 0;
+    ptrace (step ? 9 : 7, inferior_pid, 1, signal);
+    if (errno)
+               perror_with_name ("ptrace");
+       pid = wait(&w); 
+       if(pid != inferior_pid) 
+               perror_with_name ("wait"); 
+
+       if(WIFEXITED(w))
+       {
+               printf("\nchild exited with retcode = %x \n",WRETCODE(w)); 
+               *status = 'E'; 
+               return((unsigned char) WRETCODE(w));
+       } 
+       else if(!WIFSTOPPED(w))
+       {
+               printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); 
+               *status = 'T'; 
+               return((unsigned char) WTERMSIG(w)); 
+       } 
+       else 
+       {
+               printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); 
+               *status = 'S'; 
+               return((unsigned char) WSTOPSIG(w)); 
+       } 
+                
+}
+
+
+#ifdef NEW_SUN_PTRACE
+
+void
+fetch_inferior_registers ()
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  extern char registers[];
+
+      ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
+      if (errno)
+               perror_with_name ("ptrace");
+         /**********debugging begin **********/ 
+         print_some_registers(&inferior_registers); 
+         /**********debugging end **********/ 
+      ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
+      if (errno)
+               perror_with_name ("ptrace");
+
+      bcopy (&inferior_registers, registers, 16 * 4);
+      bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+            sizeof inferior_fp_registers.fps_regs);
+      *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+      *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+      bcopy (&inferior_fp_registers.fps_control,
+            &registers[REGISTER_BYTE (FPC_REGNUM)],
+            sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  extern char registers[];
+
+      bcopy (registers, &inferior_registers, 16 * 4);
+      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+            sizeof inferior_fp_registers.fps_regs);
+      inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
+      inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
+      bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+            &inferior_fp_registers.fps_control,
+            sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+
+      ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
+      if (errno)
+               perror_with_name ("ptrace");
+      ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
+      if (errno)
+               perror_with_name ("ptrace");
+}
+
+#endif /* not NEW_SUN_PTRACE */
+
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+   in the NEW_SUN_PTRACE case.
+   It ought to be straightforward.  But it appears that writing did
+   not write the data that I specified.  I cannot understand where
+   it got the data that it actually did write.  */
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+   to debugger memory starting at MYADDR.  */
+
+read_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & - sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+
+  /* Read all the longwords */
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+       buffer[i] = ptrace (1, inferior_pid, addr, 0);
+    }
+
+  /* Copy appropriate bytes out of the buffer.  */
+  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+   to inferior's memory at MEMADDR.
+   On failure (cannot write the inferior)
+   returns the value of errno.  */
+
+int
+write_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & - sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+  extern int errno;
+
+  /* Fill start and end extra bytes of buffer with existing memory data.  */
+
+    buffer[0] = ptrace (1, inferior_pid, addr, 0);
+
+  if (count > 1)
+    {
+       buffer[count - 1]
+         = ptrace (1, inferior_pid,
+                   addr + (count - 1) * sizeof (int), 0);
+    }
+
+  /* Copy data to be written over corresponding part of buffer */
+
+  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+
+  /* Write the entire buffer.  */
+
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+      errno = 0;
+       ptrace (4, inferior_pid, addr, buffer[i]);
+      if (errno)
+       return errno;
+    }
+
+  return 0;
+}
+\f
+void
+try_writing_regs_command ()
+{
+  register int i;
+  register int value;
+  extern int errno;
+
+  if (inferior_pid == 0)
+    error ("There is no inferior process now.");
+
+  fetch_inferior_registers(); 
+  for (i = 0;i<18 ; i ++)
+    {
+      QUIT;
+      errno = 0;
+      value = read_register(i); 
+      write_register ( i, value);
+      if (errno == 0)
+       {
+               printf (" Succeeded with register %d; value 0x%x (%d).\n",
+                 i, value, value);
+       }
+      else 
+               printf (" Failed with register %d.\n", i);
+    }
+}
+
+void
+initialize ()
+{
+
+  inferior_pid = 0;
+
+
+}
+
+
+/* Return the contents of register REGNO,
+   regarding it as an integer.  */
+
+CORE_ADDR
+read_register (regno)
+     int regno;
+{
+  /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
+  return *(int *) &registers[REGISTER_BYTE (regno)];
+}
+
+/* Store VALUE in the register number REGNO, regarded as an integer.  */
+
+void
+write_register (regno, val)
+     int regno, val;
+{
+  /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
+  *(int *) &registers[REGISTER_BYTE (regno)] = val;
+
+  if (have_inferior_p ())
+    store_inferior_registers (regno);
+}
+
+
+int
+have_inferior_p ()
+{
+  return inferior_pid != 0;
+}
+
+print_some_registers(regs)
+int regs[];
+{
+   register int i;
+   for (i = 0; i < 18; i++) {
+        printf("reg[%d] = %x\n", i, regs[i]);
+        }
+}
+
+SHAR_EOF
+cat << \SHAR_EOF > remote_server.c
+/* Main code for remote server for GDB, the GNU Debugger.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "param.h"
+#include <stdio.h>
+
+void read_inferior_memory(), fetch_inferior_registers(); 
+unsigned char resume(); 
+void kill_inferior(); 
+void initialize(), try_writing_regs_command();  
+int create_inferior(), read_register(); 
+
+extern char registers[]; 
+int inferior_pid; 
+extern char **environ; 
+
+/* Descriptor for I/O to remote machine.  */
+int remote_desc;
+int kiodebug = 0;
+int remote_debugging; 
+
+void remote_send ();
+void putpkt ();
+void getpkt ();
+void remote_open(); 
+void write_ok(); 
+void write_enn(); 
+void convert_ascii_to_int(); 
+void convert_int_to_ascii(); 
+void prepare_resume_reply(); 
+void decode_m_packet(); 
+void decode_M_packet(); 
+
+
+main(argc,argv)
+int argc; char *argv[]; 
+{
+    char ch,status, own_buf[2000], mem_buf[2000]; 
+       int i=0;  
+       unsigned char signal;  
+       unsigned int mem_addr, len; 
+
+       initialize(); 
+    printf("\nwill open serial link\n"); 
+    remote_open("/dev/ttya",0); 
+
+       if(argc < 2) 
+       { 
+               printf("Enter name of program to be run with command line args\n"); 
+               gets(own_buf); 
+               inferior_pid = create_inferior(own_buf,environ); 
+               printf("\nProcess %s created; pid = %d\n",own_buf,inferior_pid);
+       } 
+       else 
+       { 
+               inferior_pid = create_inferior(argv[1],environ); 
+               printf("\nProcess %s created; pid = %d\n",argv[1],inferior_pid);
+       } 
+
+    do {  
+        getpkt(own_buf); 
+        printf("\nPacket received is>:%s\n",own_buf); 
+               i = 0; 
+               ch = own_buf[i++]; 
+           switch (ch) { 
+                       case 'h':       /**********This is only for tweaking the gdb+ program *******/ 
+                                               signal = resume(1,0,&status);
+                                               prepare_resume_reply(own_buf,status,signal); 
+                                               break; 
+                                               /*************end tweak*************************************/ 
+
+                       case 'g':       fetch_inferior_registers();             
+                                               convert_int_to_ascii(registers,own_buf,REGISTER_BYTES); 
+                                               break; 
+                       case 'G':       convert_ascii_to_int(&own_buf[1],registers,REGISTER_BYTES);
+                                               if(store_inferior_registers(-1)==0)  
+                                                       write_ok(own_buf); 
+                                               else  
+                                                       write_enn(own_buf); 
+                                               break; 
+                       case 'm':       decode_m_packet(&own_buf[1],&mem_addr,&len); 
+                                               read_inferior_memory(mem_addr,mem_buf,len);
+                                               convert_int_to_ascii(mem_buf,own_buf,len); 
+                                               break; 
+                       case 'M':       decode_M_packet(&own_buf[1],&mem_addr,&len,mem_buf); 
+                                               if(write_inferior_memory(mem_addr,mem_buf,len)==0)  
+                                                       write_ok(own_buf); 
+                                               else 
+                                                       write_enn(own_buf); 
+                                               break; 
+                       case 'c':       signal = resume(0,0,&status);
+                                               printf("\nSignal received is >: %0x \n",signal); 
+                                               prepare_resume_reply(own_buf,status,signal); 
+                                               break; 
+                       case 's':       signal = resume(1,0,&status);
+                                               prepare_resume_reply(own_buf,status,signal); 
+                                               break; 
+                       case 'k':       kill_inferior();
+                                               sprintf(own_buf,"q"); 
+                                       putpkt(own_buf); 
+                                               printf("\nObtained kill request...terminating\n"); 
+                                       close(remote_desc); 
+                                               exit(0); 
+                       case 't':       try_writing_regs_command();
+                                               own_buf[0] = '\0'; 
+                                               break; 
+                       default :       printf("\nUnknown option chosen by master\n"); 
+                                               write_enn(own_buf); 
+                                               break; 
+                 } 
+
+        putpkt(own_buf); 
+     }  while(1) ; 
+
+    close(remote_desc); 
+    /** now get out of here**/ 
+    printf("\nFinished reading data from serial link - Bye!\n"); 
+    exit(0);
+
+}
+
+SHAR_EOF
+cat << \SHAR_EOF > remote_utils.c
+/* Remote utility routines for the remote server for GDB, the GNU debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "param.h"
+#include <stdio.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <a.out.h>
+#include <sys/file.h>
+#include <sgtty.h> 
+
+extern int remote_desc; 
+extern int remote_debugging; 
+extern int kiodebug; 
+
+void remote_open(); 
+void remote_send(); 
+void putpkt(); 
+void getpkt(); 
+
+void write_ok(); 
+void write_enn(); 
+void convert_ascii_to_int(); 
+void convert_int_to_ascii(); 
+void prepare_resume_reply(); 
+
+/* Open a connection to a remote debugger.
+   NAME is the filename used for communication.  */
+
+void
+remote_open (name, from_tty)
+     char *name;
+     int from_tty;
+{
+  struct sgttyb sg;
+
+  remote_debugging = 0;
+
+  remote_desc = open (name, O_RDWR);
+  if (remote_desc < 0)
+    printf("\ncould not open remote device\n"); 
+
+  ioctl (remote_desc, TIOCGETP, &sg);
+  sg.sg_flags = RAW;
+  ioctl (remote_desc, TIOCSETP, &sg);
+
+  if (from_tty)
+    printf ("Remote debugging using %s\n", name);
+  remote_debugging = 1;
+}
+
+/* Convert hex digit A to a number.  */
+
+static int
+fromhex (a)
+     int a;
+{
+  if (a >= '0' && a <= '9')
+    return a - '0';
+  else if (a >= 'a' && a <= 'f')
+    return a - 'a' + 10;
+  else
+    perror ("Reply contains invalid hex digit");
+}
+
+/* Convert number NIB to a hex digit.  */
+
+static int
+tohex (nib)
+     int nib;
+{
+  if (nib < 10)
+    return '0'+nib;
+  else
+    return 'a'+nib-10;
+}
+
+/* Send the command in BUF to the remote machine,
+   and read the reply into BUF.
+   Report an error if we get an error reply.  */
+
+void
+remote_send (buf)
+     char *buf;
+{
+  putpkt (buf);
+  getpkt (buf);
+
+  if (buf[0] == 'E')
+    perror ("Remote failure reply: %s", buf);
+}
+
+/* Send a packet to the remote machine, with error checking.
+   The data of the packet is in BUF.  */
+
+void
+putpkt (buf)
+     char *buf;
+{
+  int i;
+  unsigned char csum = 0;
+  char buf2[500];
+  char buf3[1];
+  int cnt = strlen (buf);
+  char *p;
+
+  if (kiodebug)
+    fprintf (stderr, "Sending packet: %s\n", buf);
+
+  /* Copy the packet into buffer BUF2, encapsulating it
+     and giving it a checksum.  */
+
+  p = buf2;
+  *p++ = '$';
+
+  for (i = 0; i < cnt; i++)
+    {
+      csum += buf[i];
+      *p++ = buf[i];
+    }
+  *p++ = '#';
+  *p++ = tohex ((csum >> 4) & 0xf);
+  *p++ = tohex (csum & 0xf);
+
+  /* Send it over and over until we get a positive ack.  */
+
+  do {
+    write (remote_desc, buf2, p - buf2);
+    read (remote_desc, buf3, 1);
+  } while (buf3[0] != '+');
+}
+
+static int
+readchar ()
+{
+  char buf[1];
+  while (read (remote_desc, buf, 1) != 1) ;
+  return buf[0] & 0x7f;
+}
+
+/* Read a packet from the remote machine, with error checking,
+   and store it in BUF.  */
+
+void
+getpkt (buf)
+     char *buf;
+{
+  char *bp;
+  unsigned char csum, c, c1, c2;
+  extern kiodebug;
+
+  while (1)
+    {
+         csum = 0; 
+      while ((c = readchar()) != '$');
+
+      bp = buf;
+      while (1)
+       {
+         c = readchar ();
+         if (c == '#')
+           break;
+         *bp++ = c;
+         csum += c;
+       }
+      *bp = 0;
+
+      c1 = fromhex (readchar ());
+      c2 = fromhex (readchar ());
+      if (csum == (c1 << 4) + c2)
+           break;
+
+      printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+             (c1 << 4) + c2, csum, buf);
+      write (remote_desc, "-", 1);
+    }
+
+  write (remote_desc, "+", 1);
+
+  if (kiodebug)
+    fprintf (stderr,"Packet received :%s\n", buf);
+}
+
+
+void 
+write_ok(buf)
+       char *buf; 
+{
+       buf[0] = 'O';
+       buf[1] = 'k';
+       buf[2] = '\0';
+}
+
+void 
+write_enn(buf)
+       char *buf; 
+{
+       buf[0] = 'E';
+       buf[1] = 'N';
+       buf[2] = 'N';
+       buf[3] = '\0';
+}
+
+void
+convert_int_to_ascii(from,to,n)
+char *from, *to; int n; 
+{
+       int nib ; 
+       char ch; 
+       while( n-- )
+       {
+               ch = *from++;           
+               nib = ((ch & 0xf0) >> 4)& 0x0f; 
+               *to++ = tohex(nib); 
+               nib = ch & 0x0f; 
+               *to++ = tohex(nib); 
+       } 
+       *to++ = 0; 
+}
+
+
+void
+convert_ascii_to_int(from,to,n)
+char *from, *to; int n;  
+{
+       int nib1,nib2 ; 
+       while( n-- )
+       {
+               nib1 = fromhex(*from++); 
+               nib2 = fromhex(*from++); 
+               *to++ = (((nib1 & 0x0f)<< 4)& 0xf0) | (nib2 & 0x0f); 
+       } 
+}
+
+void
+prepare_resume_reply(buf,status,signal)
+char *buf ,status; 
+unsigned char signal; 
+{
+       int nib; 
+       char ch; 
+
+       *buf++ = 'S';  
+       *buf++ = status;  
+       nib = ((signal & 0xf0) >> 4) ; 
+       *buf++ = tohex(nib); 
+       nib = signal & 0x0f; 
+       *buf++ = tohex(nib); 
+       *buf++ = 0; 
+}
+
+void 
+decode_m_packet(from,mem_addr_ptr,len_ptr)
+char *from;
+unsigned int *mem_addr_ptr, *len_ptr; 
+{
+       int i = 0, j = 0 ; 
+       char ch; 
+       *mem_addr_ptr = *len_ptr = 0; 
+       /************debugging begin************/ 
+       printf("\nIn decode_m_packet"); 
+       /************debugging end************/ 
+
+       while((ch = from[i++]) != ',') 
+       { 
+               *mem_addr_ptr = *mem_addr_ptr << 4; 
+               *mem_addr_ptr |= fromhex(ch) & 0x0f; 
+       } 
+       /************debugging begin************/ 
+       printf("\nFinished mem_addr part"); 
+       /************debugging end************/ 
+
+       for(j=0; j < 4; j++) 
+       { 
+               if((ch = from[i++]) == 0)  
+                       break; 
+               *len_ptr = *len_ptr << 4; 
+               *len_ptr |= fromhex(ch) & 0x0f; 
+       } 
+       /************debugging begin************/ 
+       printf("\nFinished len_ptr part"); 
+       /************debugging end************/ 
+}
+
+void 
+decode_M_packet(from,mem_addr_ptr,len_ptr,to)
+char *from, *to;
+unsigned int *mem_addr_ptr, *len_ptr; 
+{
+       int i = 0, j = 0 ; 
+       char ch; 
+       *mem_addr_ptr = *len_ptr = 0; 
+       /************debugging begin************/ 
+       printf("\nIn decode_M_packet"); 
+       /************debugging end************/ 
+
+       while((ch = from[i++]) != ',') 
+       { 
+               *mem_addr_ptr = *mem_addr_ptr << 4; 
+               *mem_addr_ptr |= fromhex(ch) & 0x0f; 
+       } 
+       /************debugging begin************/ 
+       printf("\nFinished mem_addr part: memaddr = %x",*mem_addr_ptr); 
+       /************debugging end************/ 
+
+       while((ch = from[i++]) != ':') 
+       { 
+               *len_ptr = *len_ptr << 4; 
+               *len_ptr |= fromhex(ch) & 0x0f; 
+       } 
+       /************debugging begin************/ 
+       printf("\nFinished len_ptr part: len = %d",*len_ptr); 
+       /************debugging end************/ 
+
+       convert_ascii_to_int(&from[i++],to,*len_ptr); 
+
+       /************debugging begin************/ 
+       printf("\nmembuf : %x",*(int *)to); 
+       /************debugging end************/ 
+}
+
+SHAR_EOF
+#      End of shell archive
+exit 0
diff --git a/gdb/remote-nindy.c b/gdb/remote-nindy.c
new file mode 100644 (file)
index 0000000..5724f42
--- /dev/null
@@ -0,0 +1,962 @@
+/* Memory-access and commands for remote NINDY process, for GDB.
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
+
+GDB is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY.  No author or distributor accepts responsibility to anyone
+for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing.
+Refer to the GDB General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute GDB,
+but only under the conditions described in the GDB General Public
+License.  A copy of this license is supposed to have been given to you
+along with GDB so you can know your rights and responsibilities.  It
+should be in a file named COPYING.  Among other things, the copyright
+notice and this notice must be preserved on all copies.
+
+In other words, go ahead and share GDB, but don't try to stop
+anyone else from sharing it farther.  Help stamp out software hoarding!
+*/
+
+/*
+Except for the data cache routines, this file bears little resemblence
+to remote.c.  A new (although similar) protocol has been specified, and
+portions of the code are entirely dependent on having an i80960 with a
+NINDY ROM monitor at the other end of the line.
+*/
+
+/*****************************************************************************
+ *
+ * REMOTE COMMUNICATION PROTOCOL BETWEEN GDB960 AND THE NINDY ROM MONITOR.
+ *
+ *
+ * MODES OF OPERATION
+ * ----- -- ---------
+ *     
+ * As far as NINDY is concerned, GDB is always in one of two modes: command
+ * mode or passthrough mode.
+ *
+ * In command mode (the default) pre-defined packets containing requests
+ * are sent by GDB to NINDY.  NINDY never talks except in reponse to a request.
+ *
+ * Once the the user program is started, GDB enters passthrough mode, to give
+ * the user program access to the terminal.  GDB remains in this mode until
+ * NINDY indicates that the program has stopped.
+ *
+ *
+ * PASSTHROUGH MODE
+ * ----------- ----
+ *
+ * GDB writes all input received from the keyboard directly to NINDY, and writes
+ * all characters received from NINDY directly to the monitor.
+ *
+ * Keyboard input is neither buffered nor echoed to the monitor.
+ *
+ * GDB remains in passthrough mode until NINDY sends a single ^P character,
+ * to indicate that the user process has stopped.
+ *
+ * Note:
+ *     GDB assumes NINDY performs a 'flushreg' when the user program stops.
+ *
+ *
+ * COMMAND MODE
+ * ------- ----
+ *
+ * All info (except for message ack and nak) is transferred between gdb
+ * and the remote processor in messages of the following format:
+ *
+ *             <info>#<checksum>
+ *
+ * where 
+ *     #       is a literal character
+ *
+ *     <info>  ASCII information;  all numeric information is in the
+ *             form of hex digits ('0'-'9' and lowercase 'a'-'f').
+ *
+ *     <checksum>
+ *             is a pair of ASCII hex digits representing an 8-bit
+ *             checksum formed by adding together each of the
+ *             characters in <info>.
+ *
+ * The receiver of a message always sends a single character to the sender
+ * to indicate that the checksum was good ('+') or bad ('-');  the sender
+ * re-transmits the entire message over until a '+' is received.
+ *
+ * In response to a command NINDY always sends back either data or
+ * a result code of the form "Xnn", where "nn" are hex digits and "X00"
+ * means no errors.  (Exceptions: the "s" and "c" commands don't respond.)
+ *
+ * SEE THE HEADER OF THE FILE "gdb.c" IN THE NINDY MONITOR SOURCE CODE FOR A
+ * FULL DESCRIPTION OF LEGAL COMMANDS.
+ *
+ * SEE THE FILE "stop.h" IN THE NINDY MONITOR SOURCE CODE FOR A LIST
+ * OF STOP CODES.
+ *
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <setjmp.h>
+
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "bfd.h"
+#include "ieee-float.h"
+
+#include "wait.h"
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <ctype.h>
+#include "nindy-share/ttycntl.h"
+#include "nindy-share/demux.h"
+#include "nindy-share/env.h"
+#include "nindy-share/stop.h"
+
+extern int unlink();
+extern char *getenv();
+extern char *mktemp();
+
+extern char *coffstrip();
+extern void add_syms_addr_command ();
+extern value call_function_by_hand ();
+extern void generic_mourn_inferior ();
+
+extern struct target_ops nindy_ops;
+extern jmp_buf to_top_level;
+extern FILE *instream;
+extern struct ext_format ext_format_i960[];    /* i960-tdep.c */
+
+extern char ninStopWhy ();
+
+int nindy_initial_brk; /* nonzero if want to send an initial BREAK to nindy */
+int nindy_old_protocol;        /* nonzero if want to use old protocol */
+char *nindy_ttyname;   /* name of tty to talk to nindy on, or null */
+
+#define DLE    '\020'  /* Character NINDY sends to indicate user program has
+                        * halted.  */
+#define TRUE   1
+#define FALSE  0
+
+int nindy_fd = 0;      /* Descriptor for I/O to NINDY  */
+static int have_regs = 0;      /* 1 iff regs read since i960 last halted */
+static int regs_changed = 0;   /* 1 iff regs were modified since last read */
+
+extern char *exists();
+static void dcache_flush (), dcache_poke (), dcache_init();
+static int dcache_fetch ();
+\f
+/* FIXME, we can probably use the normal terminal_inferior stuff here.
+   We have to do terminal_inferior and then set up the passthrough
+   settings initially.  Thereafter, terminal_ours and terminal_inferior
+   will automatically swap the settings around for us.  */
+
+/* Restore TTY to normal operation */
+
+static TTY_STRUCT orig_tty;    /* TTY attributes before entering passthrough */
+
+static void
+restore_tty()
+{
+       ioctl( 0, TIOCSETN, &orig_tty );
+}
+
+
+/* Recover from ^Z or ^C while remote process is running */
+
+static void (*old_ctrlc)();    /* Signal handlers before entering passthrough */
+
+#ifdef SIGTSTP
+static void (*old_ctrlz)();
+#endif
+
+static
+#ifdef USG
+void
+#endif
+cleanup()
+{
+       restore_tty();
+       signal(SIGINT, old_ctrlc);
+#ifdef SIGTSTP
+       signal(SIGTSTP, old_ctrlz);
+#endif
+       error("\n\nYou may need to reset the 80960 and/or reload your program.\n");
+}
+\f
+/* Clean up anything that needs cleaning when losing control.  */
+
+static char *savename;
+
+static void
+nindy_close (quitting)
+     int quitting;
+{
+  if (nindy_fd)
+    close (nindy_fd);
+  nindy_fd = 0;
+
+  if (savename)
+    free (savename);
+  savename = 0;
+}
+
+/* Open a connection to a remote debugger.   
+   FIXME, there should be a way to specify the various options that are
+   now specified with gdb command-line options.  (baud_rate, old_protocol,
+   and initial_brk)  */
+void
+nindy_open (name, from_tty)
+    char *name;                /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */
+    int from_tty;
+{
+
+  if (!name)
+    error_no_arg ("serial port device name");
+
+  nindy_close (0);
+
+       have_regs = regs_changed = 0;
+       dcache_init();
+
+       /* Allow user to interrupt the following -- we could hang if
+        * there's no NINDY at the other end of the remote tty.
+        */
+       immediate_quit++;
+       nindy_fd = ninConnect( name, baud_rate? baud_rate: "9600",
+                       nindy_initial_brk, !from_tty, nindy_old_protocol );
+       immediate_quit--;
+
+       if ( nindy_fd < 0 ){
+               nindy_fd = 0;
+               error( "Can't open tty '%s'", name );
+       }
+
+        savename = savestring (name, strlen (name));
+       push_target (&nindy_ops);
+       target_fetch_registers(-1);
+}
+
+/* User-initiated quit of nindy operations.  */
+
+static void
+nindy_detach (name, from_tty)
+     char *name;
+     int from_tty;
+{
+  dont_repeat ();
+  if (name)
+    error ("Too many arguments");
+  pop_target ();
+}
+
+static void
+nindy_files_info ()
+{
+  printf("\tAttached to %s at %s bps%s%s.\n", savename,
+        baud_rate? baud_rate: "9600",
+        nindy_old_protocol? " in old protocol": "",
+         nindy_initial_brk? " with initial break": "");
+}
+\f
+/******************************************************************************
+ * remote_load:
+ *     Download an object file to the remote system by invoking the "comm960"
+ *     utility.  We look for "comm960" in $G960BIN, $G960BASE/bin, and
+ *     DEFAULT_BASE/bin/HOST/bin where
+ *             DEFAULT_BASE is defined in env.h, and
+ *             HOST must be defined on the compiler invocation line.
+ ******************************************************************************/
+
+static void
+nindy_load( filename, from_tty )
+    char *filename;
+    int from_tty;
+{
+  char *tmpfile;
+  struct cleanup *old_chain;
+  char *scratch_pathname;
+  int scratch_chan;
+
+  if (!filename)
+    filename = get_exec_file (1);
+
+  filename = tilde_expand (filename);
+  make_cleanup (free, filename);
+
+  scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+                       &scratch_pathname);
+  if (scratch_chan < 0)
+    perror_with_name (filename);
+  close (scratch_chan);                /* Slightly wasteful FIXME */
+
+  have_regs = regs_changed = 0;
+  mark_breakpoints_out();
+  inferior_pid = 0;
+  dcache_flush();
+
+  tmpfile = coffstrip(scratch_pathname);
+  if ( tmpfile ){
+         old_chain = make_cleanup(unlink,tmpfile);
+         immediate_quit++;
+         ninDownload( tmpfile, !from_tty );
+/* FIXME, don't we want this merged in here? */
+         immediate_quit--;
+         do_cleanups (old_chain);
+  }
+}
+
+
+
+/* Return the number of characters in the buffer before the first DLE character.
+ */
+
+static
+int
+non_dle( buf, n )
+    char *buf;         /* Character buffer; NOT '\0'-terminated */
+    int n;             /* Number of characters in buffer */
+{
+       int i;
+
+       for ( i = 0; i < n; i++ ){
+               if ( buf[i] == DLE ){
+                       break;
+               }
+       }
+       return i;
+}
+\f
+/* Tell the remote machine to resume.  */
+
+void
+nindy_resume (step, siggnal)
+     int step, siggnal;
+{
+       if (siggnal != 0 && siggnal != stop_signal)
+         error ("Can't send signals to remote NINDY targets.");
+
+       dcache_flush();
+       if ( regs_changed ){
+               nindy_store_registers ();
+               regs_changed = 0;
+       }
+       have_regs = 0;
+       ninGo( step );
+}
+
+/* Wait until the remote machine stops. While waiting, operate in passthrough
+ * mode; i.e., pass everything NINDY sends to stdout, and everything from
+ * stdin to NINDY.
+ *
+ * Return to caller, storing status in 'status' just as `wait' would.
+ */
+
+void
+nindy_wait( status )
+    WAITTYPE *status;
+{
+       DEMUX_DECL;     /* OS-dependent data needed by DEMUX... macros */
+       char buf[500];  /* FIXME, what is "500" here? */
+       int i, n;
+       unsigned char stop_exit;
+       unsigned char stop_code;
+       TTY_STRUCT tty;
+       long ip_value, fp_value, sp_value;      /* Reg values from stop */
+
+
+       WSETEXIT( (*status), 0 );
+
+       /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
+
+       /* Save current tty attributes, set up signals to restore them.
+        */
+       ioctl( 0, TIOCGETP, &orig_tty );
+       old_ctrlc = signal( SIGINT, cleanup );
+#ifdef SIGTSTP
+       old_ctrlz = signal( SIGTSTP, cleanup );
+#endif
+
+       /* Pass input from keyboard to NINDY as it arrives.
+        * NINDY will interpret <CR> and perform echo.
+        */
+       tty = orig_tty;
+       TTY_NINDYTERM( tty );
+       ioctl( 0, TIOCSETN, &tty );
+
+       while ( 1 ){
+               /* Go to sleep until there's something for us on either
+                * the remote port or stdin.
+                */
+
+               DEMUX_WAIT( nindy_fd );
+
+               /* Pass input through to correct place */
+
+               n = DEMUX_READ( 0, buf, sizeof(buf) );
+               if ( n ){                               /* Input on stdin */
+                       write( nindy_fd, buf, n );
+               }
+
+               n = DEMUX_READ( nindy_fd, buf, sizeof(buf) );
+               if ( n ){                               /* Input on remote */
+                       /* Write out any characters in buffer preceding DLE */
+                       i = non_dle( buf, n );
+                       if ( i > 0 ){
+                               write( 1, buf, i );
+                       }
+
+                       if ( i != n ){
+                               /* There *was* a DLE in the buffer */
+                               stop_exit = ninStopWhy( &stop_code,
+                                       &ip_value, &fp_value, &sp_value);
+                               if ( !stop_exit && (stop_code==STOP_SRQ) ){
+                                       immediate_quit++;
+                                       ninSrq();
+                                       immediate_quit--;
+                               } else {
+                                       /* Get out of loop */
+                                       supply_register (IP_REGNUM, &ip_value);
+                                       supply_register (FP_REGNUM, &fp_value);
+                                       supply_register (SP_REGNUM, &sp_value);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       signal( SIGINT, old_ctrlc );
+#ifdef SIGTSTP
+       signal( SIGTSTP, old_ctrlz );
+#endif
+       restore_tty();
+
+       if ( stop_exit ){                       /* User program exited */
+               WSETEXIT( (*status), stop_code );
+       } else {                                /* Fault or trace */
+               switch (stop_code){
+               case STOP_GDB_BPT:
+               case TRACE_STEP:
+                       /* Make it look like a VAX trace trap */
+                       stop_code = SIGTRAP;
+                       break;
+               default:
+                       /* The target is not running Unix, and its
+                          faults/traces do not map nicely into Unix signals.
+                          Make sure they do not get confused with Unix signals
+                          by numbering them with values higher than the highest
+                          legal Unix signal.  code in i960_print_fault(),
+                          called via PRINT_RANDOM_SIGNAL, will interpret the
+                          value.  */
+                       stop_code += NSIG;
+                       break;
+               }
+               WSETSTOP( (*status), stop_code );
+       }
+}
+
+/* Read the remote registers into the block REGS.  */
+
+/* This is the block that ninRegsGet and ninRegsPut handles.  */
+struct nindy_regs {
+  char local_regs[16 * 4];
+  char global_regs[16 * 4];
+  char pcw_acw[2 * 4];
+  char ip[4];
+  char tcw[4];
+  char fp_as_double[4 * 8];
+};
+
+static int
+nindy_fetch_registers(regno)
+     int regno;
+{
+  struct nindy_regs nindy_regs;
+  int regnum, inv;
+  double dub;
+
+  immediate_quit++;
+  ninRegsGet( (char *) &nindy_regs );
+  immediate_quit--;
+
+  bcopy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16*4);
+  bcopy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16*4);
+  bcopy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2*4);
+  bcopy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1*4);
+  bcopy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1*4);
+  for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
+    dub = unpack_double (builtin_type_double,
+                        &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
+                        &inv);
+    /* dub now in host byte order */
+    double_to_ieee_extended (ext_format_i960, &dub,
+                            &registers[REGISTER_BYTE (regnum)]);
+  }
+
+  registers_fetched ();
+  return 0;
+}
+
+static void
+nindy_prepare_to_store()
+{
+  nindy_fetch_registers(-1);
+}
+
+static int
+nindy_store_registers(regno)
+     int regno;
+{
+  struct nindy_regs nindy_regs;
+  int regnum, inv;
+  double dub;
+
+  bcopy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs,  16*4);
+  bcopy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
+  bcopy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw,     2*4);
+  bcopy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip,           1*4);
+  bcopy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw,         1*4);
+  /* Float regs.  Only works on IEEE_FLOAT hosts.  */
+  for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
+    ieee_extended_to_double (ext_format_i960,
+                            &registers[REGISTER_BYTE (regnum)], &dub);
+    /* dub now in host byte order */
+    /* FIXME-someday, the arguments to unpack_double are backward.
+       It expects a target double and returns a host; we pass the opposite.
+       This mostly works but not quite.  */
+    dub = unpack_double (builtin_type_double, &dub, &inv);
+    /* dub now in target byte order */
+    bcopy ((char *)&dub, &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
+       8);
+  }
+
+  immediate_quit++;
+  ninRegsPut( (char *) &nindy_regs );
+  immediate_quit--;
+  return 0;
+}
+
+/* Read a word from remote address ADDR and return it.
+ * This goes through the data cache.
+ */
+int
+nindy_fetch_word (addr)
+     CORE_ADDR addr;
+{
+       return dcache_fetch (addr);
+}
+
+/* Write a word WORD into remote address ADDR.
+   This goes through the data cache.  */
+
+void
+nindy_store_word (addr, word)
+     CORE_ADDR addr;
+     int word;
+{
+       dcache_poke (addr, word);
+}
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
+   to debugger memory starting at MYADDR.   Copy to inferior if
+   WRITE is nonzero.  Returns the length copied.
+
+   This is stolen almost directly from infptrace.c's child_xfer_memory,
+   which also deals with a word-oriented memory interface.  Sometime,
+   FIXME, rewrite this to not use the word-oriented routines.  */
+
+int
+nindy_xfer_inferior_memory(memaddr, myaddr, len, write)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int write;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & - sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+
+  if (write)
+    {
+      /* Fill start and end extra bytes of buffer with existing memory data.  */
+
+      if (addr != memaddr || len < (int)sizeof (int)) {
+       /* Need part of initial word -- fetch it.  */
+        buffer[0] = nindy_fetch_word (addr);
+      }
+
+      if (count > 1)           /* FIXME, avoid if even boundary */
+       {
+         buffer[count - 1]
+           = nindy_fetch_word (addr + (count - 1) * sizeof (int));
+       }
+
+      /* Copy data to be written over corresponding part of buffer */
+
+      bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+
+      /* Write the entire buffer.  */
+
+      for (i = 0; i < count; i++, addr += sizeof (int))
+       {
+         errno = 0;
+         nindy_store_word (addr, buffer[i]);
+         if (errno)
+           return 0;
+       }
+    }
+  else
+    {
+      /* Read all the longwords */
+      for (i = 0; i < count; i++, addr += sizeof (int))
+       {
+         errno = 0;
+         buffer[i] = nindy_fetch_word (addr);
+         if (errno)
+           return 0;
+         QUIT;
+       }
+
+      /* Copy appropriate bytes out of the buffer.  */
+      bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+    }
+  return len;
+}
+\f
+/* The data cache records all the data read from the remote machine
+   since the last time it stopped.
+
+   Each cache block holds 16 bytes of data
+   starting at a multiple-of-16 address.  */
+
+#define DCACHE_SIZE 64         /* Number of cache blocks */
+
+struct dcache_block {
+       struct dcache_block *next, *last;
+       unsigned int addr;      /* Address for which data is recorded.  */
+       int data[4];
+};
+
+struct dcache_block dcache_free, dcache_valid;
+
+/* Free all the data cache blocks, thus discarding all cached data.  */ 
+static
+void
+dcache_flush ()
+{
+  register struct dcache_block *db;
+
+  while ((db = dcache_valid.next) != &dcache_valid)
+    {
+      remque (db);
+      insque (db, &dcache_free);
+    }
+}
+
+/*
+ * If addr is present in the dcache, return the address of the block
+ * containing it.
+ */
+static
+struct dcache_block *
+dcache_hit (addr)
+     unsigned int addr;
+{
+  register struct dcache_block *db;
+
+  if (addr & 3)
+    abort ();
+
+  /* Search all cache blocks for one that is at this address.  */
+  db = dcache_valid.next;
+  while (db != &dcache_valid)
+    {
+      if ((addr & 0xfffffff0) == db->addr)
+       return db;
+      db = db->next;
+    }
+  return NULL;
+}
+
+/*  Return the int data at address ADDR in dcache block DC.  */
+static
+int
+dcache_value (db, addr)
+     struct dcache_block *db;
+     unsigned int addr;
+{
+  if (addr & 3)
+    abort ();
+  return (db->data[(addr>>2)&3]);
+}
+
+/* Get a free cache block, put or keep it on the valid list,
+   and return its address.  The caller should store into the block
+   the address and data that it describes, then remque it from the
+   free list and insert it into the valid list.  This procedure
+   prevents errors from creeping in if a ninMemGet is interrupted
+   (which used to put garbage blocks in the valid list...).  */
+static
+struct dcache_block *
+dcache_alloc ()
+{
+  register struct dcache_block *db;
+
+  if ((db = dcache_free.next) == &dcache_free)
+    {
+      /* If we can't get one from the free list, take last valid and put
+        it on the free list.  */
+      db = dcache_valid.last;
+      remque (db);
+      insque (db, &dcache_free);
+    }
+
+  remque (db);
+  insque (db, &dcache_valid);
+  return (db);
+}
+
+/* Return the contents of the word at address ADDR in the remote machine,
+   using the data cache.  */
+static
+int
+dcache_fetch (addr)
+     CORE_ADDR addr;
+{
+  register struct dcache_block *db;
+
+  db = dcache_hit (addr);
+  if (db == 0)
+    {
+      db = dcache_alloc ();
+      immediate_quit++;
+      ninMemGet(addr & ~0xf, (unsigned char *)db->data, 16);
+      immediate_quit--;
+      db->addr = addr & ~0xf;
+      remque (db);                     /* Off the free list */
+      insque (db, &dcache_valid);      /* On the valid list */
+    }
+  return (dcache_value (db, addr));
+}
+
+/* Write the word at ADDR both in the data cache and in the remote machine.  */
+static void
+dcache_poke (addr, data)
+     CORE_ADDR addr;
+     int data;
+{
+  register struct dcache_block *db;
+
+  /* First make sure the word is IN the cache.  DB is its cache block.  */
+  db = dcache_hit (addr);
+  if (db == 0)
+    {
+      db = dcache_alloc ();
+      immediate_quit++;
+      ninMemGet(addr & ~0xf, (unsigned char *)db->data, 16);
+      immediate_quit--;
+      db->addr = addr & ~0xf;
+      remque (db);                     /* Off the free list */
+      insque (db, &dcache_valid);      /* On the valid list */
+    }
+
+  /* Modify the word in the cache.  */
+  db->data[(addr>>2)&3] = data;
+
+  /* Send the changed word.  */
+  immediate_quit++;
+  ninMemPut(addr, (unsigned char *)&data, 4);
+  immediate_quit--;
+}
+
+/* The cache itself. */
+struct dcache_block the_cache[DCACHE_SIZE];
+
+/* Initialize the data cache.  */
+static void
+dcache_init ()
+{
+  register i;
+  register struct dcache_block *db;
+
+  db = the_cache;
+  dcache_free.next = dcache_free.last = &dcache_free;
+  dcache_valid.next = dcache_valid.last = &dcache_valid;
+  for (i=0;i<DCACHE_SIZE;i++,db++)
+    insque (db, &dcache_free);
+}
+
+
+static void
+nindy_create_inferior (execfile, args, env)
+     char *execfile;
+     char *args;
+     char **env;
+{
+  int entry_pt;
+  int pid;
+
+  if (args && *args)
+    error ("Can't pass arguments to remote NINDY process");
+
+  if (execfile == 0 || exec_bfd == 0)
+    error ("No exec file specified");
+
+  entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+  pid = 42;
+
+#ifdef CREATE_INFERIOR_HOOK
+  CREATE_INFERIOR_HOOK (pid);
+#endif  
+
+/* The "process" (board) is already stopped awaiting our commands, and
+   the program is already downloaded.  We just set its PC and go.  */
+
+  inferior_pid = pid;          /* Needed for wait_for_inferior below */
+
+  clear_proceed_status ();
+
+#if defined (START_INFERIOR_HOOK)
+  START_INFERIOR_HOOK ();
+#endif
+
+  /* Tell wait_for_inferior that we've started a new process.  */
+  init_wait_for_inferior ();
+
+  /* Set up the "saved terminal modes" of the inferior
+     based on what modes we are starting it with.  */
+  target_terminal_init ();
+
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  /* remote_start(args); */
+  /* trap_expected = 0; */
+  /* insert_step_breakpoint ();  FIXME, do we need this?  */
+  proceed ((CORE_ADDR)entry_pt, -1, 0);                /* Let 'er rip... */
+}
+
+static void
+reset_command(args, from_tty)
+     char *args;
+     int from_tty;
+{
+       if ( !nindy_fd ){
+           error( "No target system to reset -- use 'target nindy' command.");
+       }
+       if ( query("Really reset the target system?",0,0) ){
+               send_break( nindy_fd );
+               tty_flush( nindy_fd );
+       }
+}
+
+void
+nindy_kill (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  return;              /* Ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+
+   The program actually lives on in the remote processor's RAM, and may be
+   run again without a download.  Don't leave it full of breakpoint
+   instructions.  */
+
+void
+nindy_mourn_inferior ()
+{
+  remove_breakpoints ();
+  generic_mourn_inferior ();   /* Do all the proper things now */
+}
+\f
+/* This routine is run as a hook, just before the main command loop is
+   entered.  If gdb is configured for the i960, but has not had its
+   nindy target specified yet, this will loop prompting the user to do so.
+
+   Unlike the loop provided by Intel, we actually let the user get out
+   of this with a RETURN.  This is useful when e.g. simply examining
+   an i960 object file on the host system.  */
+
+nindy_before_main_loop ()
+{
+  char ttyname[100];
+  char *p, *p2;
+
+  setjmp(to_top_level);
+  while (current_target != &nindy_ops) { /* remote tty not specified yet */
+       if ( instream == stdin ){
+               printf("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit:  ");
+               fflush( stdout );
+       }
+       fgets( ttyname, sizeof(ttyname)-1, stdin );
+
+       /* Strip leading and trailing whitespace */
+       for ( p = ttyname; isspace(*p); p++ ){
+               ;
+       }
+       if ( *p == '\0' ){
+               return;         /* User just hit spaces or return, wants out */
+       }
+       for ( p2= p; !isspace(*p2) && (*p2 != '\0'); p2++ ){
+               ;
+       }
+       *p2= '\0';
+       if ( !strcmp("quit",p) ){
+               exit(1);
+       }
+
+       nindy_open( p, 1 );
+
+       /* Now that we have a tty open for talking to the remote machine,
+          download the executable file if one was specified.  */
+       if ( !setjmp(to_top_level) && exec_bfd ) {
+             target_load (bfd_get_filename (exec_bfd), 1);
+       }
+  }
+}
+\f
+/* Define the target subroutine names */
+
+struct target_ops nindy_ops = {
+       "nindy", "Remote serial target in i960 NINDY-specific protocol",
+       nindy_open, nindy_close,
+       0, nindy_detach, nindy_resume, nindy_wait,
+       nindy_fetch_registers, nindy_store_registers,
+       nindy_prepare_to_store, 0, 0, /* conv_from, conv_to */
+       nindy_xfer_inferior_memory, nindy_files_info,
+       0, 0, /* insert_breakpoint, remove_breakpoint, */
+       0, 0, 0, 0, 0,  /* Terminal crud */
+       nindy_kill,
+       nindy_load, add_syms_addr_command,
+       call_function_by_hand,
+       0, /* lookup_symbol */
+       nindy_create_inferior,
+       nindy_mourn_inferior,
+       process_stratum, 0, /* next */
+       1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
+       OPS_MAGIC,              /* Always the last thing */
+};
+
+void
+_initialize_nindy ()
+{
+  add_target (&nindy_ops);
+  add_com ("reset", class_obscure, reset_command,
+          "Send a 'break' to the remote target system.\n\
+Only useful if the target has been equipped with a circuit\n\
+to perform a hard reset when a break is detected.");
+}
diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c
new file mode 100644 (file)
index 0000000..63028e2
--- /dev/null
@@ -0,0 +1,1775 @@
+/* Memory-access and commands for remote VxWorks processes, for GDB.
+   Copyright (C) 1990-1991  Free Software Foundation, Inc.
+   Contributed by Wind River Systems and Cygnus Support.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "wait.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "command.h"
+#include "symtab.h"
+#include "symfile.h"           /* for struct complaint */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#define free bogon_free                /* Sun claims "int free()" not void */
+#include <rpc/rpc.h>
+#undef free
+#include <sys/time.h>          /* UTek's <rpc/rpc.h> doesn't #incl this */
+#include <netdb.h>
+#include <ptrace.h>
+#include "xdr_ptrace.h"
+#include "xdr_ld.h"
+#include "xdr_rdb.h"
+#include "dbgRpcLib.h"
+
+/* get rid of value.h if possible */
+#include <value.h>
+#include <symtab.h>
+extern value call_function_by_hand ();
+extern void symbol_file_command ();
+extern void add_syms_addr_command ();
+extern int stop_soon_quietly;          /* for wait_for_inferior */
+
+static int net_ptrace_clnt_call ();    /* Forward decl */
+static enum clnt_stat net_clnt_call ();        /* Forward decl */
+extern struct target_ops vx_ops, vx_run_ops;   /* Forward declaration */
+
+/* Saved name of target host and called function for "info files".
+   Both malloc'd.  */
+
+static char *vx_host;
+static char *vx_running;               /* Called function */
+
+/* Nonzero means target that is being debugged remotely has a floating
+   point processor.  */
+
+static int target_has_fp;
+
+/* Default error message when the network is forking up.  */
+
+static const char rpcerr[] = "network target debugging:  rpc error";
+
+CLIENT *pClient;         /* client used in net debugging */
+static int ptraceSock = RPC_ANYSOCK;
+
+enum clnt_stat net_clnt_call();
+static void parse_args ();
+
+static struct timeval rpcTimeout = { 10, 0 };
+
+static char *skip_white_space ();
+static char *find_white_space ();
+/* Tell the VxWorks target system to download a file.
+   The load addresses of the text, data, and bss segments are
+   stored in pTextAddr, pDataAddr, and *pBssAddr (respectively).
+   Returns 0 for success, -1 for failure.  */
+
+static int
+net_load (filename, pTextAddr, pDataAddr, pBssAddr)
+    char *filename;
+    CORE_ADDR *pTextAddr;
+    CORE_ADDR *pDataAddr;
+    CORE_ADDR *pBssAddr;
+    {
+    enum clnt_stat status;
+    struct ldfile ldstruct;
+    struct timeval load_timeout;
+    bzero ((char *) &ldstruct, sizeof (ldstruct));
+
+    /* We invoke clnt_call () here directly, instead of through
+       net_clnt_call (), because we need to set a large timeout value.
+       The load on the target side can take quite a while, easily
+       more than 10 seconds.  The user can kill this call by typing
+       CTRL-C if there really is a problem with the load.  
+       
+       Do not change the tv_sec value without checking -- select() imposes
+       a limit of 10**8 on it for no good reason that I can see...  */
+
+    load_timeout.tv_sec = 99999999;   /* A large number, effectively inf. */
+    load_timeout.tv_usec = 0;
+    status = clnt_call (pClient, VX_LOAD, xdr_wrapstring, &filename, xdr_ldfile,
+                       &ldstruct, load_timeout);
+
+    if (status == RPC_SUCCESS)
+      {
+        if (*ldstruct.name == NULL)    /* load failed on VxWorks side */
+          return -1;
+       *pTextAddr = ldstruct.txt_addr;
+       *pDataAddr = ldstruct.data_addr;
+       *pBssAddr = ldstruct.bss_addr;
+       return 0;
+      }
+    else
+        return -1;
+    }
+      
+/* returns 0 if successful, errno if RPC failed or VxWorks complains. */
+
+static int
+net_break (addr, procnum)
+    int addr;
+    u_long procnum;
+    {
+    enum clnt_stat status;
+    int break_status;
+    Rptrace ptrace_in;  /* XXX This is stupid.  It doesn't need to be a ptrace
+                           structure.  How about something smaller? */
+
+    bzero ((char *) &ptrace_in, sizeof (ptrace_in));
+    break_status = 0;
+
+    ptrace_in.addr = addr;
+    ptrace_in.pid = inferior_pid;
+
+    status = net_clnt_call (procnum, xdr_rptrace, &ptrace_in, xdr_int,
+                           &break_status);
+
+    if (status != RPC_SUCCESS)
+       return errno;
+
+    if (break_status == -1)
+      return ENOMEM;
+    return break_status;       /* probably (FIXME) zero */
+    }
+/* returns 0 if successful, errno otherwise */
+
+int
+vx_insert_breakpoint (addr)
+    int addr;
+    {
+    return net_break (addr, VX_BREAK_ADD);
+    }
+
+/* returns 0 if successful, errno otherwise */
+
+int
+vx_remove_breakpoint (addr)
+    int addr;
+    {
+    return net_break (addr, VX_BREAK_DELETE);
+    }
+
+/* Call a function on the VxWorks target system.
+   ARGS is a vector of values of arguments (NARGS of them).
+   FUNCTION is a value, the function to be called.
+   Returns a struct value * representing what the function returned.
+   May fail to return, if a breakpoint or signal is hit
+   during the execution of the function.  */
+
+#ifdef FIXME
+/* FIXME, function calls are really fried.  GO back to manual method. */
+value
+vx_call_function (function, nargs, args)
+     value function;
+     int nargs;
+     value *args;
+{
+  register CORE_ADDR sp;
+  register int i;
+  CORE_ADDR start_sp;
+  static REGISTER_TYPE dummy[] = CALL_DUMMY;
+  REGISTER_TYPE dummy1[sizeof dummy / sizeof (REGISTER_TYPE)];
+  CORE_ADDR old_sp;
+  struct type *value_type;
+  unsigned char struct_return;
+  CORE_ADDR struct_addr;
+  struct inferior_status inf_status;
+  struct cleanup *old_chain;
+  CORE_ADDR funaddr;
+  int using_gcc;
+
+  save_inferior_status (&inf_status, 1);
+  old_chain = make_cleanup (restore_inferior_status, &inf_status);
+
+  /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
+     (and POP_FRAME for restoring them).  (At least on most machines)
+     they are saved on the stack in the inferior.  */
+  PUSH_DUMMY_FRAME;
+
+  old_sp = sp = read_register (SP_REGNUM);
+
+#if 1 INNER_THAN 2             /* Stack grows down */
+  sp -= sizeof dummy;
+  start_sp = sp;
+#else                          /* Stack grows up */
+  start_sp = sp;
+  sp += sizeof dummy;
+#endif
+
+  funaddr = find_function_addr (function, &value_type);
+
+  {
+    struct block *b = block_for_pc (funaddr);
+    /* If compiled without -g, assume GCC.  */
+    using_gcc = b == NULL || BLOCK_GCC_COMPILED (b);
+  }
+
+  /* Are we returning a value using a structure return or a normal
+     value return? */
+
+  struct_return = using_struct_return (function, funaddr, value_type,
+                                      using_gcc);
+
+  /* Create a call sequence customized for this function
+     and the number of arguments for it.  */
+  bcopy (dummy, dummy1, sizeof dummy);
+  FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+                 value_type, using_gcc);
+
+#if CALL_DUMMY_LOCATION == ON_STACK
+  write_memory (start_sp, dummy1, sizeof dummy);
+
+#else /* Not on stack.  */
+#if CALL_DUMMY_LOCATION == BEFORE_TEXT_END
+  /* Convex Unix prohibits executing in the stack segment. */
+  /* Hope there is empty room at the top of the text segment. */
+  {
+    static checked = 0;
+    if (!checked)
+      for (start_sp = text_end - sizeof dummy; start_sp < text_end; ++start_sp)
+       if (read_memory_integer (start_sp, 1) != 0)
+         error ("text segment full -- no place to put call");
+    checked = 1;
+    sp = old_sp;
+    start_sp = text_end - sizeof dummy;
+    write_memory (start_sp, dummy1, sizeof dummy);
+  }
+#else /* After text_end.  */
+  {
+    int errcode;
+    sp = old_sp;
+    start_sp = text_end;
+    errcode = target_write_memory (start_sp, dummy1, sizeof dummy);
+    if (errcode != 0)
+      error ("Cannot write text segment -- call_function failed");
+  }
+#endif /* After text_end.  */
+#endif /* Not on stack.  */
+
+#ifdef STACK_ALIGN
+  /* If stack grows down, we must leave a hole at the top. */
+  {
+    int len = 0;
+
+    /* Reserve space for the return structure to be written on the
+       stack, if necessary */
+
+    if (struct_return)
+      len += TYPE_LENGTH (value_type);
+    
+    for (i = nargs - 1; i >= 0; i--)
+      len += TYPE_LENGTH (VALUE_TYPE (value_arg_coerce (args[i])));
+#ifdef CALL_DUMMY_STACK_ADJUST
+    len += CALL_DUMMY_STACK_ADJUST;
+#endif
+#if 1 INNER_THAN 2
+    sp -= STACK_ALIGN (len) - len;
+#else
+    sp += STACK_ALIGN (len) - len;
+#endif
+  }
+#endif /* STACK_ALIGN */
+
+    /* Reserve space for the return structure to be written on the
+       stack, if necessary */
+
+    if (struct_return)
+      {
+#if 1 INNER_THAN 2
+       sp -= TYPE_LENGTH (value_type);
+       struct_addr = sp;
+#else
+       struct_addr = sp;
+       sp += TYPE_LENGTH (value_type);
+#endif
+      }
+
+#if defined (REG_STRUCT_HAS_ADDR)
+  {
+    /* This is a machine like the sparc, where we need to pass a pointer
+       to the structure, not the structure itself.  */
+    if (REG_STRUCT_HAS_ADDR (using_gcc))
+      for (i = nargs - 1; i >= 0; i--)
+       if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT)
+         {
+           CORE_ADDR addr;
+#if !(1 INNER_THAN 2)
+           /* The stack grows up, so the address of the thing we push
+              is the stack pointer before we push it.  */
+           addr = sp;
+#endif
+           /* Push the structure.  */
+           sp = value_push (sp, args[i]);
+#if 1 INNER_THAN 2
+           /* The stack grows down, so the address of the thing we push
+              is the stack pointer after we push it.  */
+           addr = sp;
+#endif
+           /* The value we're going to pass is the address of the thing
+              we just pushed.  */
+           args[i] = value_from_long (builtin_type_long, (LONGEST) addr);
+         }
+  }
+#endif /* REG_STRUCT_HAS_ADDR.  */
+
+#ifdef PUSH_ARGUMENTS
+  PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
+#else /* !PUSH_ARGUMENTS */
+  for (i = nargs - 1; i >= 0; i--)
+    sp = value_arg_push (sp, args[i]);
+#endif /* !PUSH_ARGUMENTS */
+
+#ifdef CALL_DUMMY_STACK_ADJUST
+#if 1 INNER_THAN 2
+  sp -= CALL_DUMMY_STACK_ADJUST;
+#else
+  sp += CALL_DUMMY_STACK_ADJUST;
+#endif
+#endif /* CALL_DUMMY_STACK_ADJUST */
+
+  /* Store the address at which the structure is supposed to be
+     written.  Note that this (and the code which reserved the space
+     above) assumes that gcc was used to compile this function.  Since
+     it doesn't cost us anything but space and if the function is pcc
+     it will ignore this value, we will make that assumption.
+
+     Also note that on some machines (like the sparc) pcc uses a 
+     convention like gcc's.  */
+
+  if (struct_return)
+    STORE_STRUCT_RETURN (struct_addr, sp);
+
+  /* Write the stack pointer.  This is here because the statements above
+     might fool with it.  On SPARC, this write also stores the register
+     window into the right place in the new stack frame, which otherwise
+     wouldn't happen.  (See write_inferior_registers in sparc-xdep.c.)  */
+  write_register (SP_REGNUM, sp);
+
+  /* Figure out the value returned by the function.  */
+  {
+    char retbuf[REGISTER_BYTES];
+
+    /* Execute the stack dummy routine, calling FUNCTION.
+       When it is done, discard the empty frame
+       after storing the contents of all regs into retbuf.  */
+    run_stack_dummy (start_sp + CALL_DUMMY_START_OFFSET, retbuf);
+
+    do_cleanups (old_chain);
+
+    return value_being_returned (value_type, retbuf, struct_return);
+  }
+}
+/* should return a value of some sort */
+value
+vx_call_function (funcAddr, nargs, args, valueType)
+    char *funcAddr;
+    int nargs;
+    value *args;
+    struct type * valueType;
+{
+    int i;
+    func_call funcInfo;
+    arg_value *argValue;
+    enum clnt_stat status;
+    register int len;
+    arg_value funcReturn;
+    value gdbValue;
+
+    argValue = (arg_value *) xmalloc (nargs * sizeof (arg_value));
+
+    bzero (argValue, nargs * sizeof (arg_value));
+    bzero (&funcReturn, sizeof (funcReturn));
+
+    for (i = nargs - 1; i >= 0; i--)
+       {
+       len = TYPE_LENGTH (VALUE_TYPE (args [i]));
+
+       switch (TYPE_CODE (VALUE_TYPE (args[i])))
+           {
+           /* XXX put other types here.  Where's CHAR, etc??? */
+
+           case TYPE_CODE_FLT:
+               argValue[i].type = T_FLOAT;
+               break;
+           case TYPE_CODE_INT:
+           case TYPE_CODE_PTR:
+           case TYPE_CODE_ENUM:
+           case TYPE_CODE_FUNC:
+               argValue[i].type = T_INT;
+               break;
+
+           case TYPE_CODE_UNDEF:
+           case TYPE_CODE_ARRAY:
+           case TYPE_CODE_STRUCT:
+           case TYPE_CODE_UNION:
+           case TYPE_CODE_VOID:
+           case TYPE_CODE_SET:
+           case TYPE_CODE_RANGE:
+           case TYPE_CODE_PASCAL_ARRAY:
+           case TYPE_CODE_MEMBER:          /* C++ */
+           case TYPE_CODE_METHOD:          /* C++ */
+           case TYPE_CODE_REF:             /* C++ */
+           default:
+               error ("No corresponding VxWorks type for %d.  CHECK IT OUT!!!\n",
+                       TYPE_CODE(VALUE_TYPE(args[i])));
+           } /* switch */
+       if (TYPE_CODE(VALUE_TYPE(args[i])) == TYPE_CODE_FUNC)
+           argValue[i].arg_value_u.v_int = VALUE_ADDRESS(args[i]);
+       else
+           bcopy (VALUE_CONTENTS (args[i]), (char *) &argValue[i].arg_value_u,
+                  len);
+       }
+
+    /* XXX what should the type of this function addr be?
+     * XXX Both in gdb and vxWorks
+     */
+    funcInfo.func_addr = (int) funcAddr;
+    funcInfo.args.args_len = nargs;
+    funcInfo.args.args_val = argValue;
+
+    status = net_clnt_call (VX_CALL_FUNC, xdr_func_call, (char *) &funcInfo,
+                           xdr_arg_value, &funcReturn);
+
+    free ((char *) argValue);
+
+    if (status == RPC_SUCCESS)
+       {
+       /* XXX this assumes that vxWorks ALWAYS returns an int, and that
+        * XXX gdb isn't expecting anything more
+        */
+
+       /*******************
+       if (funcReturn.type == T_UNKNOWN)
+           return YYYXXX...;
+       *******************/
+       gdbValue = allocate_value (valueType);
+       bcopy (&funcReturn.arg_value_u.v_int, VALUE_CONTENTS (gdbValue),
+               sizeof (int));
+        return gdbValue;
+       }
+    else 
+       error (rpcerr);
+    }
+#endif /* FIXME */
+/* Start an inferior process and sets inferior_pid to its pid.
+   EXEC_FILE is the file to run.
+   ALLARGS is a string containing the arguments to the program.
+   ENV is the environment vector to pass.
+   Returns process id.  Errors reported with error().
+   On VxWorks, we ignore exec_file.  */
+void
+vx_create_inferior (exec_file, args, env)
+     char *exec_file;
+     char *args;
+     char **env;
+{
+  enum clnt_stat status;
+  arg_array passArgs;
+  TASK_START taskStart;
+
+  bzero ((char *) &passArgs, sizeof (passArgs));
+  bzero ((char *) &taskStart, sizeof (taskStart));
+
+  /* parse arguments, put them in passArgs */
+
+  parse_args (args, &passArgs);
+
+  if (passArgs.arg_array_len == 0)
+    error ("You must specify a function name to run, and arguments if any");
+
+  status = net_clnt_call (PROCESS_START, xdr_arg_array, &passArgs,
+                         xdr_TASK_START, &taskStart);
+
+  if ((status != RPC_SUCCESS) || (taskStart.status == -1))
+    error ("Can't create process on remote target machine");
+
+  /* Save the name of the running function */
+  vx_running = savestring (passArgs.arg_array_val[0],
+                          strlen (passArgs.arg_array_val[0]));
+
+#ifdef CREATE_INFERIOR_HOOK
+  CREATE_INFERIOR_HOOK (pid);
+#endif  
+
+  push_target (&vx_run_ops);
+  inferior_pid = taskStart.pid;
+
+#if defined (START_INFERIOR_HOOK)
+  START_INFERIOR_HOOK ();
+#endif
+
+  /* We will get a trace trap after one instruction.
+     Insert breakpoints and continue.  */
+
+  init_wait_for_inferior ();
+
+  /* Set up the "saved terminal modes" of the inferior
+     based on what modes we are starting it with.  */
+  target_terminal_init ();
+
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  /* remote_start(args); */
+  /* trap_expected = 0; */
+  stop_soon_quietly = 1;
+  wait_for_inferior ();                /* Get the task spawn event */
+  stop_soon_quietly = 0;
+
+  /* insert_step_breakpoint ();  FIXME, do we need this?  */
+  proceed(-1, -1, 0);
+}
+
+/* Fill ARGSTRUCT in argc/argv form with the arguments from the
+   argument string ARGSTRING.  */
+
+static void
+parse_args (arg_string, arg_struct)
+     register char *arg_string;
+     arg_array *arg_struct;
+{
+  register int arg_count = 0;  /* number of arguments */
+  register int arg_index = 0;
+  register char *p0;
+  bzero ((char *) arg_struct, sizeof (arg_array));
+  /* first count how many arguments there are */
+
+  p0 = arg_string;
+  while (*p0 != '\0')
+    {
+      if (*(p0 = skip_white_space (p0)) == '\0')
+       break;
+      p0 = find_white_space (p0);
+      arg_count++;
+    }
+
+  arg_struct->arg_array_len = arg_count;
+  arg_struct->arg_array_val = (char **) xmalloc ((arg_count + 1)
+                                                * sizeof (char *));
+
+  /* now copy argument strings into arg_struct.  */
+
+  while (*(arg_string = skip_white_space (arg_string)))
+    {
+      p0 = find_white_space (arg_string);
+      arg_struct->arg_array_val[arg_index++] = savestring (arg_string,
+                                                          p0 - arg_string);
+      arg_string = p0;
+    }
+
+  arg_struct->arg_array_val[arg_count] = NULL;
+}
+
+/* Advance a string pointer across whitespace and return a pointer
+   to the first non-white character.  */
+
+static char *
+skip_white_space (p)
+     register char *p;
+{
+  while (*p == ' ' || *p == '\t')
+    p++;
+  return p;
+}
+    
+/* Search for the first unquoted whitespace character in a string.
+   Returns a pointer to the character, or to the null terminator
+   if no whitespace is found.  */
+
+static char *
+find_white_space (p)
+     register char *p;
+{
+  register int c;
+
+  while ((c = *p) != ' ' && c != '\t' && c)
+    {
+      if (c == '\'' || c == '"')
+       {
+         while (*++p != c && *p)
+           {
+             if (*p == '\\')
+               p++;
+           }
+         if (!*p)
+           break;
+       }
+      p++;
+    }
+  return p;
+}
+    
+/* Poll the VxWorks target system for an event related
+   to the debugged task.
+   Returns -1 if remote wait failed, task status otherwise.  */
+
+int
+net_wait (pEvent)
+    RDB_EVENT *pEvent;
+{
+    int pid;
+    enum clnt_stat status;
+
+    bzero ((char *) pEvent, sizeof (RDB_EVENT));
+
+    pid = inferior_pid;
+    status = net_clnt_call (PROCESS_WAIT, xdr_int, &pid, xdr_RDB_EVENT, pEvent);
+
+    return (status == RPC_SUCCESS)? pEvent->status: -1;
+}
+    
+/* Suspend the remote task.
+   Returns -1 if suspend fails on target system, 0 otherwise.  */
+
+int
+net_quit ()
+{
+    int pid;
+    int quit_status;
+    enum clnt_stat status;
+
+    quit_status = 0;
+
+    /* don't let rdbTask suspend itself by passing a pid of 0 */
+
+    if ((pid = inferior_pid) == 0)
+       return -1;
+
+    status = net_clnt_call (VX_TASK_SUSPEND, xdr_int, &pid, xdr_int,
+                           &quit_status);
+
+    return (status == RPC_SUCCESS)? quit_status: -1;
+}
+
+/* Read a register or registers from the remote system.  */
+
+int
+vx_read_register (regno)
+     int regno;
+{
+  int status;
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  extern char registers[];
+
+  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
+  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+
+  /* FIXME, eventually only get the ones we need.  */
+  registers_fetched ();
+  
+  ptrace_in.pid = inferior_pid;
+  ptrace_out.info.more_data = (caddr_t) &inferior_registers;
+  status = net_ptrace_clnt_call (PTRACE_GETREGS, &ptrace_in, &ptrace_out);
+  if (status)
+    error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      return -1;
+    }
+  
+#ifdef I80960
+
+      bcopy ((char *) inferior_registers.r_lreg,
+            &registers[REGISTER_BYTE (R0_REGNUM)], 16 * sizeof (int));
+      bcopy ((char *) inferior_registers.r_greg,
+            &registers[REGISTER_BYTE (G0_REGNUM)], 16 * sizeof (int));
+
+      /* Don't assume that a location in registers[] is properly aligned.  */
+
+      bcopy ((char *) &inferior_registers.r_pcw,
+            &registers[REGISTER_BYTE (PCW_REGNUM)], sizeof (int));
+      bcopy ((char *) &inferior_registers.r_acw,
+            &registers[REGISTER_BYTE (ACW_REGNUM)], sizeof (int));
+      bcopy ((char *) &inferior_registers.r_lreg[2],   /* r2 (RIP) -> IP */
+            &registers[REGISTER_BYTE (IP_REGNUM)], sizeof (int));
+      bcopy ((char *) &inferior_registers.r_tcw,
+            &registers[REGISTER_BYTE (TCW_REGNUM)], sizeof (int));
+
+      /* If the target has floating point registers, fetch them.
+        Otherwise, zero the floating point register values in
+        registers[] for good measure, even though we might not
+        need to.  */
+
+      if (target_has_fp)
+       {
+         ptrace_in.pid = inferior_pid;
+         ptrace_out.info.more_data = (caddr_t) &inferior_fp_registers;
+         status = net_ptrace_clnt_call (PTRACE_GETFPREGS, &ptrace_in, &ptrace_out);
+         if (status)
+           error (rpcerr);
+         if (ptrace_out.status == -1)
+           {
+             errno = ptrace_out.errno;
+             return -1;
+           }
+         
+         bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+                REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
+       }
+      else
+       {
+         bzero ((char *) &registers[REGISTER_BYTE (FP0_REGNUM)],
+                REGISTER_RAW_SIZE (FP0_REGNUM) * 4);
+       }
+
+#else  /* not 960, thus must be 68000:  FIXME!  */
+
+  bcopy (&inferior_registers, registers, 16 * 4);
+  *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+  *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+
+  if (target_has_fp)
+    {
+      ptrace_in.pid = inferior_pid;
+      ptrace_out.info.more_data = (caddr_t) &inferior_fp_registers;
+      status = net_ptrace_clnt_call (PTRACE_GETFPREGS, &ptrace_in, &ptrace_out);
+      if (status)
+       error (rpcerr);
+      if (ptrace_out.status == -1)
+       {
+         errno = ptrace_out.errno;
+         return -1;
+       }
+      
+      bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+            sizeof inferior_fp_registers.fps_regs);
+      bcopy (&inferior_fp_registers.fps_control,
+        &registers[REGISTER_BYTE (FPC_REGNUM)],
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+    }
+  else
+    {
+      bzero (&registers[REGISTER_BYTE (FP0_REGNUM)],
+            sizeof inferior_fp_registers.fps_regs);
+      bzero (&registers[REGISTER_BYTE (FPC_REGNUM)],
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+    }
+#endif  /* various architectures */
+
+  return 0;
+}
+
+/* Prepare to store registers.  Since we will store all of them,
+   read out their current values now.  */
+
+void
+vx_prepare_to_store ()
+{
+  vx_read_register (-1);
+}
+
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+   /* FIXME, look at REGNO to save time here */
+
+vx_write_register (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  extern char registers[];
+  int status;
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+
+  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
+  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+
+#ifdef I80960
+
+  bcopy (&registers[REGISTER_BYTE (R0_REGNUM)],
+        (char *) inferior_registers.r_lreg, 16 * sizeof (int));
+  bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
+        (char *) inferior_registers.r_greg, 16 * sizeof (int));
+
+  /* Don't assume that a location in registers[] is properly aligned.  */
+
+  bcopy (&registers[REGISTER_BYTE (PCW_REGNUM)],
+        (char *) &inferior_registers.r_pcw, sizeof (int));
+  bcopy (&registers[REGISTER_BYTE (ACW_REGNUM)],
+        (char *) &inferior_registers.r_acw, sizeof (int));
+  bcopy (&registers[REGISTER_BYTE (TCW_REGNUM)],
+        (char *) &inferior_registers.r_tcw, sizeof (int));
+
+#else  /* not 960 -- assume 68k -- FIXME */
+
+  bcopy (registers, &inferior_registers, 16 * 4);
+  inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
+  inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
+
+#endif  /* Different register sets */
+
+  ptrace_in.pid = inferior_pid;
+  ptrace_in.info.ttype     = REGS;
+  ptrace_in.info.more_data = (caddr_t) &inferior_registers;
+
+  /* XXX change second param to be a proc number */
+  status = net_ptrace_clnt_call (PTRACE_SETREGS, &ptrace_in, &ptrace_out);
+  if (status)
+      error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      return -1;
+    }
+
+  /* Store floating point registers if the target has them.  */
+
+  if (target_has_fp)
+    {
+#ifdef I80960
+
+      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+            sizeof inferior_fp_registers.fps_regs);
+
+#else  /* not 960 -- assume 68k -- FIXME */
+
+      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+            sizeof inferior_fp_registers.fps_regs);
+      bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+        &inferior_fp_registers.fps_control,
+         sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+
+#endif  /* Different register sets */
+
+      ptrace_in.pid = inferior_pid;
+      ptrace_in.info.ttype     = FPREGS;
+      ptrace_in.info.more_data = (caddr_t) &inferior_fp_registers;
+
+      status = net_ptrace_clnt_call (PTRACE_SETFPREGS, &ptrace_in, &ptrace_out);
+      if (status)
+         error (rpcerr);
+      if (ptrace_out.status == -1)
+       {
+         errno = ptrace_out.errno;
+         return -1;
+       }
+    }
+  return 0;
+}
+
+/* Copy LEN bytes to or from remote inferior's memory starting at MEMADDR
+   to debugger memory starting at MYADDR.  WRITE is true if writing to the
+   inferior.
+   Result is the number of bytes written or read (zero if error).  The
+   protocol allows us to return a negative count, indicating that we can't
+   handle the current address but can handle one N bytes further, but
+   vxworks doesn't give us that information.  */
+
+int
+vx_xfer_memory (memaddr, myaddr, len, write)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int status;
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+  C_bytes data;
+
+  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
+  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+
+  ptrace_in.pid = inferior_pid;                /* XXX pid unnecessary for READDATA */
+  ptrace_in.addr = (int) memaddr;      /* Where from */
+  ptrace_in.data = len;                        /* How many bytes */
+
+  if (write)
+    {
+      ptrace_in.info.ttype     = DATA;
+      ptrace_in.info.more_data = (caddr_t) &data;
+
+      data.bytes = (caddr_t) myaddr;   /* Where from */
+      data.len   = len;                        /* How many bytes (again, for XDR) */
+
+      /* XXX change second param to be a proc number */
+      status = net_ptrace_clnt_call (PTRACE_WRITEDATA, &ptrace_in, &ptrace_out);
+    }
+  else
+    {
+      ptrace_out.info.more_data = (caddr_t) &data;
+      data.bytes = myaddr;             /* Where to */
+      data.len   = len;                        /* How many (again, for XDR) */
+
+      /* XXX change second param to be a proc number */
+      status = net_ptrace_clnt_call (PTRACE_READDATA, &ptrace_in, &ptrace_out);
+    }
+
+  if (status)
+      error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      return 0;                /* No bytes moved */
+    }
+  return len;          /* Moved *all* the bytes */
+}
+
+void
+vx_files_info ()
+{
+  printf ("\tAttached to host `%s'", vx_host);
+  printf (", which has %sfloating point", target_has_fp? "": "no ");
+  printf (".\n");
+}
+
+void
+vx_run_files_info ()
+{
+  printf ("\tRunning %s VxWorks process 0x%x", 
+         vx_running? "child": "attached",
+         inferior_pid);
+  if (vx_running)
+    printf (", function `%s'", vx_running);
+  printf(".\n");
+}
+
+void
+vx_resume (step, siggnal)
+     int step;
+     int siggnal;
+{
+  int status;
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+
+  if (siggnal != 0 && siggnal != stop_signal)
+    error ("Cannot send signals to VxWorks processes");
+
+  bzero ((char *) &ptrace_in, sizeof (ptrace_in));
+  bzero ((char *) &ptrace_out, sizeof (ptrace_out));
+
+  ptrace_in.pid = inferior_pid;
+  ptrace_in.addr = 1;  /* Target side insists on this, or it panics.  */
+
+  /* XXX change second param to be a proc number */
+  status = net_ptrace_clnt_call (step? PTRACE_SINGLESTEP: PTRACE_CONT,
+                                &ptrace_in, &ptrace_out);
+  if (status)
+      error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      perror_with_name ("Resuming remote process");
+    }
+}
+
+void
+vx_mourn_inferior ()
+{
+  pop_target ();               /* Pop back to no-child state */
+  generic_mourn_inferior ();
+}
+
+\f
+/* This function allows the addition of incrementally linked object files.  */
+
+void
+vx_load_command (arg_string, from_tty)
+     char* arg_string;
+     int from_tty;
+{
+  CORE_ADDR text_addr;
+  CORE_ADDR data_addr;
+  CORE_ADDR bss_addr;
+  
+  if (arg_string == 0)
+    error ("The load command takes a file name");
+
+  arg_string = tilde_expand (arg_string);
+  make_cleanup (free, arg_string);
+
+  dont_repeat ();
+
+  QUIT;
+  immediate_quit++;
+  if (net_load (arg_string, &text_addr, &data_addr, &bss_addr) == -1)
+    error ("Load failed on target machine");
+  immediate_quit--;
+
+  /* FIXME, for now we ignore data_addr and bss_addr.  */
+  symbol_file_add (arg_string, from_tty, text_addr, 0);
+}
+
+#ifdef FIXME  /* Not ready for prime time */
+/* Single step the target program at the source or machine level.
+   Takes an error exit if rpc fails.
+   Returns -1 if remote single-step operation fails, else 0.  */
+
+static int
+net_step ()
+{
+  enum clnt_stat status;
+  int step_status;
+  SOURCE_STEP source_step;
+
+  source_step.taskId = inferior_pid;
+
+  if (step_range_end)
+    {
+      source_step.startAddr = step_range_start;
+      source_step.endAddr = step_range_end;
+    }
+  else
+    {
+      source_step.startAddr = 0;
+      source_step.endAddr = 0;
+    }
+
+  status = net_clnt_call (VX_SOURCE_STEP, xdr_SOURCE_STEP, &source_step,
+                         xdr_int, &step_status);
+
+  if (status == RPC_SUCCESS)
+    return step_status;
+  else 
+    error (rpcerr);
+}
+#endif
+
+/* Emulate ptrace using RPC calls to the VxWorks target system.
+   Returns nonzero (-1) if RPC status to VxWorks is bad, 0 otherwise.  */
+
+static int
+net_ptrace_clnt_call (request, pPtraceIn, pPtraceOut)
+    enum ptracereq request;
+    Rptrace *pPtraceIn;
+    Ptrace_return *pPtraceOut;
+{
+  enum clnt_stat status;
+
+  status = net_clnt_call (request, xdr_rptrace, pPtraceIn, xdr_ptrace_return,
+                         pPtraceOut);
+
+  if (status != RPC_SUCCESS)
+      return -1;
+
+  return 0;
+}
+
+/* Query the target for the name of the file from which VxWorks was
+   booted.  pBootFile is the address of a pointer to the buffer to
+   receive the file name; if the pointer pointed to by pBootFile is 
+   NULL, memory for the buffer will be allocated by XDR.
+   Returns -1 if rpc failed, 0 otherwise.  */
+
+int
+net_get_boot_file (pBootFile)
+     char **pBootFile;
+{
+  enum clnt_stat status;
+
+  status = net_clnt_call (VX_BOOT_FILE_INQ, xdr_void, (char *) 0,
+                         xdr_wrapstring, pBootFile);
+  return (status == RPC_SUCCESS) ? 0 : -1;
+}
+
+/* Fetch a list of loaded object modules from the VxWorks target.
+   Returns -1 if rpc failed, 0 otherwise
+   There's no way to check if the returned loadTable is correct.
+   VxWorks doesn't check it.  */
+
+int
+net_get_symbols (pLoadTable)
+     ldtabl *pLoadTable;               /* return pointer to ldtabl here */
+{
+  enum clnt_stat status;
+
+  bzero ((char *) pLoadTable, sizeof (struct ldtabl));
+
+  status = net_clnt_call (VX_STATE_INQ, xdr_void, 0, xdr_ldtabl, pLoadTable);
+  return (status == RPC_SUCCESS) ? 0 : -1;
+}
+
+/* Look up a symbol in the VxWorks target's symbol table.
+   Returns status of symbol read on target side (0=success, -1=fail)
+   Returns -1 and complain()s if rpc fails.  */
+
+struct complaint cant_contact_target =
+  {"Lost contact with VxWorks target", 0, 0};
+
+int
+vx_lookup_symbol (name, pAddr)
+     char *name;               /* symbol name */
+     CORE_ADDR *pAddr;
+{
+  enum clnt_stat status;
+  SYMBOL_ADDR symbolAddr;
+
+  *pAddr = 0;
+  bzero ((char *) &symbolAddr, sizeof (symbolAddr));
+
+  status = net_clnt_call (VX_SYMBOL_INQ, xdr_wrapstring, &name,
+                         xdr_SYMBOL_ADDR, &symbolAddr);
+  if (status != RPC_SUCCESS) {
+      complain (&cant_contact_target, 0);
+      return -1;
+  }
+
+  *pAddr = symbolAddr.addr;
+  return symbolAddr.status;
+}
+
+/* Check to see if the VxWorks target has a floating point coprocessor.
+   Returns 1 if target has floating point processor, 0 otherwise.
+   Calls error() if rpc fails.  */
+
+int
+net_check_for_fp ()
+{
+  enum clnt_stat status;
+  bool_t fp = 0;       /* true if fp processor is present on target board */
+
+  status = net_clnt_call (VX_FP_INQUIRE, xdr_void, 0, xdr_bool, &fp);
+  if (status != RPC_SUCCESS)
+      error (rpcerr);
+
+   return (int) fp;
+}
+
+/* Establish an RPC connection with the VxWorks target system.
+   Calls error () if unable to establish connection.  */
+
+void
+net_connect (host)
+     char *host;
+{
+  struct sockaddr_in destAddr;
+  struct hostent *destHost;
+
+  /* get the internet address for the given host */
+
+  if ((destHost = (struct hostent *) gethostbyname (host)) == NULL)
+      error ("Invalid hostname.  Couldn't find remote host address.");
+
+  bzero (&destAddr, sizeof (destAddr));
+
+  destAddr.sin_addr.s_addr = * (u_long *) destHost->h_addr;
+  destAddr.sin_family      = AF_INET;
+  destAddr.sin_port        = 0;        /* set to actual port that remote
+                                  ptrace is listening on.  */
+
+  /* Create a tcp client transport on which to issue
+     calls to the remote ptrace server.  */
+
+  ptraceSock = RPC_ANYSOCK;
+  pClient = clnttcp_create (&destAddr, RDBPROG, RDBVERS, &ptraceSock, 0, 0);
+  /* FIXME, here is where we deal with different version numbers of the proto */
+  
+  if (pClient == NULL)
+    {
+      clnt_pcreateerror ("\tnet_connect");
+      error ("Couldn't connect to remote target.");
+    }
+}
+\f
+/* Sleep for the specified number of milliseconds 
+ * (assumed to be less than 1000).
+ * If select () is interrupted, returns immediately;
+ * takes an error exit if select () fails for some other reason.
+ */
+
+static void
+sleep_ms (ms)
+     long ms;
+{
+  struct timeval select_timeout;
+  int status;
+
+  select_timeout.tv_sec = 0;
+  select_timeout.tv_usec = ms * 1000;
+
+  status = select (0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &select_timeout);
+
+  if (status < 0 && errno != EINTR)
+    perror_with_name ("select");
+}
+
+/* Wait for control to return from inferior to debugger.
+   If inferior gets a signal, we may decide to start it up again
+   instead of returning.  That is why there is a loop in this function.
+   When this function actually returns it means the inferior
+   should be left stopped and GDB should read more commands.  */
+
+/* For network debugging with VxWorks.
+ * VxWorks knows when tasks hit breakpoints, receive signals, exit, etc,
+ * so vx_wait() receives this information directly from
+ * VxWorks instead of trying to figure out what happenned via a wait() call.
+ */
+
+static int
+vx_wait (status)
+     int *status;
+{
+  register int pid;
+  WAITTYPE w;
+  RDB_EVENT rdbEvent;
+  int quit_failed;
+
+  do
+    {
+      /* If CTRL-C is hit during this loop,
+        suspend the inferior process.  */
+
+      quit_failed = 0;
+      if (quit_flag)
+       {
+         quit_failed = (net_quit () == -1);
+         quit_flag = 0;
+       }
+
+      /* If a net_quit () or net_wait () call has failed,
+        allow the user to break the connection with the target.
+        We can't simply error () out of this loop, since the 
+        data structures representing the state of the inferior
+        are in an inconsistent state.  */
+
+      if (quit_failed || net_wait (&rdbEvent) == -1)
+       {
+         terminal_ours ();
+         if (query ("Can't %s.  Disconnect from target system? ",
+                    (quit_failed) ? "suspend remote task"
+                                  : "get status of remote task"))
+           {
+             target_mourn_inferior();
+             error ("Use the \"target\" command to reconnect.");
+           }
+         else
+           {
+             terminal_inferior ();
+             continue;
+           }
+       }
+      
+      pid = rdbEvent.taskId;
+      if (pid == 0)
+       {
+         sleep_ms (200);       /* FIXME Don't kill the network too badly */
+       }
+      else if (pid != inferior_pid)
+       fatal ("Bad pid for debugged task: 0x%x\n", pid);
+    } while (pid == 0);
+
+  /* FIXME, eventually do more then SIGTRAP on everything...  */
+  switch (rdbEvent.eventType)
+    {
+    case EVENT_EXIT:
+      WSETEXIT (w, 0);
+      /* FIXME is it possible to distinguish between a
+        XXX   normal vs abnormal exit in VxWorks? */
+      break;
+
+    case EVENT_START:          /* Task was just started. */
+      WSETSTOP (w, SIGTRAP);
+      break;
+
+    case EVENT_STOP:
+      WSETSTOP (w, SIGTRAP);
+      /* XXX was it stopped by a signal?  act accordingly */
+      break;
+
+    case EVENT_BREAK:          /* Breakpoint was hit. */
+      WSETSTOP (w, SIGTRAP);
+      break;
+
+    case EVENT_SUSPEND:                /* Task was suspended, probably by ^C. */
+      WSETSTOP (w, SIGINT);
+      break;
+
+    case EVENT_BUS_ERR:                /* Task made evil nasty reference. */
+      WSETSTOP (w, SIGBUS);
+      break;
+
+    case EVENT_ZERO_DIV:       /* Division by zero */
+      WSETSTOP (w, SIGFPE);    /* Like Unix, call it a float exception. */
+
+    case EVENT_SIGNAL:
+      /* The target is not running Unix, and its
+        faults/traces do not map nicely into Unix signals.
+        Make sure they do not get confused with Unix signals
+        by numbering them with values higher than the highest
+        legal Unix signal.  code in the arch-dependent PRINT_RANDOM_SIGNAL
+        routine will interpret the value for wait_for_inferior.  */
+      WSETSTOP (w, rdbEvent.sigType + NSIG);
+      break;
+    } /* switch */
+  *status = *(int *)&w;                /* Grumble union wait crap Grumble */
+  return pid;
+}
+\f
+static int
+symbol_stub (arg)
+     int arg;
+{
+  char *bootFile = (char *)arg;
+  symbol_file_command (bootFile, 0);
+  return 1;
+}
+
+static int
+add_symbol_stub (arg)
+     int arg;
+{
+  struct ldfile *pLoadFile = (struct ldfile *)arg;
+
+  printf("\t%s: ", pLoadFile->name);
+  symbol_file_add (pLoadFile->name, 0, pLoadFile->txt_addr, 0);
+  printf ("ok\n");
+  return 1;
+}
+/* Target command for VxWorks target systems.
+
+   Used in vxgdb.  Takes the name of a remote target machine
+   running vxWorks and connects to it to initialize remote network
+   debugging.  */
+
+static void
+vx_open (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  extern int close ();
+  char *bootFile;
+  extern char *source_path;
+  struct ldtabl loadTable;
+  struct ldfile *pLoadFile;
+  int i;
+  extern CLIENT *pClient;
+
+  if (!args)
+    error_no_arg ("target machine name");
+
+  unpush_target (&vx_ops);
+  printf ("Attaching remote machine across net...\n");
+  fflush (stdout);
+
+  /* Allow the user to kill the connect attempt by typing ^C.
+     Wait until the call to target_has_fp () completes before
+     disallowing an immediate quit, since even if net_connect ()
+     is successful, the remote debug server might be hung.  */
+
+  immediate_quit++;
+
+  net_connect (args);
+  target_has_fp = net_check_for_fp ();
+  printf_filtered ("Connected to %s.\n", args);
+
+  immediate_quit--;
+
+  push_target (&vx_ops);
+
+  /* Save a copy of the target host's name.  */
+  vx_host = savestring (args, strlen (args));
+
+  /* Find out the name of the file from which the target was booted
+     and load its symbol table.  */
+
+  printf_filtered ("Looking in Unix path for all loaded modules:\n");
+  bootFile = NULL;
+  if (!net_get_boot_file (&bootFile))
+    {
+      if (*bootFile) {
+       printf_filtered ("\t%s: ", bootFile);
+       if (catch_errors (symbol_stub, (int)bootFile,
+               "Error reading symbols from boot file"))
+         puts_filtered ("ok\n");
+      } else if (from_tty)
+       printf ("VxWorks kernel symbols not loaded.\n");
+    }
+  else
+    error ("Can't retrieve boot file name from target machine.");
+
+  clnt_freeres (pClient, xdr_wrapstring, &bootFile);
+
+  if (net_get_symbols (&loadTable) != 0)
+    error ("Can't read loaded modules from target machine");
+
+  i = 0-1;
+  while (++i < loadTable.tbl_size)
+    {
+      QUIT;    /* FIXME, avoids clnt_freeres below:  mem leak */
+      pLoadFile = &loadTable.tbl_ent [i];
+#ifdef WRS_ORIG
+  {
+    register int desc;
+    struct cleanup *old_chain;
+    char *fullname = NULL;
+
+    desc = openp (source_path, 0, pLoadFile->name, O_RDONLY, 0, &fullname);
+    if (desc < 0)
+       perror_with_name (pLoadFile->name);
+    old_chain = make_cleanup (close, desc);
+    add_file_at_addr (fullname, desc, pLoadFile->txt_addr, pLoadFile->data_addr,
+                     pLoadFile->bss_addr);
+    do_cleanups (old_chain);
+  }
+#else
+      /* Botches, FIXME:
+        (1)  Searches the PATH, not the source path.
+        (2)  data and bss are assumed to be at the usual offsets from text.  */
+      catch_errors (add_symbol_stub, (int)pLoadFile, (char *)0);
+#endif
+    }
+  printf_filtered ("Done.\n");
+
+  clnt_freeres (pClient, xdr_ldtabl, &loadTable);
+}
+\f
+/* attach_command --
+   takes a task started up outside of gdb and ``attaches'' to it.
+   This stops it cold in its tracks and allows us to start tracing it.  */
+
+static void
+vx_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int pid;
+  char *cptr = 0;
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+  int status;
+
+  dont_repeat();
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  pid = strtol (args, &cptr, 0);
+  if ((cptr == args) || (*cptr != '\0'))
+    error ("Invalid process-id -- give a single number in decimal or 0xhex");
+
+  if (from_tty)
+      printf ("Attaching pid 0x%x.\n", pid);
+
+  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
+  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
+  ptrace_in.pid = pid;
+
+  status = net_ptrace_clnt_call (PTRACE_ATTACH, &ptrace_in, &ptrace_out);
+  if (status == -1)
+    error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      perror_with_name ("Attaching remote process");
+    }
+
+  /* It worked... */
+  push_target (&vx_run_ops);
+  inferior_pid = pid;
+  vx_running = 0;
+
+#if defined (START_INFERIOR_HOOK)
+  START_INFERIOR_HOOK ();
+#endif
+
+  mark_breakpoints_out ();
+
+  /* Set up the "saved terminal modes" of the inferior
+     based on what modes we are starting it with.  */
+  target_terminal_init ();
+
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  /* We will get a task spawn event immediately.  */
+  init_wait_for_inferior ();
+  clear_proceed_status ();
+  stop_soon_quietly = 1;
+  wait_for_inferior ();
+  stop_soon_quietly = 0;
+  normal_stop ();
+}
+
+
+/* detach_command --
+   takes a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via the normal ptrace (PTRACE_TRACEME).  */
+
+static void
+vx_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+  int signal = 0;
+  int status;
+
+  if (args)
+    error ("Argument given to VxWorks \"detach\".");
+
+  if (from_tty)
+      printf ("Detaching pid 0x%x.\n", inferior_pid);
+
+  if (args)            /* FIXME, should be possible to leave suspended */
+    signal = atoi (args);
+  
+  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
+  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
+  ptrace_in.pid = inferior_pid;
+
+  status = net_ptrace_clnt_call (PTRACE_DETACH, &ptrace_in, &ptrace_out);
+  if (status == -1)
+    error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      perror_with_name ("Detaching VxWorks process");
+    }
+
+  inferior_pid = 0;
+  pop_target ();       /* go back to non-executing VxWorks connection */
+}
+
+/* vx_kill -- takes a running task and wipes it out.  */
+
+static void
+vx_kill (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  Rptrace ptrace_in;
+  Ptrace_return ptrace_out;
+  int status;
+
+  if (args)
+    error ("Argument given to VxWorks \"kill\".");
+
+  if (from_tty)
+      printf ("Killing pid 0x%x.\n", inferior_pid);
+
+  bzero ((char *)&ptrace_in,  sizeof (ptrace_in));
+  bzero ((char *)&ptrace_out, sizeof (ptrace_out));
+  ptrace_in.pid = inferior_pid;
+
+  status = net_ptrace_clnt_call (PTRACE_KILL, &ptrace_in, &ptrace_out);
+  if (status == -1)
+    error (rpcerr);
+  if (ptrace_out.status == -1)
+    {
+      errno = ptrace_out.errno;
+      perror_with_name ("Killing VxWorks process");
+    }
+
+  /* If it gives good status, the process is *gone*, no events remain.  */
+  inferior_pid = 0;
+  pop_target ();       /* go back to non-executing VxWorks connection */
+}
+
+/* Clean up from the VxWorks process target as it goes away.  */
+
+void
+vx_proc_close (quitting)
+     int quitting;
+{
+  inferior_pid = 0;            /* No longer have a process.  */
+  if (vx_running)
+    free (vx_running);
+  vx_running = 0;
+}
+\f
+/* Cross-net conversion of floats to and from extended form.
+   (This is needed because different target machines have different
+    extended floating point formats.)  */
+
+/* Convert from an extended float to a double.
+
+   The extended float is stored as raw data pointed to by FROM.
+   Return the converted value as raw data in the double pointed to by TO.
+*/
+
+static void
+vx_convert_to_virtual (regno, from, to)
+    int regno;
+    char *from;
+    char *to;
+{
+  enum clnt_stat status;
+
+  if (REGISTER_CONVERTIBLE (regno)) 
+    {
+      if (!target_has_fp) {
+       *(double *)to = 0.0;    /* Skip the trouble if no float anyway */
+       return;
+      }
+
+      status = net_clnt_call (VX_CONV_FROM_68881, xdr_ext_fp, from,
+                             xdr_double, to);
+
+      if (status == RPC_SUCCESS)
+         return;
+      else
+         error (rpcerr);
+    }
+  else
+    bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
+}
+
+
+/* The converse:  convert from a double to an extended float.
+
+   The double is stored as raw data pointed to by FROM.
+   Return the converted value as raw data in the extended
+   float pointed to by TO.
+*/
+
+static void
+vx_convert_from_virtual (regno, from, to)
+    int regno;
+    char *from;
+    char *to;
+{
+  enum clnt_stat status;
+
+  if (REGISTER_CONVERTIBLE (regno)) 
+    {
+      if (!target_has_fp) {
+       bzero (to, REGISTER_RAW_SIZE (FP0_REGNUM));     /* Shrug */
+       return;
+      }
+
+      status = net_clnt_call (VX_CONV_TO_68881, xdr_double, from,
+                             xdr_ext_fp, to);
+      if (status == RPC_SUCCESS)
+         return;
+      else
+         error (rpcerr);
+    }
+  else
+    bcopy (from, to, REGISTER_VIRTUAL_SIZE (regno));
+}
+\f
+/* Make an RPC call to the VxWorks target.
+   Returns RPC status.  */
+
+static enum clnt_stat
+net_clnt_call (procNum, inProc, in, outProc, out)
+    enum ptracereq procNum;
+    xdrproc_t inProc;
+    char *in;
+    xdrproc_t outProc;
+    char *out;
+{
+  enum clnt_stat status;
+  
+  status = clnt_call (pClient, procNum, inProc, in, outProc, out, rpcTimeout);
+
+  if (status != RPC_SUCCESS)
+      clnt_perrno (status);
+
+  return status;
+}
+
+/* Clean up before losing control.  */
+
+void
+vx_close (quitting)
+     int quitting;
+{
+  if (pClient)
+    clnt_destroy (pClient);    /* The net connection */
+  pClient = 0;
+
+  if (vx_host)
+    free (vx_host);            /* The hostname */
+  vx_host = 0;
+}
+
+
+/* Target ops structure for accessing memory and such over the net */
+
+struct target_ops vx_ops = {
+       "vxworks", "VxWorks target memory via RPC over TCP/IP",
+       vx_open, vx_close, vx_attach, 0, /* vx_detach, */
+       0, 0, /* resume, wait */
+       0, 0, /* read_reg, write_reg */
+       0, vx_convert_to_virtual, vx_convert_from_virtual,  /* prep_to_store, */
+       vx_xfer_memory, vx_files_info,
+       0, 0, /* insert_breakpoint, remove_breakpoint */
+       0, 0, 0, 0, 0,  /* terminal stuff */
+       0, /* vx_kill, */
+       vx_load_command, add_syms_addr_command,
+       0,  /* call_function */
+       vx_lookup_symbol,
+       vx_create_inferior, 0,  /* mourn_inferior */
+       core_stratum, 0, /* next */
+       1, 1, 0, 0, 0,  /* all mem, mem, stack, regs, exec */
+       OPS_MAGIC,              /* Always the last thing */
+};
+
+/* Target ops structure for accessing VxWorks child processes over the net */
+
+struct target_ops vx_run_ops = {
+       "vxprocess", "VxWorks process",
+       vx_open, vx_proc_close, 0, vx_detach, /* vx_attach */
+       vx_resume, vx_wait,
+       vx_read_register, vx_write_register,
+       vx_prepare_to_store, vx_convert_to_virtual, vx_convert_from_virtual,
+       vx_xfer_memory, vx_run_files_info,
+       vx_insert_breakpoint, vx_remove_breakpoint,
+       0, 0, 0, 0, 0,  /* terminal stuff */
+       vx_kill,
+       vx_load_command, add_syms_addr_command,
+       call_function_by_hand,  /* FIXME, calling fns is maybe botched? */
+       vx_lookup_symbol,
+       0, vx_mourn_inferior,
+       process_stratum, 0, /* next */
+       0, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
+                       /* all_mem is off to avoid spurious msg in "i files" */
+       OPS_MAGIC,              /* Always the last thing */
+};
+/* ==> Remember when reading at end of file, there are two "ops" structs here. */
+\f
+void
+_initialize_vx ()
+{
+  add_target (&vx_ops);
+  add_target (&vx_run_ops);
+}
diff --git a/gdb/saber.suppress b/gdb/saber.suppress
new file mode 100644 (file)
index 0000000..19fac4d
--- /dev/null
@@ -0,0 +1,411 @@
+
+
+/* Options for project */
+unsetopt ansi
+setopt auto_compile
+unsetopt auto_reload
+setopt auto_replace
+unsetopt batch_load
+unsetopt batch_run
+unsetopt cc_prog
+setopt ccargs               -g
+unsetopt create_file
+unsetopt debug_child
+unsetopt echo
+setopt edit_jobs            5
+unsetopt eight_bit
+setopt line_edit
+setopt line_meta
+setopt lint_load            2
+setopt lint_run             2
+setopt list_action
+setopt load_flags           -I. -g -I.. -I../vx-share
+unsetopt long_not_int
+unsetopt make_args
+setopt make_hfiles
+unsetopt make_offset
+unsetopt make_prog
+setopt make_symbol          #
+setopt mem_config           16384
+unsetopt mem_trace
+setopt num_proc             1
+unsetopt page_cmds
+setopt page_list            19
+unsetopt page_load
+unsetopt path
+setopt proto_path           . /s2/saber_dir30/sun4-40/proto /s2/saber_dir30/sun4-40/../common/proto
+unsetopt preprocessor
+setopt program_name         a.out
+unsetopt print_custom
+setopt print_pointer
+setopt print_string         20
+unsetopt save_memory
+setopt sbrk_size            1048576
+setopt src_err              3
+setopt src_step             1
+setopt src_stop             3
+setopt sys_load_flags       -L/lib -L/usr/lib -L/usr/local/lib -I/usr/include -Dunix -Dsun -Dsparc
+unsetopt tab_stop
+unsetopt terse_suppress
+unsetopt terse_where
+setopt unset_value          191
+unsetopt win_fork_nodup
+setopt win_no_raise
+unsetopt win_message_list
+unsetopt win_project_list
+/* Suppressions for project */
+suppress 6 in read_huge_number 
+/* Over/underflow <plus> */
+suppress 8 in read_huge_number 
+/* Over/underflow <multiply> */
+suppress 22 
+/* Pointer subtraction */
+suppress 22 in free_all_psymtabs 
+/* Pointer subtraction */
+suppress 22 in free_all_symtabs 
+/* Pointer subtraction */
+suppress 56 in print_string 
+/* Information lost <function> */
+suppress 65 "../bfd/bfd.c":379 
+/* Too many function arguments */
+suppress 65 on printf_filtered 
+/* Too many function arguments */
+suppress 65 on fprintf_filtered 
+/* Too many function arguments */
+suppress 65 on vfprintf_filtered 
+/* Too many function arguments */
+suppress 65 on query 
+/* Too many function arguments */
+suppress 65 on fatal_dump_core 
+/* Too many function arguments */
+suppress 65 on fatal 
+/* Too many function arguments */
+suppress 65 on error 
+/* Too many function arguments */
+suppress 65 on noprocess 
+/* Too many function arguments */
+suppress 65 
+/* Too many function arguments */
+suppress 66 on say 
+/* Too few function arguments */
+suppress 66 on printf_filtered 
+/* Too few function arguments */
+suppress 66 on fprintf_filtered 
+/* Too few function arguments */
+suppress 66 on vfprintf_filtered 
+/* Too few function arguments */
+suppress 66 on query 
+/* Too few function arguments */
+suppress 66 on fatal_dump_core 
+/* Too few function arguments */
+suppress 66 on fatal 
+/* Too few function arguments */
+suppress 66 on error 
+/* Too few function arguments */
+suppress 67 on printf_filtered 
+/* Signed/unsigned argument mismatch */
+suppress 67 on fprintf_filtered 
+/* Signed/unsigned argument mismatch */
+suppress 67 on vfprintf_filtered 
+/* Signed/unsigned argument mismatch */
+suppress 67 on query 
+/* Signed/unsigned argument mismatch */
+suppress 67 on fatal_dump_core 
+/* Signed/unsigned argument mismatch */
+suppress 67 on fatal 
+/* Signed/unsigned argument mismatch */
+suppress 67 on error 
+/* Signed/unsigned argument mismatch */
+suppress 67 
+/* Signed/unsigned argument mismatch */
+suppress 68 on bfd_get_section_contents 
+/* Benign argument mismatch */
+suppress 68 on _do_getblong 
+/* Benign argument mismatch */
+suppress 68 on supply_register 
+/* Benign argument mismatch */
+suppress 68 on target_write_memory 
+/* Benign argument mismatch */
+suppress 68 on write_register_bytes 
+/* Benign argument mismatch */
+suppress 68 on read_register_bytes 
+/* Benign argument mismatch */
+suppress 68 on read_memory 
+/* Benign argument mismatch */
+suppress 68 on say 
+/* Benign argument mismatch */
+suppress 68 on printf_filtered 
+/* Benign argument mismatch */
+suppress 68 on fprintf_filtered 
+/* Benign argument mismatch */
+suppress 68 on vfprintf_filtered 
+/* Benign argument mismatch */
+suppress 68 on query 
+/* Benign argument mismatch */
+suppress 68 on fatal_dump_core 
+/* Benign argument mismatch */
+suppress 68 on fatal 
+/* Benign argument mismatch */
+suppress 68 on error 
+/* Benign argument mismatch */
+suppress 68 in find_solib 
+/* Benign argument mismatch */
+suppress 68 on child_wait 
+/* Benign argument mismatch */
+suppress 68 on xrealloc 
+/* Benign argument mismatch */
+suppress 68 on myread 
+/* Benign argument mismatch */
+suppress 68 in do_cleanups 
+/* Benign argument mismatch */
+suppress 68 on make_cleanup 
+/* Benign argument mismatch */
+suppress 68 on target_read_memory 
+/* Benign argument mismatch */
+suppress 69 on printf_filtered 
+/* Serious argument mismatch */
+suppress 69 on fprintf_filtered 
+/* Serious argument mismatch */
+suppress 69 on vfprintf_filtered 
+/* Serious argument mismatch */
+suppress 69 on query 
+/* Serious argument mismatch */
+suppress 69 on fatal_dump_core 
+/* Serious argument mismatch */
+suppress 69 on fatal 
+/* Serious argument mismatch */
+suppress 69 on error 
+/* Serious argument mismatch */
+suppress 70 on printf_filtered 
+/* Passing illegal enumeration value */
+suppress 70 on fprintf_filtered 
+/* Passing illegal enumeration value */
+suppress 70 on vfprintf_filtered 
+/* Passing illegal enumeration value */
+suppress 70 on query 
+/* Passing illegal enumeration value */
+suppress 70 on fatal_dump_core 
+/* Passing illegal enumeration value */
+suppress 70 on fatal 
+/* Passing illegal enumeration value */
+suppress 70 on error 
+/* Passing illegal enumeration value */
+suppress 110 in printf_filtered 
+/* Signed/unsigned memory retrieval */
+suppress 110 in fprintf_filtered 
+/* Signed/unsigned memory retrieval */
+suppress 110 in vfprintf_filtered 
+/* Signed/unsigned memory retrieval */
+suppress 110 in query 
+/* Signed/unsigned memory retrieval */
+suppress 110 in fatal_dump_core 
+/* Signed/unsigned memory retrieval */
+suppress 110 in fatal 
+/* Signed/unsigned memory retrieval */
+suppress 110 in error 
+/* Signed/unsigned memory retrieval */
+suppress 112 in printf_filtered 
+/* Memory retrieval */
+suppress 112 in fprintf_filtered 
+/* Memory retrieval */
+suppress 112 in vfprintf_filtered 
+/* Memory retrieval */
+suppress 112 in query 
+/* Memory retrieval */
+suppress 112 in fatal_dump_core 
+/* Memory retrieval */
+suppress 112 in fatal 
+/* Memory retrieval */
+suppress 112 in error 
+/* Memory retrieval */
+suppress 112 
+/* Memory retrieval */
+suppress 112 ../symtab.c 
+/* Memory retrieval */
+suppress 112 in child_xfer_memory 
+/* Memory retrieval */
+suppress 165 in frame_saved_pc 
+/* Dereference */
+suppress 165 in get_prev_frame_info 
+/* Dereference */
+suppress 167 in get_prev_frame_info 
+/* Selection */
+suppress 167 in frame_saved_pc 
+/* Selection */
+suppress 442 in try_baudrate 
+/* Escape has null value */
+suppress 529 in read_range_type 
+/* Statement not reached */
+suppress 529 in process_one_symbol 
+/* Statement not reached */
+suppress 529 in unpack_double 
+/* Statement not reached */
+suppress 529 in wait_for_inferior 
+/* Statement not reached */
+suppress 529 in do_registers_info 
+/* Statement not reached */
+suppress 529 in value_from_register 
+/* Statement not reached */
+suppress 530 "../environ.c":69 
+/* Empty body of statement */
+suppress 530 "../remote-eb.c":333 
+/* Empty body of statement */
+suppress 530 "../remote-eb.c":331 
+/* Empty body of statement */
+suppress 530 "../remote-eb.c":324 
+/* Empty body of statement */
+suppress 530 "../dbxread.c":792 
+/* Empty body of statement */
+suppress 530 
+/* Empty body of statement */
+suppress 530 "../dbxread.c":796 
+/* Empty body of statement */
+suppress 546 in net_quit 
+/* Function exits through bottom */
+suppress 546 in net_wait 
+/* Function exits through bottom */
+suppress 546 in vx_remove_breakpoint 
+/* Function exits through bottom */
+suppress 546 in vx_insert_breakpoint 
+/* Function exits through bottom */
+suppress 546 in value_less 
+/* Function exits through bottom */
+suppress 546 in value_equal 
+/* Function exits through bottom */
+suppress 546 in unpack_long 
+/* Function exits through bottom */
+suppress 558 in read_range_type 
+/* Constant in conditional */
+suppress 558 in process_one_symbol 
+/* Constant in conditional */
+suppress 558 in read_dbx_symtab 
+/* Constant in conditional */
+suppress 558 in vx_write_register 
+/* Constant in conditional */
+suppress 558 in vx_read_register 
+/* Constant in conditional */
+suppress 558 in unpack_double 
+/* Constant in conditional */
+suppress 558 in wait_for_inferior 
+/* Constant in conditional */
+suppress 558 in do_registers_info 
+/* Constant in conditional */
+suppress 558 in value_from_register 
+/* Constant in conditional */
+suppress 560 in solib_address 
+/* Assignment within conditional */
+suppress 560 in solib_info 
+/* Assignment within conditional */
+suppress 560 in solib_add 
+/* Assignment within conditional */
+suppress 560 in read_type 
+/* Assignment within conditional */
+suppress 560 in type_print_base 
+/* Assignment within conditional */
+suppress 560 in type_print_derivation_info 
+/* Assignment within conditional */
+suppress 560 in block_depth 
+/* Assignment within conditional */
+suppress 560 in select_source_symtab 
+/* Assignment within conditional */
+suppress 560 in clear_value_history 
+/* Assignment within conditional */
+suppress 560 in clear_displays 
+/* Assignment within conditional */
+suppress 560 in initialize_main 
+/* Assignment within conditional */
+suppress 560 in echo_command 
+/* Assignment within conditional */
+suppress 560 in unset_in_environ 
+/* Assignment within conditional */
+suppress 560 in set_in_environ 
+/* Assignment within conditional */
+suppress 560 in get_in_environ 
+/* Assignment within conditional */
+suppress 560 in do_setshow_command 
+/* Assignment within conditional */
+suppress 560 in breakpoint_1 
+/* Assignment within conditional */
+suppress 590 on sig 
+/* Unused formal parameter */
+suppress 590 in nindy_create_inferior 
+/* Unused formal parameter */
+suppress 590 in add_to_section_table 
+/* Unused formal parameter */
+suppress 590 in vx_create_inferior 
+/* Unused formal parameter */
+suppress 590 in host_convert_from_virtual 
+/* Unused formal parameter */
+suppress 590 in host_convert_to_virtual 
+/* Unused formal parameter */
+suppress 590 on siggnal 
+/* Unused formal parameter */
+suppress 590 in init_sig 
+/* Unused formal parameter */
+suppress 590 in nindy_resume 
+/* Unused formal parameter */
+suppress 590 in set_history_size_command 
+/* Unused formal parameter */
+suppress 590 in not_just_help_class_command 
+/* Unused formal parameter */
+suppress 590 on regno 
+/* Unused formal parameter */
+suppress 590 on from_tty 
+/* Unused formal parameter */
+suppress 590 on args 
+/* Unused formal parameter */
+suppress 590 in process_symbol_pair 
+/* Unused formal parameter */
+suppress 591 in print_scalar_formatted 
+/* Unused automatic variable */
+suppress 592 on rcsid 
+/* Unused static */
+suppress 592 on check_break_insn_size 
+/* Unused static */
+suppress 594 in call_function_by_hand 
+/* Set but not used */
+suppress 594 in record_latest_value 
+/* Set but not used */
+suppress 594 in bpstat_stop_status 
+/* Set but not used */
+suppress 595 in coffstrip 
+/* Used before set */
+suppress 652 ../bfd.h 
+/* Declaration has no effect */
+suppress 652 /usr/include/machine/reg.h 
+/* Declaration has no effect */
+
+/* Signals caught and ignored */
+catch HUP
+catch QUIT
+catch ILL
+catch TRAP
+catch IOT
+catch EMT
+catch FPE
+catch KILL
+catch BUS
+catch SEGV
+catch SYS
+catch PIPE
+catch TERM
+catch URG
+catch STOP
+catch TSTP
+catch TTIN
+catch TTOU
+catch IO
+catch XCPU
+catch XFSZ
+catch VTALRM
+catch PROF
+catch LOST
+catch USR1
+catch USR2
+ignore INT
+ignore ALRM
+ignore CONT
+ignore CHLD
+ignore WINCH
+
+/* Status of project */
diff --git a/gdb/signals.h b/gdb/signals.h
new file mode 100644 (file)
index 0000000..a6218d9
--- /dev/null
@@ -0,0 +1,34 @@
+/* Signal handler definitions for GDB, the GNU Debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/*  This file is almost the same as including <signal.h> except that it
+    eliminates certain signal names when job control is not supported,
+    (or, on some systems, when job control is there but doesn't work
+    the way GDB expects it to work).  */
+
+#include <signal.h>
+
+#ifdef NO_JOB_CONTROL
+# undef SIGTSTP
+# undef SIGSTOP
+# undef SIGCONT
+# undef SIGTTIN
+# undef SIGTTOU
+#endif
diff --git a/gdb/signame.c b/gdb/signame.c
new file mode 100755 (executable)
index 0000000..740da40
--- /dev/null
@@ -0,0 +1,246 @@
+/* Convert between signal names and numbers.
+   Copyright (C) 1990 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <signal.h>
+#include "signame.h"
+
+#ifdef __STDC__
+#define CONST const
+#else
+#define CONST
+#endif
+
+#ifdef SYS_SIGLIST_MISSING
+/* There is too much variation in Sys V signal numbers and names, so
+   we must initialize them at runtime.  */
+
+static CONST char undoc[] = "unknown signal";
+
+CONST char *sys_siglist[NSIG];
+#endif /* SYS_SIGLIST_MISSING */
+
+/* Table of abbreviations for signals.  Note:  A given number can
+   appear more than once with different abbreviations.  */
+typedef struct
+  {
+    int number;
+    CONST char *abbrev;
+  } num_abbrev;
+static num_abbrev sig_table[NSIG*2];
+/* Number of elements of sig_table used.  */
+static int sig_table_nelts = 0;
+
+/* Enter signal number NUMBER into the tables with ABBREV and NAME.  */
+static void
+init_sig (number, abbrev, name)
+     int number;
+     CONST char *abbrev;
+     CONST char *name;
+{
+#ifdef SYS_SIGLIST_MISSING
+  sys_siglist[number] = name;
+#endif
+  sig_table[sig_table_nelts].number = number;
+  sig_table[sig_table_nelts++].abbrev = abbrev;
+}
+
+static void init_sigs ()
+{
+#ifdef SYS_SIGLIST_MISSING
+  /* Initialize signal names.  */
+       for (i = 0; i < NSIG; i++)
+               sys_siglist[i] = undoc;
+#endif /* SYS_SIGLIST_MISSING */
+
+  /* Initialize signal names.  */
+#if defined (SIGHUP)
+  init_sig (SIGHUP, "HUP", "Hangup");
+#endif
+#if defined (SIGINT)
+  init_sig (SIGINT, "INT", "Interrupt");
+#endif
+#if defined (SIGQUIT)
+  init_sig (SIGQUIT, "QUIT", "Quit");
+#endif
+#if defined (SIGILL)
+  init_sig (SIGILL, "ILL", "Illegal Instruction");
+#endif
+#if defined (SIGTRAP)
+  init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap");
+#endif
+  /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because
+     SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't.  */
+#if defined (SIGABRT)
+  init_sig (SIGABRT, "ABRT", "Aborted");
+#endif
+#if defined (SIGIOT)
+  init_sig (SIGIOT, "IOT", "IOT trap");
+#endif
+#if defined (SIGEMT)
+  init_sig (SIGEMT, "EMT", "EMT trap");
+#endif
+#if defined (SIGFPE)
+  init_sig (SIGFPE, "FPE", "Floating point exception");
+#endif
+#if defined (SIGKILL)
+  init_sig (SIGKILL, "KILL", "Killed");
+#endif
+#if defined (SIGBUS)
+  init_sig (SIGBUS, "BUS", "Bus error");
+#endif
+#if defined (SIGSEGV)
+  init_sig (SIGSEGV, "SEGV", "Segmentation fault");
+#endif
+#if defined (SIGSYS)
+  init_sig (SIGSYS, "SYS", "Bad system call");
+#endif
+#if defined (SIGPIPE)
+  init_sig (SIGPIPE, "PIPE", "Broken pipe");
+#endif
+#if defined (SIGALRM)
+  init_sig (SIGALRM, "ALRM", "Alarm clock");
+#endif
+#if defined (SIGTERM)
+  init_sig (SIGTERM, "TERM", "Terminated");
+#endif
+#if defined (SIGUSR1)
+  init_sig (SIGUSR1, "USR1", "User defined signal 1");
+#endif
+#if defined (SIGUSR2)
+  init_sig (SIGUSR2, "USR2", "User defined signal 2");
+#endif
+  /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that
+     is what is in POSIX.1.  */
+#if defined (SIGCHLD)
+  init_sig (SIGCHLD, "CHLD", "Child exited");
+#endif
+#if defined (SIGCLD)
+  init_sig (SIGCLD, "CLD", "Child exited");
+#endif
+#if defined (SIGPWR)
+  init_sig (SIGPWR, "PWR", "Power failure");
+#endif
+#if defined (SIGTSTP)
+  init_sig (SIGTSTP, "TSTP", "Stopped");
+#endif
+#if defined (SIGTTIN)
+  init_sig (SIGTTIN, "TTIN", "Stopped (tty input)");
+#endif
+#if defined (SIGTTOU)
+  init_sig (SIGTTOU, "TTOU", "Stopped (tty output)");
+#endif
+#if defined (SIGSTOP)
+  init_sig (SIGSTOP, "STOP", "Stopped (signal)");
+#endif
+#if defined (SIGXCPU)
+  init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded");
+#endif
+#if defined (SIGXFSZ)
+  init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded");
+#endif
+#if defined (SIGVTALRM)
+  init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired");
+#endif
+#if defined (SIGPROF)
+  init_sig (SIGPROF, "PROF", "Profiling timer expired");
+#endif
+#if defined (SIGWINCH)
+  /* "Window size changed" might be more accurate, but even if that
+     is all that it means now, perhaps in the future it will be
+     extended to cover other kinds of window changes.  */
+  init_sig (SIGWINCH, "WINCH", "Window changed");
+#endif
+#if defined (SIGCONT)
+  init_sig (SIGCONT, "CONT", "Continued");
+#endif
+#if defined (SIGURG)
+  init_sig (SIGURG, "URG", "Urgent I/O condition");
+#endif
+#if defined (SIGIO)
+  /* "I/O pending" has also been suggested.  A disadvantage is
+     that signal only happens when the process has
+     asked for it, not everytime I/O is pending.  Another disadvantage
+     is the confusion from giving it a different name than under Unix.  */
+  init_sig (SIGIO, "IO", "I/O possible");
+#endif
+#if defined (SIGWIND)
+  init_sig (SIGWIND, "WIND", "SIGWIND");
+#endif
+#if defined (SIGPHONE)
+  init_sig (SIGPHONE, "PHONE", "SIGPHONE");
+#endif
+#if defined (SIGPOLL)
+  init_sig (SIGPOLL, "POLL", "I/O possible");
+#endif
+#if defined (SIGLOST)
+  init_sig (SIGLOST, "LOST", "Resource lost");
+#endif
+}
+
+/* Return the abbreviation for signal NUMBER.  */
+char *
+sig_abbrev (number)
+     int number;
+{
+  int i;
+
+  for (i = 0; i < sig_table_nelts; i++)
+    if (sig_table[i].number == number)
+      return (char *)sig_table[i].abbrev;
+  return NULL;
+}
+
+/* Return the signal number for an ABBREV, or -1 if there is no
+   signal by that name.  */
+int
+sig_number (abbrev)
+     CONST char *abbrev;
+{
+  int i;
+
+  /* Skip over "SIG" if present.  */
+  if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G')
+    abbrev += 3;
+
+  for (i = 0; i < sig_table_nelts; i++)
+    if (abbrev[0] == sig_table[i].abbrev[0]
+       && strcmp (abbrev, sig_table[i].abbrev) == 0)
+      return sig_table[i].number;
+  return -1;
+}
+
+#if defined (SYS_SIGLIST_MISSING)
+/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
+   a colon, and followed by a newline.  */
+void
+psignal (signal, message)
+     unsigned signal;
+     CONST char *message;
+{
+  if (signal <= 0 || signal >= NSIG)
+    fprintf (stderr, "%s: unknown signal", message);
+  else
+    fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]);
+}
+#endif
+
+void
+_initialize_signame ()
+{
+       init_sigs ();
+}
diff --git a/gdb/signame.h b/gdb/signame.h
new file mode 100755 (executable)
index 0000000..83edfa8
--- /dev/null
@@ -0,0 +1,41 @@
+/* Convert between signal names and numbers.
+   Copyright (C) 1990 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Names for signals from 0 to NSIG-1.  */
+extern char *sys_siglist[];
+
+#ifdef __STDC__
+/* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER.
+   Do not return this as a const char *.  The caller might want to
+   assign it to a char *.  */
+char *sig_abbrev (int number);
+
+/* Return the signal number for an ABBREV, or -1 if there is no
+   signal by that name.  */
+int sig_number (const char *abbrev);
+
+/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
+   a colon, and followed by a newline.  */
+void psignal (unsigned signal, const char *message);
+
+#else
+
+char *sig_abbrev ();
+int sig_number ();
+void psignal ();
+
+#endif
diff --git a/gdb/sparc-opcode.h b/gdb/sparc-opcode.h
new file mode 100755 (executable)
index 0000000..473ab6f
--- /dev/null
@@ -0,0 +1,641 @@
+/* Table of opcodes for the sparc.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+GAS/GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GAS/GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GAS or GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ * Structure of an opcode table entry.
+ */
+struct sparc_opcode
+{
+    const char *name;
+    unsigned long int match;   /* Bits that must be set.  */
+    unsigned long int lose;    /* Bits that must not be set.  */
+    const char *args;
+    char flags;
+};
+
+#define        F_DELAYED       1       /* Delayed branch */
+#define        F_ALIAS         2       /* Alias for a "real" instruction */
+
+/*
+   All sparc opcodes are 32 bits, except for the `set' instruction (really
+   a macro), which is 64 bits.  It is handled as a special case.
+
+   The match component is a mask saying which bits must match a
+   particular opcode in order for an instruction to be an instance
+   of that opcode.
+
+   The args component is a string containing one character
+   for each operand of the instruction.
+
+Kinds of operands:
+   #    Number used by optimizer.  It is ignored.
+   1    rs1 register.
+   2    rs2 register.
+   d    rd register.
+   e    frs1 floating point register.
+   f    frs2 floating point register.
+   g    frsd floating point register.
+   b    crs1 coprocessor register
+   c    crs2 coprocessor register
+   D    crsd coprocessor register
+   h    22 high bits.
+   i    13 bit Immediate.
+   l    22 bit PC relative immediate.
+   L    30 bit PC relative immediate.
+   a    Annul.  The annul bit is set.
+   A    Alternate address space.  Stored as 8 bits.
+   C    Coprocessor state register.
+   F    floating point state register.
+   p    Processor state register.
+   q    Floating point queue.
+   r    Single register that is both rs1 and rsd.
+   Q    Coprocessor queue.
+   S    Special case.
+   t    Trap base register.
+   w    Window invalid mask register.
+   y    Y register.
+
+*/
+
+/* The order of the opcodes in this table is significant:
+   
+   * The assembler requires that all instances of the same mnemonic must be
+   consecutive.  If they aren't, the assembler will bomb at runtime.
+
+   * The disassembler should not care about the order of the opcodes.  */
+
+static struct sparc_opcode sparc_opcodes[] =
+{
+
+{ "ldd",        0xc1980000, 0x0060201f, "[1],D", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd",        0xc1982000, 0x00601fff, "[1],D", 0 }, /* ldd [rs1+0],d */
+{ "ldd",        0xc1982000, 0x00600000, "[1+i],D", 0 },
+{ "ldd",        0xc1982000, 0x00600000, "[i+1],D", 0 },
+{ "ldd",        0xc1980000, 0x00602000, "[1+2],D", 0 },
+{ "ldd",        0xc1180000, 0x00e0201f, "[1],g", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd",        0xc1182000, 0x00e01fff, "[1],g", 0 }, /* ldd [rs1+0],d */
+{ "ldd",        0xc1182000, 0x00e00000, "[1+i],g", 0 },
+{ "ldd",        0xc1182000, 0x00e00000, "[i+1],g", 0 },
+{ "ldd",        0xc1180000, 0x00e02000, "[1+2],g", 0 },
+{ "ldd",       0xc0180000, 0x01e0201f, "[1],d", 0 }, /* ldd [rs1+%g0],d */
+{ "ldd",        0xc0182000, 0x01e01fff, "[1],d", 0 }, /* ldd [rs1+0],d */
+{ "ldd",       0xc0182000, 0x01e00000, "[1+i],d", 0 },
+{ "ldd",       0xc0182000, 0x01e00000, "[i+1],d", 0 },
+{ "ldd",       0xc0180000, 0x01e02000, "[1+2],d", 0 },
+{ "ld",         0xc1880000, 0x0070201f, "[1],C", 0 }, /* ld [rs1+%g0],d */
+{ "ld",         0xc1882000, 0x00701fff, "[1],C", 0 }, /* ld [rs1+0],d */
+{ "ld",         0xc1882000, 0x00700000, "[1+i],C", 0 },
+{ "ld",         0xc1882000, 0x00700000, "[i+1],C", 0 },
+{ "ld",         0xc1880000, 0x00702000, "[1+2],C", 0 },
+{ "ld",         0xc1800000, 0x0078201f, "[1],D", 0 }, /* ld [rs1+%g0],d */
+{ "ld",         0xc1802000, 0x00781fff, "[1],D", 0 }, /* ld [rs1+0],d */
+{ "ld",         0xc1802000, 0x00780000, "[1+i],D", 0 },
+{ "ld",         0xc1802000, 0x00780000, "[i+1],D", 0 },
+{ "ld",         0xc1800000, 0x00782000, "[1+2],D", 0 },
+{ "ld",         0xc1080000, 0x00f0201f, "[1],F", 0 }, /* ld [rs1+%g0],d */
+{ "ld",         0xc1082000, 0x00f01fff, "[1],F", 0 }, /* ld [rs1+0],d */
+{ "ld",         0xc1082000, 0x00f00000, "[1+i],F", 0 },
+{ "ld",         0xc1082000, 0x00f00000, "[i+1],F", 0 },
+{ "ld",         0xc1080000, 0x00f02000, "[1+2],F", 0 },
+{ "ld",         0xc1000000, 0x00f8201f, "[1],g", 0 }, /* ld [rs1+%g0],d */
+{ "ld",         0xc1002000, 0x00f81fff, "[1],g", 0 }, /* ld [rs1+0],d */
+{ "ld",         0xc1002000, 0x00f80000, "[1+i],g", 0 },
+{ "ld",         0xc1002000, 0x00f80000, "[i+1],g", 0 },
+{ "ld",         0xc1000000, 0x00f82000, "[1+2],g", 0 },
+{ "ld",                0xc0000000, 0x01f8201f, "[1],d", 0 }, /* ld [rs1+%g0],d */
+{ "ld",                0xc0002000, 0x01f81fff, "[1],d", 0 }, /* ld [rs1+0],d */
+{ "ld",                0xc0002000, 0x01f80000, "[1+i],d", 0 },
+{ "ld",                0xc0002000, 0x01f80000, "[i+1],d", 0 },
+{ "ld",                0xc0000000, 0x01f82000, "[1+2],d", 0 },
+{ "ldstuba",    0xc0d80000, 0x0100201f, "[1]A,d", 0 }, /* ldstuba [rs1+%g0],d */
+{ "ldstuba",   0xc0d80000, 0x01002000, "[1+2]A,d", 0 },
+{ "ldsha",      0xc0d00000, 0x0128201f, "[1]A,d", 0 }, /* ldsha [rs1+%g0],d */
+{ "ldsha",     0xc0d00000, 0x01282000, "[1+2]A,d", 0 },
+{ "ldsba",      0xc0c80000, 0x0130201f, "[1]A,d", 0 }, /* ldsba [rs1+%g0],d */
+{ "ldsba",     0xc0c80000, 0x01302000, "[1+2]A,d", 0 },
+{ "ldda",       0xc0980000, 0x0160201f, "[1]A,d", 0 }, /* ldda [rs1+%g0],d */
+{ "ldda",      0xc0980000, 0x01602000, "[1+2]A,d", 0 },
+{ "lduha",      0xc0900000, 0x0168201f, "[1]A,d", 0 }, /* lduha [rs1+%g0],d */
+{ "lduha",     0xc0900000, 0x01682000, "[1+2]A,d", 0 },
+{ "ldstub",     0xc0680000, 0x0190201f, "[1],d", 0 }, /* ldstub [rs1+%g0],d */
+{ "ldstub",    0xc0682000, 0x01900000, "[1+i],d", 0 },
+{ "ldstub",    0xc0682000, 0x01900000, "[i+1],d", 0 },
+{ "ldstub",    0xc0680000, 0x01902000, "[1+2],d", 0 },
+{ "lda",        0xc0800000, 0x0178201f, "[1]A,d", 0 }, /* lda [rs1+%g0],d */
+{ "lda",       0xc0800000, 0x01782000, "[1+2]A,d", 0 },
+{ "ldsh",       0xc0500000, 0x0000000d, "[1],d", 0 }, /* ldsh [rs1+%g0],d */
+{ "ldsh",       0xc0502000, 0x01a81fff, "[1],d", 0 }, /* ldsh [rs1+0],d */
+{ "ldsh",      0xc0502000, 0x01a80000, "[1+i],d", 0 },
+{ "ldsh",      0xc0502000, 0x01a80000, "[i+1],d", 0 },
+{ "ldsh",      0xc0500000, 0x01a82000, "[1+2],d", 0 },
+{ "ldsb",       0xc0480000, 0x01b0201f, "[1],d", 0 }, /* ldsb [rs1+%g0],d */
+{ "ldsb",      0xc0482000, 0x01b01fff, "[1],d", 0 }, /* ldsb [rs1+0],d */
+{ "ldsb",      0xc0482000, 0x01b00000, "[1+i],d", 0 },
+{ "ldsb",      0xc0482000, 0x01b00000, "[i+1],d", 0 },
+{ "ldsb",      0xc0480000, 0x01b02000, "[1+2],d", 0 },
+{ "ldub",       0xc0080000, 0x01f0201f, "[1],d", 0 }, /* ldub [rs1+%g0],d */
+{ "ldub",       0xc0082000, 0x01f01fff, "[1],d", 0 }, /* ldub [rs1+0],d */
+{ "ldub",      0xc0082000, 0x01f00000, "[1+i],d", 0 },
+{ "ldub",      0xc0082000, 0x01f00000, "[i+1],d", 0 },
+{ "ldub",      0xc0080000, 0x01f02000, "[1+2],d", 0 },
+{ "lduba",      0xc0880000, 0x0170201f, "[1]A,d", 0 }, /* lduba [rs1+%g0],d */
+{ "lduba",     0xc0880000, 0x01702000, "[1+2]A,d", 0 },
+{ "lduh",      0xc0102000, 0x01e80000, "[1+i],d", 0 },
+{ "lduh",      0xc0102000, 0x01e80000, "[i+1],d", 0 },
+{ "lduh",      0xc0100000, 0x01e8201f, "[1],d", 0 }, /* lduh [rs1+%g0],d */
+{ "lduh",      0xc0102000, 0x01e81fff, "[1],d", 0 }, /* lduh [rs1+0],d */
+{ "lduh",      0xc0100000, 0x01e82000, "[1+2],d", 0 },
+
+{ "st",                0xc0200000, 0x01d8201f, "d,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st",                0xc0202000, 0x01d81fff, "d,[1]", 0 }, /* st d,[rs1+0] */
+{ "st",                0xc0202000, 0x01d80000, "d,[1+i]", 0 },
+{ "st",                0xc0202000, 0x01d80000, "d,[i+1]", 0 },
+{ "st",                0xc0200000, 0x01d82000, "d,[1+2]", 0 },
+{ "st",                0xc1200000, 0x00d8201f, "g,[1]", 0 }, /* st d[rs1+%g0] */
+{ "st",                0xc1202000, 0x00d81fff, "g,[1]", 0 }, /* st d,[rs1+0] */
+{ "st",                0xc1202000, 0x00d80000, "g,[1+i]", 0 },
+{ "st",                0xc1202000, 0x00d80000, "g,[i+1]", 0 },
+{ "st",                0xc1200000, 0x00d82000, "g,[1+2]", 0 },
+{ "st",                0xc1280000, 0x00d0201f, "F,[1]", 0 }, /* st %fsr,[rs1+%g0] */
+{ "st",                0xc1282000, 0x00d01fff, "F,[1]", 0 }, /* st %fsr,[rs1+0] */
+{ "st",                0xc1282000, 0x00d00000, "F,[1+i]", 0 },
+{ "st",                0xc1282000, 0x00d00000, "F,[i+1]", 0 },
+{ "st",                0xc1280000, 0x00d02000, "F,[1+2]", 0 },
+{ "st",                0xc1a00000, 0x0058201f, "D,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st",                0xc1a02000, 0x00581fff, "D,[1]", 0 }, /* st d,[rs1+0] */
+{ "st",                0xc1a02000, 0x00580000, "D,[1+i]", 0 },
+{ "st",                0xc1a02000, 0x00580000, "D,[i+1]", 0 },
+{ "st",                0xc1a00000, 0x00582000, "D,[1+2]", 0 },
+{ "st",                0xc1a80000, 0x0050201f, "C,[1]", 0 }, /* st d,[rs1+%g0] */
+{ "st",                0xc1a82000, 0x00501fff, "C,[1]", 0 }, /* st d,[rs1+0] */
+{ "st",                0xc1a82000, 0x00500000, "C,[1+i]", 0 },
+{ "st",                0xc1a82000, 0x00500000, "C,[i+1]", 0 },
+{ "st",                0xc1a80000, 0x00502000, "C,[1+2]", 0 },
+{ "sta",        0xc0a00000, 0x0108201f, "d,[1]A", 0 }, /* sta d,[rs1+%g0] */
+{ "sta",       0xc0a00000, 0x01082000, "d,[1+2]A", 0 },
+
+{ "stb",        0xc0280000, 0x01d0201f, "d,[1]", 0 }, /* stb d,[rs1+%g0] */
+{ "stb",       0xc0282000, 0x01d01fff, "d,[1]", 0 }, /* stb d,[rs1+0] */
+{ "stb",       0xc0282000, 0x01d00000, "d,[1+i]", 0 },
+{ "stb",       0xc0282000, 0x01d00000, "d,[i+1]", 0 },
+{ "stb",       0xc0280000, 0x01d02000, "d,[1+2]", 0 },
+{ "stba",       0xc0a80000, 0x01002000, "d,[1+2]A", 0 },
+{ "stba",      0xc0a80000, 0x0100201f, "d,[1]A", 0 }, /* stba d,[rs1+%g0] */
+
+{ "std",        0xc0380000, 0x01c0201f, "d,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std",       0xc0382000, 0x01c01fff, "d,[1]", 0 }, /* std d,[rs1+0] */
+{ "std",       0xc0382000, 0x01c00000, "d,[1+i]", 0 },
+{ "std",       0xc0382000, 0x01c00000, "d,[i+1]", 0 },
+{ "std",       0xc0380000, 0x01c02000, "d,[1+2]", 0 },
+{ "std",       0xc1380000, 0x00c0201f, "g,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std",        0xc1382000, 0x00c01fff, "g,[1]", 0 }, /* std d,[rs1+0] */
+{ "std",       0xc1382000, 0x00c00000, "g,[1+i]", 0 },
+{ "std",       0xc1382000, 0x00c00000, "g,[i+1]", 0 },
+{ "std",       0xc1380000, 0x00c02000, "g,[1+2]", 0 },
+{ "std",        0xc1300000, 0x00c8201f, "q,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std",       0xc1302000, 0x00c81fff, "q,[1]", 0 }, /* std d,[rs1+0] */
+{ "std",       0xc1302000, 0x00c80000, "q,[1+i]", 0 },
+{ "std",       0xc1302000, 0x00c80000, "q,[i+1]", 0 },
+{ "std",       0xc1300000, 0x00c82000, "q,[1+2]", 0 },
+{ "std",       0xc1b80000, 0x0040201f, "D,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std",       0xc1b82000, 0x00401fff, "D,[1]", 0 }, /* std d,[rs1+0] */
+{ "std",       0xc1b82000, 0x00400000, "D,[1+i]", 0 },
+{ "std",       0xc1b82000, 0x00400000, "D,[i+1]", 0 },
+{ "std",       0xc1b80000, 0x00402000, "D,[1+2]", 0 },
+{ "std",       0xc1b00000, 0x0048201f, "Q,[1]", 0 }, /* std d,[rs1+%g0] */
+{ "std",       0xc1b02000, 0x00481fff, "Q,[1]", 0 }, /* std d,[rs1+0] */
+{ "std",       0xc1b02000, 0x00480000, "Q,[1+i]", 0 },
+{ "std",       0xc1b02000, 0x00480000, "Q,[i+1]", 0 },
+{ "std",       0xc1b00000, 0x00482000, "Q,[1+2]", 0 },
+{ "stda",       0xc0b80000, 0x01402000, "d,[1+2]A", 0 },
+{ "stda",      0xc0b80000, 0x0140201f, "d,[1]A", 0 }, /* stda d,[rs1+%g0] */
+
+{ "sth",        0xc0300000, 0x01c8201f, "d,[1]", 0 }, /* sth d,[rs1+%g0] */
+{ "sth",       0xc0302000, 0x01c81fff, "d,[1]", 0 }, /* sth d,[rs1+0] */
+{ "sth",       0xc0300000, 0x01c82000, "d,[1+2]", 0 },
+{ "sth",       0xc0302000, 0x01c80000, "d,[1+i]", 0 },
+{ "sth",       0xc0302000, 0x01c80000, "d,[i+1]", 0 },
+{ "stha",       0xc0b00000, 0x0148201f, "d,[1]A", 0 }, /* stha d,[rs1+%g0] */
+{ "stha",      0xc0b00000, 0x01482000, "d,[1+2]A", 0 },
+
+{ "swap",       0xc0780000, 0x0180201f, "[1],d", 0 }, /* swap [rs1+%g0],d */
+{ "swap",       0xc0782000, 0x01801fff, "[1],d", 0 }, /* swap [rs1+0],d */
+{ "swap",       0xc0782000, 0x01800000, "[1+i],d", 0 },
+{ "swap",       0xc0782000, 0x01800000, "[i+1],d", 0 },
+{ "swap",       0xc0780000, 0x01802000, "[1+2],d", 0 },
+{ "swapa",      0xc0f80000, 0x01002000, "[1+2]A,d", 0 },
+{ "swapa",      0xc0f80000, 0x0100201f, "[1]A,d", 0 }, /* swapa [rs1+%g0],d */
+
+{ "restore",    0x81e80000, 0x7e17e01f, "", 0 }, /* restore %g0,%g0,%g0 */
+{ "restore",    0x81e82000, 0x7e14dfff, "", 0 }, /* restore %g0,0,%g0 */
+{ "restore",   0x81e82000, 0x00000000, "1,i,d", 0 },
+{ "restore",   0x81e80000, 0x00000000, "1,2,d", 0 },
+{ "rett",       0x81c82000, 0x40300000, "1+i", F_DELAYED },
+{ "rett",       0x81c82000, 0x40300000, "i+1", F_DELAYED },
+{ "rett",      0x81c80000, 0x40302000, "1+2", F_DELAYED },
+{ "rett",      0x81c82000, 0x40301fff, "1", F_DELAYED}, /* rett X,0 */
+{ "rett",      0x81c80000, 0x4030201f, "1", F_DELAYED}, /* rett X,%g0 */
+{ "save",       0x81e02000, 0x40180000, "1,i,d", 0 },
+{ "save",      0x81e00000, 0x40180000, "1,2,d", 0 },
+
+{ "ret",       0x81c7e008, 0x00001ff7, "", F_DELAYED }, /* jmpl %i7+8,%g0 */
+{ "retl",       0x81c3e008, 0x00001ff7, "", F_DELAYED }, /* jmpl %o7+8,%g0 */
+
+{ "jmpl",       0x81c00000, 0x4038201f, "1,d", F_DELAYED }, /* jmpl rs1+%g0,d */
+{ "jmpl",      0x81c02000, 0x4037c000, "i,d", F_DELAYED }, /* jmpl %g0+i,d */
+{ "jmpl",      0x81c02000, 0x40380000, "1+i,d", F_DELAYED },
+{ "jmpl",      0x81c02000, 0x40380000, "i+1,d", F_DELAYED },
+{ "jmpl",      0x81c00000, 0x40382000, "1+2,d", F_DELAYED },
+{ "wr",         0x81982000, 0x40600000, "1,i,t", 0 },
+{ "wr",         0x81980000, 0x40600000, "1,2,t", 0 },
+{ "wr",         0x81902000, 0x40680000, "1,i,w", 0 },
+{ "wr",         0x81900000, 0x40680000, "1,2,w", 0 },
+{ "wr",         0x81882000, 0x40700000, "1,i,p", 0 },
+{ "wr",         0x81880000, 0x40700000, "1,2,p", 0 },
+{ "wr",         0x81802000, 0x40780000, "1,i,y", 0 },
+{ "wr",         0x81800000, 0x40780000, "1,2,y", 0 },
+
+{ "rd",        0x81580000, 0x40a00000, "t,d", 0 },
+{ "rd",        0x81500000, 0x40a80000, "w,d", 0 },
+{ "rd",        0x81480000, 0x40b00000, "p,d", 0 },
+{ "rd",         0x81400000, 0x40b80000, "y,d", 0 },
+
+{ "sra",       0x81382000, 0x00000000, "1,i,d", 0 },
+{ "sra",       0x81380000, 0x00000000, "1,2,d", 0 },
+{ "srl",        0x81302000, 0x40c80000, "1,i,d", 0 },
+{ "srl",       0x81300000, 0x40c80000, "1,2,d", 0 },
+{ "sll",        0x81282000, 0x40d00000, "1,i,d", 0 },
+{ "sll",       0x81280000, 0x40d00000, "1,2,d", 0 },
+
+{ "mulscc",     0x81202000, 0x40d80000, "1,i,d", 0 },
+{ "mulscc",    0x81200000, 0x40d80000, "1,2,d", 0 },
+
+{ "clr",        0x80100000, 0x4e87e01f, "d", F_ALIAS }, /* or %g0,%g0,d */
+{ "clr",        0x80102000, 0x41efdfff, "d", F_ALIAS }, /* or %g0,0,d   */
+{ "clr",       0xc0200000, 0x3fd8001f, "[1]", F_ALIAS }, /* st %g0,[rs1+%g0] */
+{ "clr",       0xc0202000, 0x3fd81fff, "[1]", F_ALIAS }, /* st %g0,[rs1+0] */
+{ "clr",       0xc0202000, 0x3fd80000, "[1+i]", F_ALIAS },
+{ "clr",       0xc0202000, 0x3fd80000, "[i+1]", F_ALIAS },
+{ "clr",       0xc0200000, 0x3fd80000, "[1+2]", F_ALIAS },
+
+{ "clrb",       0xc0280000, 0x3fd0001f, "[1]", F_ALIAS },/* stb %g0,[rs1+%g0] */
+{ "clrb",      0xc0282000, 0x3fd00000, "[1+i]", F_ALIAS },
+{ "clrb",      0xc0282000, 0x3fd00000, "[i+1]", F_ALIAS },
+{ "clrb",      0xc0280000, 0x3fd00000, "[1+2]", F_ALIAS },
+
+{ "clrh",       0xc0300000, 0x3fc8001f, "[1]", F_ALIAS },/* sth %g0,[rs1+%g0] */
+{ "clrh",      0xc0300000, 0x3fc80000, "[1+2]", F_ALIAS },
+{ "clrh",      0xc0302000, 0x3fc80000, "[1+i]", F_ALIAS },
+{ "clrh",      0xc0302000, 0x3fc80000, "[i+1]", F_ALIAS },
+
+{ "orncc",      0x80b02000, 0x04048000, "1,i,d", 0 },
+{ "orncc",     0x80b00000, 0x04048000, "1,2,d", 0 },
+
+{ "tst",        0x80900000, 0x7f6fe000, "2", 0 }, /* orcc %g0, rs2, %g0 */
+{ "tst",        0x80900000, 0x7f68201f, "1", 0 }, /* orcc rs1, %g0, %g0 */
+{ "tst",        0x80902000, 0x7f681fff, "1", 0 }, /* orcc rs1, 0, %g0 */
+  
+{ "orcc",       0x80902000, 0x41680000, "1,i,d", 0 },
+{ "orcc",      0x80902000, 0x41680000, "i,1,d", 0 },
+{ "orcc",      0x80900000, 0x41680000, "1,2,d", 0 },
+{ "orn",        0x80302000, 0x41c80000, "1,i,d", 0 },
+{ "orn",       0x80300000, 0x41c80000, "1,2,d", 0 },
+
+{ "mov",        0x81800000, 0x4078201f, "1,y", F_ALIAS }, /* wr rs1,%g0,%y */
+{ "mov",        0x81802000, 0x40781fff, "1,y", F_ALIAS }, /* wr rs1,0,%y */
+{ "mov",        0x81802000, 0x40780000, "i,y", F_ALIAS },
+{ "mov",        0x81400000, 0x40b80000, "y,d", F_ALIAS }, /* rd %y,d */
+{ "mov",        0x81980000, 0x4060201f, "1,t", F_ALIAS }, /* wr rs1,%g0,%tbr */
+{ "mov",        0x81982000, 0x40601fff, "1,t", F_ALIAS }, /* wr rs1,0,%tbr */
+{ "mov",        0x81982000, 0x40600000, "i,t", F_ALIAS },
+{ "mov",        0x81580000, 0x40a00000, "t,d", F_ALIAS }, /* rd %tbr,d */
+{ "mov",        0x81900000, 0x4068201f, "1,w", F_ALIAS }, /* wr rs1,%g0,%wim */
+{ "mov",        0x81902000, 0x40681fff, "1,w", F_ALIAS }, /* wr rs1,0,%wim */
+{ "mov",        0x81902000, 0x40680000, "i,w", F_ALIAS },
+{ "mov",        0x81500000, 0x40a80000, "w,d", F_ALIAS }, /* rd %wim,d */
+{ "mov",        0x81880000, 0x4070201f, "1,p", F_ALIAS }, /* wr rs1,%g0,%psr */
+{ "mov",        0x81882000, 0x40701fff, "1,p", F_ALIAS }, /* wr rs1,0,%psr */
+{ "mov",        0x81882000, 0x40700000, "i,p", F_ALIAS },
+{ "mov",        0x81480000, 0x40b00000, "p,d", F_ALIAS }, /* rd %psr,d */
+
+{ "mov",        0x80102000, 0x41efc000, "i,d", 0 }, /* or %g0,i,d   */
+{ "mov",        0x80100000, 0x41efe000, "2,d", 0 }, /* or %g0,rs2,d */
+{ "mov",        0x80102000, 0x41e81fff, "1,d", 0 }, /* or rs1,0,d */
+{ "mov",        0x80100000, 0x41e8201f, "1,d", 0 }, /* or rs1,%g0,d   */
+
+{ "or",                0x80102000, 0x40800000, "1,i,d", 0 },
+{ "or",                0x80102000, 0x40800000, "i,1,d", 0 },
+{ "or",                0x80100000, 0x40800000, "1,2,d", 0 },
+
+{ "bset",      0x80102000, 0x40800000, "i,r", F_ALIAS },/* or rd,i,rd */
+{ "bset",      0x80100000, 0x40800000, "2,r", F_ALIAS },/* or rd,rs2,rd */
+
+{ "andncc",     0x80a82000, 0x41500000, "1,i,d", 0 },
+{ "andncc",    0x80a80000, 0x41500000, "1,2,d", 0 },
+{ "andn",       0x80282000, 0x41d00000, "1,i,d", 0 },
+{ "andn",      0x80280000, 0x41d00000, "1,2,d", 0 },
+
+{ "bclr",      0x80282000, 0x41d00000, "i,r", F_ALIAS },/* andn rd,i,rd */
+{ "bclr",      0x80280000, 0x41d00000, "2,r", F_ALIAS },/* andn rd,rs2,rd */
+
+{ "cmp",        0x80a02000, 0x7d580000, "1,i", 0 },     /* subcc rs1,i,%g0 */
+{ "cmp",       0x80a00000, 0x7d580000, "1,2", 0 },     /* subcc rs1,rs2,%g0 */
+
+{ "subcc",      0x80a02000, 0x41580000, "1,i,d", 0 },
+{ "subcc",     0x80a00000, 0x41580000, "1,2,d", 0 },
+{ "sub",       0x80202000, 0x41d80000, "1,i,d", 0 },
+{ "sub",       0x80200000, 0x41d80000, "1,2,d", 0 },
+{ "subx",      0x80602000, 0x41980000, "1,i,d", 0 },
+{ "subx",      0x80600000, 0x41980000, "1,2,d", 0 },
+{ "subxcc",     0x80e02000, 0x41180000, "1,i,d", 0 },
+{ "subxcc",    0x80e00000, 0x41180000, "1,2,d", 0 },
+
+{ "andcc",      0x80882000, 0x41700000, "1,i,d", 0 },
+{ "andcc",     0x80882000, 0x41700000, "i,1,d", 0 },
+{ "andcc",     0x80880000, 0x41700000, "1,2,d", 0 },
+{ "and",        0x80082000, 0x41f00000, "1,i,d", 0 },
+{ "and",       0x80082000, 0x41f00000, "i,1,d", 0 },
+{ "and",       0x80080000, 0x41f00000, "1,2,d", 0 },
+
+{ "inc",       0x80002001, 0x41f81ffe, "r", F_ALIAS }, /* add rs1,1,rsd */
+{ "inccc",     0x80802001, 0x41781ffe, "r", F_ALIAS }, /* addcc rd,1,rd */
+{ "dec",        0x80202001, 0x41d81ffe, "r", F_ALIAS },        /* sub rd,1,rd */
+{ "deccc",     0x80a02001, 0x41581ffe, "r", F_ALIAS }, /* subcc rd,1,rd */
+
+{ "btst",      0x80882000, 0x41700000, "i,1", F_ALIAS },/* andcc rs1,i,%g0 */
+{ "btst",      0x80880000, 0x41700000, "1,2", F_ALIAS },/* andcc rs1,rs2,%0 */
+
+{ "neg",       0x80200000, 0x41d80000, "r", F_ALIAS }, /* sub %0,rd,rd */
+{ "neg",       0x80200000, 0x41d80000, "2,d", F_ALIAS }, /* sub %0,rs2,rd */
+
+{ "addxcc",     0x80c02000, 0x41380000, "1,i,d", 0 },
+{ "addxcc",     0x80c02000, 0x41380000, "i,1,d", 0 },
+{ "addxcc",     0x80c00000, 0x41380000, "1,2,d", 0 },
+{ "addcc",      0x80802000, 0x41780000, "1,i,d", 0 },
+{ "addcc",      0x80802000, 0x41780000, "i,1,d", 0 },
+{ "addcc",      0x80800000, 0x41780000, "1,2,d", 0 },
+{ "addx",       0x80402000, 0x41b80000, "1,i,d", 0 },
+{ "addx",      0x80402000, 0x41b80000, "i,1,d", 0 },
+{ "addx",      0x80400000, 0x41b80000, "1,2,d", 0 },
+{ "add",        0x80002000, 0x41f80000, "1,i,d", 0 },
+{ "add",       0x80002000, 0x41f80000, "i,1,d", 0 },
+{ "add",       0x80000000, 0x41f80000, "1,2,d", 0 },
+
+{ "call",       0x9fc00000, 0x4038201f, "1", F_DELAYED }, /* jmpl rs1+%g0, %o7 */
+{ "call",      0x9fc00000, 0x4038201f, "1,#", F_DELAYED },
+{ "call",      0x40000000, 0x80000000, "L", F_DELAYED },
+{ "call",      0x40000000, 0x80000000, "L,#", F_DELAYED },
+
+{ "jmp",        0x81c00000, 0x7e38201f, "1", F_DELAYED }, /* jmpl rs1+%g0,%g0 */
+{ "jmp",        0x81c02000, 0x7e3fc000, "i", F_DELAYED }, /* jmpl %g0+i,%g0 */
+{ "jmp",        0x81c00000, 0x7e382000, "1+2", F_DELAYED }, /* jmpl rs1+rs2,%g0 */
+{ "jmp",        0x81c02000, 0x7e380000, "1+i", F_DELAYED }, /* jmpl rs1+i,%g0 */
+{ "jmp",        0x81c02000, 0x7e380000, "i+1", F_DELAYED }, /* jmpl i+rs1,%g0 */
+
+{ "nop",       0x01000000, 0xfeffffff, "", 0 }, /* sethi 0, %g0 */
+
+{ "set",        0x01000000, 0xc0c00000, "Sh,d", F_ALIAS },
+
+{ "sethi",      0x01000000, 0xc0c00000, "h,d", 0 },
+
+{ "taddcctv",   0x81102000, 0x40e00000, "1,i,d", 0 },
+{ "taddcctv",   0x81100000, 0x40e00000, "1,2,d", 0 },
+{ "taddcc",     0x81002000, 0x40f80000, "1,i,d", 0 },
+{ "taddcc",     0x81000000, 0x40f80000, "1,2,d", 0 },
+
+/* Conditional instructions.
+
+   Because this part of the table was such a mess earlier, I have
+   macrofied it so that all the branches and traps are generated from
+   a single-line description of each condition value.  */
+
+#define ANNUL  0x20000000
+#define        IMMED  0x00002000
+#define        RS1_G0 0x0007C000
+#define        RS2_G0 0x0000001F
+
+/* Define two branches -- one annulled, one without */
+#define br(opcode, mask, lose, flags)  \
+ { opcode, mask+ANNUL, lose, ",al", flags },   \
+ { opcode, mask      , lose, "l",   flags }
+
+/* Define four traps: reg+reg, reg + immediate, immediate alone, reg alone. */
+#define tr(opcode, mask, lose, flags) \
+ {opcode, mask+IMMED, lose+RS1_G0      , "i", flags },  /* %g0 + imm */ \
+ {opcode, mask+IMMED, lose             , "1+i", flags }, /* rs1 + imm */ \
+ {opcode, mask      , lose+IMMED       , "1+2", flags }, /* rs1 + rs2 */ \
+ {opcode, mask      , lose+IMMED+RS2_G0, "1", flags }    /* rs1 + %g0 */
+
+/* Define both branches and traps based on condition mask */
+#ifdef __STDC__
+#define cond(bop, top, mask, flags)    \
+  br(#bop,  0x00800000+(mask << 25), 0xC1400000, F_DELAYED|flags), \
+  tr(#top,  0x81d00000+(mask << 25), 0x40280000, flags)
+#else
+#define cond(bop, top, mask, flags)    \
+  br("bop", 0x00800000+(mask << 25), 0xC1400000, F_DELAYED|flags), \
+  tr("top", 0x81d00000+(mask << 25), 0x40280000, flags)
+#endif
+
+/* Define all the conditions, all the branches, all the traps.  */
+cond (bvc,     tvc,  0xF, 0),
+cond (bvs,     tvs,  0x7, 0),
+cond (bpos,    tpos, 0xE, 0),
+cond (bneg,    tneg, 0x6, 0),
+cond (bcc,     tcc,  0xD, 0),
+cond (bcs,     tcs,  0x5, 0),
+cond (blu,     tlu,  0x5, F_ALIAS),    /* for cs */
+cond (bgeu,    tgeu, 0xD, F_ALIAS),    /* for cc */
+cond (bgu,     tgu,  0xC, 0),
+cond (bleu,    tleu, 0x4, 0),
+cond (bge,     tge,  0xB, 0),
+cond (bl,      tl,   0x3, 0),
+cond (bg,      tg,   0xA, 0),
+cond (ble,     tle,  0x2, 0),
+cond (be,      te,   0x1, 0),
+cond (bz,      tz,   0x1, F_ALIAS),    /* for e */
+cond (bne,     tne,  0x9, 0),
+cond (bnz,     tnz,  0x9, F_ALIAS),    /* for ne */
+cond (b,       t,    0x8, 0),
+cond (ba,      ta,   0x8, F_ALIAS),    /* for nothing */
+cond (bn,      tn,   0x0, 0),
+
+#undef cond
+#undef br
+#undef tr
+
+{ "tsubcc",     0x81080000, 0x40f00000, "1,2,d", 0 },
+{ "tsubcc",     0x81082000, 0x40f00000, "1,i,d", 0 },
+{ "tsubcctv",   0x80580000, 0x40a00000, "1,2,d", 0 },
+{ "tsubcctv",   0x80582000, 0x40a00000, "1,i,d", 0 },
+
+{ "unimp",      0x00000000, 0xFFFFFFFF, "l", 0 },
+
+{ "iflush",     0x81d80000, 0x40202000, "1+2", 0 },
+{ "iflush",     0x81d82000, 0x40200000, "1+i", 0 },
+
+{ "xnorcc",     0x80b80000, 0x41400000, "1,2,d", 0 },
+{ "xnorcc",    0x80b82000, 0x41400000, "1,i,d", 0 },
+{ "xnorcc",    0x80b82000, 0x41400000, "i,1,d", 0 },
+{ "xorcc",      0x80980000, 0x41600000, "1,2,d", 0 },
+{ "xorcc",     0x80982000, 0x41600000, "1,i,d", 0 },
+{ "xorcc",     0x80982000, 0x41600000, "i,1,d", 0 },
+{ "xnor",       0x80380000, 0x41c00000, "1,2,d", 0 },
+{ "xnor",      0x80382000, 0x41c00000, "1,i,d", 0 },
+{ "xnor",      0x80382000, 0x41c00000, "i,1,d", 0 },
+{ "xor",        0x80180000, 0x41e00000, "1,2,d", 0 },
+{ "xor",       0x80182000, 0x41e00000, "1,i,d", 0 },
+{ "xor",       0x80182000, 0x41e00000, "i,1,d", 0 },
+
+{ "not",        0x80380000, 0x41c00000, "r", F_ALIAS }, /* xnor rd,%0,rd */
+{ "not",        0x80380000, 0x41c00000, "1,d", F_ALIAS }, /* xnor rs1,%0,rd */
+
+{ "btog",      0x80180000, 0x41e02000, "2,r", F_ALIAS }, /* xor rd,rs2,rd */
+{ "btog",      0x80182000, 0x41e00000, "i,r", F_ALIAS }, /* xor rd,i,rd */
+
+{ "fpop1",      0x81a00000, 0x40580000, "[1+2],d", 0 },
+{ "fpop2",      0x81a80000, 0x40500000, "[1+2],d", 0 },
+
+/* Someday somebody should give these the same treatment as the branches
+   above.  FIXME someday.  */
+
+{ "fb",         0x31800000, 0xc0400000, ",al", F_DELAYED },
+{ "fb",         0x11800000, 0xc0400000, "l", F_DELAYED },
+{ "fba",        0x31800000, 0xc0400000, ",al", F_DELAYED|F_ALIAS },
+{ "fba",        0x11800000, 0xc0400000, "l", F_DELAYED|F_ALIAS },
+{ "fbn",        0x21800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbn",        0x01800000, 0xc0400000, "l", F_DELAYED },
+{ "fbu",        0x2f800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbu",        0x0f800000, 0xc0400000, "l", F_DELAYED },
+{ "fbg",        0x2d800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbg",        0x0d800000, 0xc0400000, "l", F_DELAYED },
+{ "fbug",       0x2b800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbug",       0x0b800000, 0xc0400000, "l", F_DELAYED },
+{ "fbl",        0x29800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbl",        0x09800000, 0xc0400000, "l", F_DELAYED },
+{ "fbul",       0x27800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbul",       0x07800000, 0xc0400000, "l", F_DELAYED },
+{ "fblg",       0x25800000, 0xc0400000, ",al", F_DELAYED },
+{ "fblg",       0x05800000, 0xc0400000, "l", F_DELAYED },
+{ "fbne",       0x23800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbne",       0x03800000, 0xc0400000, "l", F_DELAYED },
+{ "fbe",        0x33800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbe",        0x13800000, 0xc0400000, "l", F_DELAYED },
+{ "fbue",       0x35800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbue",       0x15800000, 0xc0400000, "l", F_DELAYED },
+{ "fbge",       0x37800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbge",       0x17800000, 0xc0400000, "l", F_DELAYED },
+{ "fbuge",      0x39800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbuge",      0x19800000, 0xc0400000, "l", F_DELAYED },
+{ "fble",       0x3b800000, 0xc0400000, ",al", F_DELAYED },
+{ "fble",       0x1b800000, 0xc0400000, "l", F_DELAYED },
+{ "fbule",      0x3d800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbule",      0x1d800000, 0xc0400000, "l", F_DELAYED },
+{ "fbo",        0x3f800000, 0xc0400000, ",al", F_DELAYED },
+{ "fbo",        0x1f800000, 0xc0400000, "l", F_DELAYED },
+
+{ "cba",        0x31c00000, 0xce000000, ",al", F_DELAYED },
+{ "cba",        0x11c00000, 0xce000000, "l", F_DELAYED },
+{ "cbn",        0x21c00000, 0xde000000, ",al", F_DELAYED },
+{ "cbn",        0x01c00000, 0xde000000, "l", F_DELAYED },
+{ "cb3",        0x2fc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb3",        0x0fc00000, 0xc0000000, "l", F_DELAYED },
+{ "cb2",        0x2dc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb2",        0x0dc00000, 0xc0000000, "l", F_DELAYED },
+{ "cb23",       0x2bc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb23",       0x0bc00000, 0xc0000000, "l", F_DELAYED },
+{ "cb1",        0x29c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb1",        0x09c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb13",       0x27c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb13",       0x07c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb12",       0x25c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb12",       0x05c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb123",      0x23c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb123",      0x03c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb0",        0x33c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb0",        0x13c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb03",       0x35c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb03",       0x15c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb02",       0x37c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb02",       0x17c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb023",      0x39c00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb023",      0x19c00000, 0xc0000000, "l", F_DELAYED },
+{ "cb01",       0x3bc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb01",       0x1bc00000, 0xc0000000, "l", F_DELAYED },
+{ "cb013",      0x3dc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb013",      0x1dc00000, 0xc0000000, "l", F_DELAYED },
+{ "cb012",      0x3fc00000, 0xc0000000, ",al", F_DELAYED },
+{ "cb012",      0x1fc00000, 0xc0000000, "l", F_DELAYED },
+
+{ "fstoi",      0x81a01a20, 0x400025c0, "f,g", 0 },
+{ "fdtoi",      0x81a01a40, 0x400025a0, "f,g", 0 },
+{ "fxtoi",      0x81a01a60, 0x40002580, "f,g", 0 },
+
+{ "fitox",      0x81a01980, 0x40002660, "f,g", 0 },
+{ "fitod",      0x81a01900, 0x400026e0, "f,g", 0 },
+{ "fitos",      0x81a01880, 0x40002660, "f,g", 0 },
+
+{ "fstod",      0x81a01920, 0x400026c0, "f,g", 0 },
+{ "fstox",      0x81a019a0, 0x40002640, "f,g", 0 },
+{ "fdtos",      0x81a018c0, 0x40002720, "f,g", 0 },
+{ "fdtox",      0x81a019c0, 0x40002620, "f,g", 0 },
+{ "fxtos",      0x81a018e0, 0x40002700, "f,g", 0 },
+{ "fxtod",      0x81a01960, 0x40002680, "f,g", 0 },
+
+{ "fdivx",      0x81a009e0, 0x40083600, "e,f,g", 0 },
+{ "fdivd",      0x81a009c0, 0x40003620, "e,f,g", 0 },
+{ "fdivs",      0x81a009a0, 0x40003640, "e,f,g", 0 },
+
+{ "fmuls",      0x81a00920, 0x400036c0, "e,f,g", 0 },
+{ "fmuld",      0x81a00940, 0x400036a0, "e,f,g", 0 },
+{ "fmulx",      0x81a00960, 0x40003680, "e,f,g", 0 },
+
+{ "fsqrts",     0x81a00520, 0x40003ac0, "f,g", 0 },
+{ "fsqrtd",     0x81a00540, 0x40003aa8, "f,g", 0 },
+{ "fsqrtx",     0x81a00560, 0x40003a80, "f,g", 0 },
+
+{ "fabss",      0x81a00120, 0x40003ec0, "f,g", 0 },
+{ "fnegs",      0x81a000a0, 0x40003f40, "f,g", 0 },
+{ "fmovs",      0x81a00020, 0x40003fc0, "f,g", 0 },
+
+{ "fsubx",      0x81a008e0, 0x40003700, "e,f,g", 0 },
+{ "fsubd",      0x81a008c0, 0x40003720, "e,f,g", 0 },
+{ "fsubs",      0x81a008a0, 0x40003740, "e,f,g", 0 },
+
+{ "faddx",      0x81a00860, 0x40003780, "e,f,g", 0 },
+{ "faddd",      0x81a00840, 0x400037a0, "e,f,g", 0 },
+{ "fadds",      0x81a00820, 0x400037c0, "e,f,g", 0 },
+
+{ "fcmpex",     0x81a80ae0, 0x40003500, "e,f", 0 },
+{ "fcmped",     0x81a80ac0, 0x40003520, "e,f", 0 },
+{ "fcmpes",     0x81a80aa0, 0x40003540, "e,f", 0 },
+{ "fcmpx",      0x81a80a60, 0x40003580, "e,f", 0 },
+{ "fcmpd",      0x81a80a40, 0x400035a0, "e,f", 0 },
+{ "fcmps",      0x81a80a20, 0x400035c0, "e,f", 0 },
+
+{ "cpop1",      0x81b00000, 0x40480000, "[1+2],d", 0 },
+{ "cpop2",      0x81b80000, 0x40400000, "[1+2],d", 0 },
+};
+
+#define NUMOPCODES ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]))
+
diff --git a/gdb/sparc-pinsn.c b/gdb/sparc-pinsn.c
new file mode 100644 (file)
index 0000000..39d62af
--- /dev/null
@@ -0,0 +1,465 @@
+/* Disassembler for the sparc.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB, the GNU disassembler.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "sparc-opcode.h"
+#include "gdbcore.h"
+#include "string.h"
+#include "target.h"
+
+extern void qsort ();
+
+
+extern char *reg_names[];
+#define        freg_names      (&reg_names[4 * 8])
+
+union sparc_insn
+  {
+    unsigned long int code;
+    struct
+      {
+       unsigned int OP:2;
+#define        op      ldst.OP
+       unsigned int RD:5;
+#define        rd      ldst.RD
+       unsigned int op3:6;
+       unsigned int RS1:5;
+#define        rs1     ldst.RS1
+       unsigned int i:1;
+       unsigned int ASI:8;
+#define        asi     ldst.ASI
+       unsigned int RS2:5;
+#define        rs2     ldst.RS2
+#define        shcnt   rs2
+      } ldst;
+    struct
+      {
+       unsigned int OP:2, RD:5, op3:6, RS1:5, i:1;
+       unsigned int IMM13:13;
+#define        imm13   IMM13.IMM13
+      } IMM13;
+    struct
+      {
+       unsigned int OP:2;
+       unsigned int a:1;
+       unsigned int cond:4;
+       unsigned int op2:3;
+       unsigned int DISP22:22;
+#define        disp22  branch.DISP22
+      } branch;
+#define        imm22   disp22
+    struct
+      {
+       unsigned int OP:2;
+       unsigned int DISP30:30;
+#define        disp30  call.DISP30
+      } call;
+  };
+
+/* Nonzero if INSN is the opcode for a delayed branch.  */
+static int
+is_delayed_branch (insn)
+     union sparc_insn insn;
+{
+  unsigned int i;
+
+  for (i = 0; i < NUMOPCODES; ++i)
+    {
+      const struct sparc_opcode *opcode = &sparc_opcodes[i];
+      if ((opcode->match & insn.code) == opcode->match
+         && (opcode->lose & insn.code) == 0)
+       return (opcode->flags & F_DELAYED);
+    }
+  return 0;
+}
+
+static int opcodes_sorted = 0;
+
+/* Print one instruction from MEMADDR on STREAM.  */
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  union sparc_insn insn;
+
+  register unsigned int i;
+
+  if (!opcodes_sorted)
+    {
+      static int compare_opcodes ();
+      qsort ((char *) sparc_opcodes, NUMOPCODES,
+            sizeof (sparc_opcodes[0]), compare_opcodes);
+      opcodes_sorted = 1;
+    }
+
+  read_memory (memaddr, &insn, sizeof (insn));
+
+  for (i = 0; i < NUMOPCODES; ++i)
+    {
+      const struct sparc_opcode *opcode = &sparc_opcodes[i];
+      if ((opcode->match & insn.code) == opcode->match
+         && (opcode->lose & insn.code) == 0)
+       {
+         /* Nonzero means that we have found an instruction which has
+            the effect of adding or or'ing the imm13 field to rs1.  */
+         int imm_added_to_rs1 = 0;
+
+         /* Nonzero means that we have found a plus sign in the args
+            field of the opcode table.  */
+         int found_plus = 0;
+         
+         /* Do we have an 'or' instruction where rs1 is the same
+            as rsd, and which has the i bit set?  */
+         if (opcode->match == 0x80102000
+             && insn.rs1 == insn.rd)
+           imm_added_to_rs1 = 1;
+
+         if (insn.rs1 != insn.rd
+             && strchr (opcode->args, 'r') != 0)
+             /* Can't do simple format if source and dest are different.  */
+             continue;
+
+         fputs_filtered (opcode->name, stream);
+
+         {
+           register const char *s;
+
+           if (opcode->args[0] != ',')
+             fputs_filtered (" ", stream);
+           for (s = opcode->args; *s != '\0'; ++s)
+             {
+               if (*s == ',')
+                 {
+                   fputs_filtered (",", stream);
+                   ++s;
+                   if (*s == 'a')
+                     {
+                       fputs_filtered ("a", stream);
+                       ++s;
+                     }
+                   fputs_filtered (" ", stream);
+                 }
+
+               switch (*s)
+                 {
+                 case '+':
+                   found_plus = 1;
+
+                   /* note fall-through */
+                 default:
+                   fprintf_filtered (stream, "%c", *s);
+                   break;
+
+                 case '#':
+                   fputs_filtered ("0", stream);
+                   break;
+
+#define        reg(n)  fprintf_filtered (stream, "%%%s", reg_names[n])
+                 case '1':
+                 case 'r':
+                   reg (insn.rs1);
+                   break;
+
+                 case '2':
+                   reg (insn.rs2);
+                   break;
+
+                 case 'd':
+                   reg (insn.rd);
+                   break;
+#undef reg
+
+#define        freg(n) fprintf_filtered (stream, "%%%s", freg_names[n])
+                 case 'e':
+                   freg (insn.rs1);
+                   break;
+
+                 case 'f':
+                   freg (insn.rs2);
+                   break;
+
+                 case 'g':
+                   freg (insn.rd);
+                   break;
+#undef freg
+
+#define        creg(n) fprintf_filtered (stream, "%%c%u", (unsigned int) (n))
+                 case 'b':
+                   creg (insn.rs1);
+                   break;
+
+                 case 'c':
+                   creg (insn.rs2);
+                   break;
+
+                 case 'D':
+                   creg (insn.rd);
+                   break;
+#undef creg
+
+                 case 'h':
+                   fprintf_filtered (stream, "%%hi(%#x)",
+                                     (int) insn.imm22 << 10);
+                   break;
+
+                 case 'i':
+                   {
+                     /* We cannot trust the compiler to sign-extend
+                        when extracting the bitfield, hence the shifts.  */
+                     int imm = ((int) insn.imm13 << 19) >> 19;
+
+                     /* Check to see whether we have a 1+i, and take
+                        note of that fact.
+
+                        Note: because of the way we sort the table,
+                        we will be matching 1+i rather than i+1,
+                        so it is OK to assume that i is after +,
+                        not before it.  */
+                     if (found_plus)
+                       imm_added_to_rs1 = 1;
+                     
+                     if (imm <= 9)
+                       fprintf_filtered (stream, "%d", imm);
+                     else
+                       fprintf_filtered (stream, "%#x", imm);
+                   }
+                   break;
+
+                 case 'L':
+                   print_address ((CORE_ADDR) memaddr + insn.disp30 * 4,
+                                  stream);
+                   break;
+
+                 case 'l':
+                   if ((insn.code >> 22) == 0)
+                     /* Special case for `unimp'.  Don't try to turn
+                        it's operand into a function offset.  */
+                     fprintf_filtered (stream, "%#x",
+                                       (int) (((int) insn.disp22 << 10) >> 10));
+                   else
+                     /* We cannot trust the compiler to sign-extend
+                        when extracting the bitfield, hence the shifts.  */
+                     print_address ((CORE_ADDR)
+                                    (memaddr
+                                     + (((int) insn.disp22 << 10) >> 10) * 4),
+                                    stream);
+                   break;
+
+                 case 'A':
+                   fprintf_filtered (stream, "(%d)", (int) insn.asi);
+                   break;
+
+                 case 'C':
+                   fputs_filtered ("%csr", stream);
+                   break;
+
+                 case 'F':
+                   fputs_filtered ("%fsr", stream);
+                   break;
+
+                 case 'p':
+                   fputs_filtered ("%psr", stream);
+                   break;
+
+                 case 'q':
+                   fputs_filtered ("%fq", stream);
+                   break;
+
+                 case 'Q':
+                   fputs_filtered ("%cq", stream);
+                   break;
+
+                 case 't':
+                   fputs_filtered ("%tbr", stream);
+                   break;
+
+                 case 'w':
+                   fputs_filtered ("%wim", stream);
+                   break;
+
+                 case 'y':
+                   fputs_filtered ("%y", stream);
+                   break;
+                 }
+             }
+         }
+
+         /* If we are adding or or'ing something to rs1, then
+            check to see whether the previous instruction was
+            a sethi to the same register as in the sethi.
+            If so, attempt to print the result of the add or
+            or (in this context add and or do the same thing)
+            and its symbolic value.  */
+         if (imm_added_to_rs1)
+           {
+             union sparc_insn prev_insn;
+             int errcode;
+
+             errcode = target_read_memory (memaddr - 4,
+                                    (char *)&prev_insn, sizeof (prev_insn));
+
+             if (errcode == 0)
+               {
+                 /* If it is a delayed branch, we need to look at the
+                    instruction before the delayed branch.  This handles
+                    sequences such as
+
+                    sethi %o1, %hi(_foo), %o1
+                    call _printf
+                    or %o1, %lo(_foo), %o1
+                    */
+
+                 if (is_delayed_branch (prev_insn))
+                   errcode = target_read_memory
+                     (memaddr - 8, (char *)&prev_insn, sizeof (prev_insn));
+               }
+
+             /* If there was a problem reading memory, then assume
+                the previous instruction was not sethi.  */
+             if (errcode == 0)
+               {
+                 /* Is it sethi to the same register?  */
+                 if ((prev_insn.code & 0xc1c00000) == 0x01000000
+                     && prev_insn.rd == insn.rs1)
+                   {
+                     fprintf_filtered (stream, "\t! ");
+                     /* We cannot trust the compiler to sign-extend
+                        when extracting the bitfield, hence the shifts.  */
+                     print_address (((int) prev_insn.imm22 << 10)
+                                    | (insn.imm13 << 19) >> 19, stream);
+                   }
+               }
+           }
+
+         return sizeof (insn);
+       }
+    }
+
+  printf_filtered ("%#8x", insn.code);
+  return sizeof (insn);
+}
+
+
+/* Compare opcodes A and B.  */
+
+static int
+compare_opcodes (a, b)
+     char *a, *b;
+{
+  struct sparc_opcode *op0 = (struct sparc_opcode *) a;
+  struct sparc_opcode *op1 = (struct sparc_opcode *) b;
+  unsigned long int match0 = op0->match, match1 = op1->match;
+  unsigned long int lose0 = op0->lose, lose1 = op1->lose;
+  register unsigned int i;
+
+  /* If a bit is set in both match and lose, there is something
+     wrong with the opcode table.  */
+  if (match0 & lose0)
+    {
+      fprintf (stderr, "Internal error:  bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
+              op0->name, match0, lose0);
+      op0->lose &= ~op0->match;
+      lose0 = op0->lose;
+    }
+
+  if (match1 & lose1)
+    {
+      fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
+              op1->name, match1, lose1);
+      op1->lose &= ~op1->match;
+      lose1 = op1->lose;
+    }
+
+  /* Because the bits that are variable in one opcode are constant in
+     another, it is important to order the opcodes in the right order.  */
+  for (i = 0; i < 32; ++i)
+    {
+      unsigned long int x = 1 << i;
+      int x0 = (match0 & x) != 0;
+      int x1 = (match1 & x) != 0;
+
+      if (x0 != x1)
+       return x1 - x0;
+    }
+
+  for (i = 0; i < 32; ++i)
+    {
+      unsigned long int x = 1 << i;
+      int x0 = (lose0 & x) != 0;
+      int x1 = (lose1 & x) != 0;
+
+      if (x0 != x1)
+       return x1 - x0;
+    }
+
+  /* They are functionally equal.  So as long as the opcode table is
+     valid, we can put whichever one first we want, on aesthetic grounds.  */
+
+  /* Our first aesthetic ground is that aliases defer to real insns.  */
+  {
+    int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
+    if (alias_diff != 0)
+      /* Put the one that isn't an alias first.  */
+      return alias_diff;
+  }
+
+  /* Except for the above aliases, two "identical" instructions had
+     better have the same opcode.  This is a sanity check on the table.  */
+  if (0 != strcmp (op0->name, op1->name))
+      fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
+       op0->name, op1->name);
+
+  /* Fewer arguments are preferred.  */
+  {
+    int length_diff = strlen (op0->args) - strlen (op1->args);
+    if (length_diff != 0)
+      /* Put the one with fewer arguments first.  */
+      return length_diff;
+  }
+
+  /* Put 1+i before i+1.  */
+  {
+    char *p0 = (char *) strchr(op0->args, '+');
+    char *p1 = (char *) strchr(op1->args, '+');
+
+    if (p0 && p1)
+      {
+       /* There is a plus in both operands.  Note that a plus
+          sign cannot be the first character in args,
+          so the following [-1]'s are valid.  */
+       if (p0[-1] == 'i' && p1[1] == 'i')
+         /* op0 is i+1 and op1 is 1+i, so op1 goes first.  */
+         return 1;
+       if (p0[1] == 'i' && p1[-1] == 'i')
+         /* op0 is 1+i and op1 is i+1, so op0 goes first.  */
+         return -1;
+      }
+  }
+
+  /* They are, as far as we can tell, identical.
+     Since qsort may have rearranged the table partially, there is
+     no way to tell which one was first in the opcode table as
+     written, so just say there are equal.  */
+  return 0;
+}
diff --git a/gdb/sparc-xdep.c b/gdb/sparc-xdep.c
new file mode 100644 (file)
index 0000000..89fcb8d
--- /dev/null
@@ -0,0 +1,298 @@
+/* Machine-dependent code which would otherwise be in inflow.c and core.c,
+   for GDB, the GNU debugger, for SPARC host systems.
+
+   Copyright (C) 1986, 1987, 1989, 1990  Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "tm-sparc.h"
+#include "param-no-tm.h"
+#include "inferior.h"
+#include "target.h"
+
+#include <sys/param.h>
+#include <sys/file.h>          /* For L_SET */
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "gdbcore.h"
+#include <sys/core.h>
+
+extern char register_valid[];
+
+/* Fetch one or more registers from the inferior.  REGNO == -1 to get
+   them all.  We actually fetch more than requested, when convenient,
+   marking them as valid so we won't fetch them again.  */
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  int i;
+
+  /* We should never be called with deferred stores, because a prerequisite
+     for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
+  if (deferred_stores) abort();
+
+  DO_DEFERRED_STORES;
+
+  /* Global and Out regs are fetched directly, as well as the control
+     registers.  If we're getting one of the in or local regs,
+     and the stack pointer has not yet been fetched,
+     we have to do that first, since they're found in memory relative
+     to the stack pointer.  */
+  if (regno < O7_REGNUM  /* including -1 */
+      || regno >= Y_REGNUM
+      || (!register_valid[SP_REGNUM] && regno < I7_REGNUM))
+    {
+      if (0 != ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers))
+           perror("ptrace_getregs");
+      
+      registers[REGISTER_BYTE (0)] = 0;
+      bcopy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (1)], 15 * REGISTER_RAW_SIZE (G0_REGNUM));
+      *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
+      *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+      *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
+      *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
+
+      for (i = G0_REGNUM; i <= O7_REGNUM; i++)
+       register_valid[i] = 1;
+      register_valid[Y_REGNUM] = 1;
+      register_valid[PS_REGNUM] = 1;
+      register_valid[PC_REGNUM] = 1;
+      register_valid[NPC_REGNUM] = 1;
+      /* If we don't set these valid, read_register_bytes() rereads
+        all the regs every time it is called!  FIXME.  */
+      register_valid[WIM_REGNUM] = 1;  /* Not true yet, FIXME */
+      register_valid[TBR_REGNUM] = 1;  /* Not true yet, FIXME */
+      register_valid[FPS_REGNUM] = 1;  /* Not true yet, FIXME */
+      register_valid[CPS_REGNUM] = 1;  /* Not true yet, FIXME */
+    }
+
+  /* Floating point registers */
+  if (regno == -1 || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
+    {
+      if (0 != ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers))
+           perror("ptrace_getfpregs");
+      bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+            sizeof inferior_fp_registers.fpu_fr);
+      /* bcopy (&inferior_fp_registers.Fpu_fsr,
+            &registers[REGISTER_BYTE (FPS_REGNUM)],
+            sizeof (FPU_FSR_TYPE));  FIXME???  -- gnu@cyg */
+      for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++)
+       register_valid[i] = 1;
+      register_valid[FPS_REGNUM] = 1;
+    }
+
+  /* These regs are saved on the stack by the kernel.  Only read them
+     all (16 ptrace calls!) if we really need them.  */
+  if (regno == -1)
+    {
+      target_xfer_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
+                         &registers[REGISTER_BYTE (L0_REGNUM)],
+                         16*REGISTER_RAW_SIZE (L0_REGNUM), 0);
+      for (i = L0_REGNUM; i <= I7_REGNUM; i++)
+       register_valid[i] = 1;
+    }
+  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
+    {
+      CORE_ADDR sp = *(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)];
+      i = REGISTER_BYTE (regno);
+      if (register_valid[regno])
+       printf("register %d valid and read\n", regno);
+      target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
+                         &registers[i], REGISTER_RAW_SIZE (regno), 0);
+      register_valid[regno] = 1;
+    }
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+#define        INT_REGS        1
+#define        STACK_REGS      2
+#define        FP_REGS         4
+int deferred_stores = 0;       /* Cumulates stores we want to do eventually. */
+
+int
+store_inferior_registers (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
+
+  /* First decide which pieces of machine-state we need to modify.  
+     Default for regno == -1 case is all pieces.  */
+  if (regno >= 0)
+    if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32)
+      {
+       wanna_store = FP_REGS;
+      }
+    else 
+      {
+       if (regno == SP_REGNUM)
+         wanna_store = INT_REGS + STACK_REGS;
+       else if (regno < L0_REGNUM || regno > I7_REGNUM)
+         wanna_store = INT_REGS;
+       else
+         wanna_store = STACK_REGS;
+      }
+
+  /* See if we're forcing the stores to happen now, or deferring. */
+  if (regno == -2)
+    {
+      wanna_store = deferred_stores;
+      deferred_stores = 0;
+    }
+  else
+    {
+      if (wanna_store == STACK_REGS)
+       {
+         /* Fall through and just store one stack reg.  If we deferred
+            it, we'd have to store them all, or remember more info.  */
+       }
+      else
+       {
+         deferred_stores |= wanna_store;
+         return 0;
+       }
+    }
+
+  if (wanna_store & STACK_REGS)
+    {
+      CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
+
+      if (regno < 0 || regno == SP_REGNUM)
+       {
+         if (!register_valid[L0_REGNUM+5]) abort();
+         target_xfer_memory (sp, 
+                             &registers[REGISTER_BYTE (L0_REGNUM)],
+                             16*REGISTER_RAW_SIZE (L0_REGNUM), 1);
+       }
+      else
+       {
+         if (!register_valid[regno]) abort();
+         target_xfer_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM),
+                             &registers[REGISTER_BYTE (regno)],
+                             REGISTER_RAW_SIZE (regno), 1);
+       }
+       
+    }
+
+  if (wanna_store & INT_REGS)
+    {
+      if (!register_valid[G1_REGNUM]) abort();
+
+      bcopy (&registers[REGISTER_BYTE (G1_REGNUM)],
+            &inferior_registers.r_g1, 15 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+      inferior_registers.r_ps =
+       *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
+      inferior_registers.r_pc =
+       *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
+      inferior_registers.r_npc =
+       *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
+      inferior_registers.r_y =
+       *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
+
+      if (0 != ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers))
+       perror("ptrace_setregs");
+    }
+
+  if (wanna_store & FP_REGS)
+    {
+      if (!register_valid[FP0_REGNUM+9]) abort();
+      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
+            &inferior_fp_registers,
+            sizeof inferior_fp_registers.fpu_fr);
+
+/*      bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
+            &inferior_fp_registers.Fpu_fsr,
+            sizeof (FPU_FSR_TYPE));
+****/
+      if (0 !=
+        ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers))
+        perror("ptrace_setfpregs");
+    }
+    return 0;
+}
+\f
+void
+fetch_core_registers (core_reg_sect, core_reg_size, which)
+  char *core_reg_sect;
+  unsigned core_reg_size;
+  int which;
+{
+
+  if (which == 0) {
+
+    /* Integer registers */
+
+#define gregs ((struct regs *)core_reg_sect)
+    /* G0 *always* holds 0.  */
+    *(int *)&registers[REGISTER_BYTE (0)] = 0;
+
+    /* The globals and output registers.  */
+    bcopy (&gregs->r_g1, 
+          &registers[REGISTER_BYTE (G1_REGNUM)],
+          15 * REGISTER_RAW_SIZE (G1_REGNUM));
+    *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
+    *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
+    *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
+    *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y;
+
+    /* My best guess at where to get the locals and input
+       registers is exactly where they usually are, right above
+       the stack pointer.  If the core dump was caused by a bus error
+       from blowing away the stack pointer (as is possible) then this
+       won't work, but it's worth the try. */
+    {
+      int sp;
+
+      sp = *(int *)&registers[REGISTER_BYTE (SP_REGNUM)];
+      if (0 != target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)], 
+                         16 * REGISTER_RAW_SIZE (L0_REGNUM)))
+       {
+         /* fprintf so user can still use gdb */
+         fprintf (stderr,
+                  "Couldn't read input and local registers from core file\n");
+       }
+    }
+  } else if (which == 2) {
+
+    /* Floating point registers */
+
+#define fpuregs  ((struct fpu *) core_reg_sect)
+    if (core_reg_size >= sizeof (struct fpu))
+      {
+       bcopy (fpuregs->fpu_regs,
+              &registers[REGISTER_BYTE (FP0_REGNUM)],
+              sizeof (fpuregs->fpu_regs));
+       bcopy (&fpuregs->fpu_fsr,
+              &registers[REGISTER_BYTE (FPS_REGNUM)],
+              sizeof (FPU_FSR_TYPE));
+      }
+    else
+      fprintf (stderr, "Couldn't read float regs from core file\n");
+  }
+}
diff --git a/gdb/stab.def b/gdb/stab.def
new file mode 100755 (executable)
index 0000000..58364e1
--- /dev/null
@@ -0,0 +1,182 @@
+/* Table of DBX symbol codes for the GNU system.
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+/* Global variable.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C.  Value is its address.
+   Desc is supposedly starting line number, but GCC doesn't set it
+   and DBX seems not to miss it.  */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage.  Value is its address.  */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage.  Value is its address.  */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine.  Only the name is significant.
+   This is not used in C.  */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Register variable.  Value is number of register.  */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Structure or union element.  Value is offset in the structure.  */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Parameter variable.  Value is offset from argument pointer.
+   (On most machines the argument pointer is the same as the frame pointer.  */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* Automatic variable in the stack.  Value is offset from frame pointer.
+   Also used for type descriptions.  */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Alternate entry point.  Value is its address.  */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Name of main source file.
+   Value is starting text address of the compilation.  */
+__define_stab (N_SO, 0x64, "SO")
+
+/* Name of sub-source file.
+   Value is starting text address of the compilation.  */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Line number in text segment.  Desc is the line number;
+   value is corresponding address.  */
+__define_stab (N_SLINE, 0x44, "SLINE")
+/* Similar, for data segment.  */
+__define_stab (N_DSLINE, 0x66, "DSLINE")
+/* Similar, for bss segment.  */
+__define_stab (N_BSLINE, 0x68, "BSLINE")
+
+/* Beginning of an include file.  Only Sun uses this.
+   In an object file, only the name is significant.
+   The Sun linker puts data into some of the other fields.  */
+__define_stab (N_BINCL, 0x82, "BINCL")
+/* End of an include file.  No name.
+   These two act as brackets around the file's output.
+   In an object file, there is no significant data in this entry.
+   The Sun linker puts data into some of the fields.  */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+/* Place holder for deleted include file.
+   This appears only in output from the Sun linker.  */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Beginning of lexical block.
+   The desc is the nesting level in lexical blocks.
+   The value is the address of the start of the text for the block.
+   The variables declared inside the block *precede* the N_LBRAC symbol.  */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+/* End of a lexical block.  Desc matches the N_LBRAC's desc.
+   The value is the address of the end of the text for the block.  */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block.  Only the name is significant.  */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+/* Begin named common block.  Only the name is significant
+   (and it should match the N_BCOMM).  */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+/* End common (local name): value is address.
+   I'm not sure how this is used.  */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+/* Second symbol entry containing a length-value for the preceding entry.
+   The value is the length.  */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* Global symbol in Pascal.
+   Supposedly the value is its line number; I'm skeptical.  */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Modula-2 compilation unit.  Can someone say what info it contains?  */
+__define_stab (N_M2C, 0x42, "M2C")
+/* Modula-2 scope information.  Can someone say what info it contains?  */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* Sun's source-code browser stabs.  ?? Don't know what the fields are.
+   Supposedly the field is "path to associated .cb file".  */
+__define_stab (N_BROWS, 0x48, "BROWS")
+
+/* GNU C++ exception stabs.  */
+
+/* GNU C++ exception variable.  Name is variable name.  */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+
+/* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
+   this entry is immediately followed by a CAUGHT stab saying what exception
+   was caught.  Multiple CAUGHT stabs means that multiple exceptions
+   can be caught here.  If Desc is 0, it means all exceptions are caught
+   here.  */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+   or something like that.  FIXME.  I have assigned the values at random
+   since I don't have a Gould here.  Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS,  0xF4, "NBBSS")
+__define_stab (N_NBSTS,  0xF6, "NBSTS")
+__define_stab (N_NBLCS,  0xF8, "NBLCS")
+__define_stab (N_NSYMS,  0xFA, "NSYMS")
+\f
+/* The above information, in matrix format.
+
+                       STAB MATRIX
+       _________________________________________________
+       | 00 - 1F are not dbx stab symbols              |
+       | Entries with bits 01 set are external symbols |
+       | N_UNDEF   | N_ABS     | N_TEXT    | N_DATA    |
+       | N_BSS     | N_COMM    |           | N_FN      |
+       |_______________________________________________|
+       | 20 GSYM   | 22 FNAME  | 24 FUN    | 26 STSYM  |
+       | 28 LCSYM  | 2A MAIN   | 2C        | 2E        |
+       | 30 PC     | 32        | 34        | 36        |
+       | 38        | 3A        | 3C        | 3E        |
+       | 40 RSYM   | 42 M2C    | 44 SLINE  | 46        |
+       | 48 BROWS  | 4A        | 4C        | 4E        |
+       | 50 EHDECL | 52        | 54 CATCH  | 56        |
+       | 58        | 5A        | 5C        | 5E        |
+       | 60 SSYM   | 62        | 64 SO     | 66 DSLINE |
+       | 68 BSLINE | 6A        | 6C        | 6E        |
+       | 70        | 72        | 74        | 76        |
+       | 78        | 7A        | 7C        | 7E        |
+       | 80 LSYM   | 82 BINCL  | 84 SOL    | 86        |
+       | 88        | 8A        | 8C        | 8E        |
+       | 90        | 92        | 94        | 96        |
+       | 98        | 9A        | 9C        | 9E        |
+       | A0 PSYM   | A2 EINCL  | A4 ENTRY  | A6        |
+       | A8        | AA        | AC        | AE        |
+       | B0        | B2        | B4        | B6        |
+       | B8        | BA        | BC        | BE        |
+       | C0 LBRAC  | C2 EXCL   | C4 SCOPE  | C6        |
+       | C8        | CA        | CC        | CE        |
+       | D0        | D2        | D4        | D6        |
+       | D8        | DA        | DC        | DE        |
+       | E0 RBRAC  | E2 BCOMM  | E4 ECOMM  | E6        |
+       | E8 ECOML  | EA        | EC        | EE        |
+       | F0        | F2        | F4        | F6        |
+       | F8        | FA        | FC        | FE LENG   |
+       +-----------------------------------------------+
+
+*/
diff --git a/gdb/standalone.c b/gdb/standalone.c
new file mode 100644 (file)
index 0000000..fcb6e7e
--- /dev/null
@@ -0,0 +1,594 @@
+/* Interface to bare machine for GDB running as kernel debugger.
+   Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined (SIGTSTP) && defined (SIGIO)
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /* SIGTSTP and SIGIO defined (must be 4.2) */
+
+#include "defs.h"
+#include "param.h"
+#include "signals.h"
+#include "symtab.h"
+#include "frame.h"
+#include "inferior.h"
+#include "wait.h"
+
+\f
+/* Random system calls, mostly no-ops to prevent link problems  */
+
+ioctl (desc, code, arg)
+{}
+
+int (* signal ()) ()
+{}
+
+kill ()
+{}
+
+getpid ()
+{
+  return 0;
+}
+
+sigsetmask ()
+{}
+
+chdir ()
+{}
+
+char *
+getwd (buf)
+     char *buf;
+{
+  buf[0] = '/';
+  buf[1] = 0;
+  return buf;
+}
+
+/* Used to check for existence of .gdbinit.  Say no.  */
+
+access ()
+{
+  return -1;
+}
+
+exit ()
+{
+  error ("Fatal error; restarting.");
+}
+\f
+/* Reading "files".  The contents of some files are written into kdb's
+   data area before it is run.  These files are used to contain the
+   symbol table for kdb to load, and the source files (in case the
+   kdb user wants to print them).  The symbols are stored in a file
+   named "kdb-symbols" in a.out format (except that all the text and
+   data have been stripped to save room).
+
+   The files are stored in the following format:
+   int     number of bytes of data for this file, including these four.
+   char[]  name of the file, ending with a null.
+   padding to multiple of 4 boundary.
+   char[]  file contents.  The length can be deduced from what was
+           specified before.  There is no terminating null here.
+
+   If the int at the front is zero, it means there are no more files.
+
+   Opening a file in kdb returns a nonzero value to indicate success,
+   but the value does not matter.  Only one file can be open, and only
+   for reading.  All the primitives for input from the file know
+   which file is open and ignore what is specified for the descriptor
+   or for the stdio stream.
+
+   Input with fgetc can be done either on the file that is open
+   or on stdin (which reads from the terminal through tty_input ()  */
+
+/* Address of data for the files stored in format described above.  */
+char *files_start;
+
+/* The file stream currently open:  */
+
+char *sourcebeg;               /* beginning of contents */
+int sourcesize;                        /* size of contents */
+char *sourceptr;               /* current read pointer */
+int sourceleft;                        /* number of bytes to eof */
+
+/* "descriptor" for the file now open.
+   Incremented at each close.
+   If specified descriptor does not match this,
+   it means the program is trying to use a closed descriptor.
+   We report an error for that.  */
+
+int sourcedesc;
+
+open (filename, modes)
+     char *filename;
+     int modes;
+{
+  register char *next;
+
+  if (modes)
+    {
+      errno = EROFS;
+      return -1;
+    }
+
+  if (sourceptr)
+    {
+      errno = EMFILE;
+      return -1;
+    }
+
+  for (next - files_start; * (int *) next;
+       next += * (int *) next)
+    {
+      if (!strcmp (next + 4, filename))
+       {
+         sourcebeg = next + 4 + strlen (next + 4) + 1;
+         sourcebeg = (char *) (((int) sourcebeg + 3) & (-4));
+         sourceptr = sourcebeg;
+         sourcesize = next + * (int *) next - sourceptr;
+         sourceleft = sourcesize;
+         return sourcedesc;
+       }
+    }
+  return 0;
+}
+
+close (desc)
+     int desc;
+{
+  sourceptr = 0;
+  sourcedesc++;
+  /* Don't let sourcedesc get big enough to be confused with stdin.  */
+  if (sourcedesc == 100)
+    sourcedesc = 5;
+}
+
+FILE *
+fopen (filename, modes)
+     char *filename;
+     char *modes;
+{
+  return (FILE *) open (filename, *modes == 'w');
+}
+
+FILE *
+fdopen (desc)
+     int desc;
+{
+  return (FILE *) desc;
+}
+
+fclose (desc)
+     int desc;
+{
+  close (desc);
+}
+
+fstat (desc, statbuf)
+     struct stat *statbuf;
+{
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  statbuf->st_size = sourcesize;
+}
+
+myread (desc, destptr, size, filename)
+     int desc;
+     char *destptr;
+     int size;
+     char *filename;
+{
+  int len = min (sourceleft, size);
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  bcopy (sourceptr, destptr, len);
+  sourceleft -= len;
+  return len;
+}
+
+int
+fread (bufp, numelts, eltsize, stream)
+{
+  register int elts = min (numelts, sourceleft / eltsize);
+  register int len = elts * eltsize;
+
+  if (stream != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  bcopy (sourceptr, bufp, len);
+  sourceleft -= len;
+  return elts;
+}
+
+int
+fgetc (desc)
+     int desc;
+{
+
+  if (desc == (int) stdin)
+    return tty_input ();
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  if (sourceleft-- <= 0)
+    return EOF;
+  return *sourceptr++;
+}
+
+lseek (desc, pos)
+     int desc;
+     int pos;
+{
+
+  if (desc != sourcedesc)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  if (pos < 0 || pos > sourcesize)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  sourceptr = sourcebeg + pos;
+  sourceleft = sourcesize - pos;
+}
+\f
+/* Output in kdb can go only to the terminal, so the stream
+   specified may be ignored.  */
+
+printf (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+{
+  char buffer[1024];
+  sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  display_string (buffer);
+}
+
+fprintf (ign, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+{
+  char buffer[1024];
+  sprintf (buffer, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  display_string (buffer);
+}
+
+fwrite (buf, numelts, size, stream)
+     register char *buf;
+     int numelts, size;
+{
+  register int i = numelts * size;
+  while (i-- > 0)
+    fputc (*buf++, stream);
+}
+
+fputc (c, ign)
+{
+  char buf[2];
+  buf[0] = c;
+  buf[1] = 0;
+  display_string (buf);
+}
+
+/* sprintf refers to this, but loading this from the
+   library would cause fflush to be loaded from it too.
+   In fact there should be no need to call this (I hope).  */
+
+_flsbuf ()
+{
+  error ("_flsbuf was actually called.");
+}
+
+fflush (ign)
+{
+}
+\f
+/* Entries into core and inflow, needed only to make things link ok.  */
+
+exec_file_command ()
+{}
+
+core_file_command ()
+{}
+
+char *
+get_exec_file (err)
+     int err;
+{
+  /* Makes one printout look reasonable; value does not matter otherwise.  */
+  return "run";
+}
+
+have_core_file_p ()
+{
+  return 0;
+}
+
+kill_command ()
+{
+  inferior_pid = 0;
+}
+
+terminal_inferior ()
+{}
+
+terminal_ours ()
+{}
+
+terminal_init_inferior ()
+{}
+
+write_inferior_register ()
+{}
+
+read_inferior_register ()
+{}
+
+read_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  bcopy (memaddr, myaddr, len);
+}
+
+/* Always return 0 indicating success.  */
+
+write_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  bcopy (myaddr, memaddr, len);
+  return 0;
+}
+
+static REGISTER_TYPE saved_regs[NUM_REGS];
+
+REGISTER_TYPE
+read_register (regno)
+     int regno;
+{
+  if (regno < 0 || regno >= NUM_REGS)
+    error ("Register number %d out of range.", regno);
+  return saved_regs[regno];
+}
+
+void
+write_register (regno, value)
+     int regno;
+     REGISTER_TYPE value;
+{
+  if (regno < 0 || regno >= NUM_REGS)
+    error ("Register number %d out of range.", regno);
+  saved_regs[regno] = value;
+}
+\f
+/* System calls needed in relation to running the "inferior".  */
+
+vfork ()
+{
+  /* Just appear to "succeed".  Say the inferior's pid is 1.  */
+  return 1;
+}
+
+/* These are called by code that normally runs in the inferior
+   that has just been forked.  That code never runs, when standalone,
+   and these definitions are so it will link without errors.  */
+
+ptrace ()
+{}
+
+setpgrp ()
+{}
+
+execle ()
+{}
+
+_exit ()
+{}
+\f
+/* Malloc calls these.  */
+
+malloc_warning (str)
+     char *str;
+{
+  printf ("\n%s.\n\n", str);
+}
+
+char *next_free;
+char *memory_limit;
+
+char *
+sbrk (amount)
+     int amount;
+{
+  if (next_free + amount > memory_limit)
+    return (char *) -1;
+  next_free += amount;
+  return next_free - amount;
+}
+
+/* Various ways malloc might ask where end of memory is.  */
+
+char *
+ulimit ()
+{
+  return memory_limit;
+}
+
+int
+vlimit ()
+{
+  return memory_limit - next_free;
+}
+
+getrlimit (addr)
+     struct rlimit *addr;
+{
+  addr->rlim_cur = memory_limit - next_free;
+}
+\f
+/* Context switching to and from program being debugged.  */
+
+/* GDB calls here to run the user program.
+   The frame pointer for this function is saved in
+   gdb_stack by save_frame_pointer; then we restore
+   all of the user program's registers, including PC and PS.  */
+
+static int fault_code;
+static REGISTER_TYPE gdb_stack;
+
+resume ()
+{
+  REGISTER_TYPE restore[NUM_REGS];
+
+  PUSH_FRAME_PTR;
+  save_frame_pointer ();
+
+  bcopy (saved_regs, restore, sizeof restore);
+  POP_REGISTERS;
+  /* Control does not drop through here!  */
+}
+
+save_frame_pointer (val)
+     CORE_ADDR val;
+{
+  gdb_stack = val;
+}
+
+/* Fault handlers call here, running in the user program stack.
+   They must first push a fault code,
+   old PC, old PS, and any other info about the fault.
+   The exact format is machine-dependent and is known only
+   in the definition of PUSH_REGISTERS.  */
+
+fault ()
+{
+  /* Transfer all registers and fault code to the stack
+     in canonical order: registers in order of GDB register number,
+     followed by fault code.  */
+  PUSH_REGISTERS;
+
+  /* Transfer them to saved_regs and fault_code.  */
+  save_registers ();
+
+  restore_gdb ();
+  /* Control does not reach here */
+}
+
+restore_gdb ()
+{
+  CORE_ADDR new_fp = gdb_stack;
+  /* Switch to GDB's stack  */
+  POP_FRAME_PTR;
+  /* Return from the function `resume'.  */
+}
+
+/* Assuming register contents and fault code have been pushed on the stack as
+   arguments to this function, copy them into the standard place
+   for the program's registers while GDB is running.  */
+
+save_registers (firstreg)
+     int firstreg;
+{
+  bcopy (&firstreg, saved_regs, sizeof saved_regs);
+  fault_code = (&firstreg)[NUM_REGS];
+}
+
+/* Store into the structure such as `wait' would return
+   the information on why the program faulted,
+   converted into a machine-independent signal number.  */
+
+static int fault_table[] = FAULT_TABLE;
+
+int
+wait (w)
+     WAITTYPE *w;
+{
+  WSETSTOP (*w, fault_table[fault_code / FAULT_CODE_UNITS]);
+  return inferior_pid;
+}
+\f
+/* Allocate a big space in which files for kdb to read will be stored.
+   Whatever is left is where malloc can allocate storage.
+
+   Initialize it, so that there will be space in the executable file
+   for it.  Then the files can be put into kdb by writing them into
+   kdb's executable file.  */
+
+/* The default size is as much space as we expect to be available
+   for kdb to use!  */
+
+#ifndef HEAP_SIZE
+#define HEAP_SIZE 400000
+#endif
+
+char heap[HEAP_SIZE] = {0};
+
+#ifndef STACK_SIZE
+#define STACK_SIZE 100000
+#endif
+
+int kdb_stack_beg[STACK_SIZE / sizeof (int)];
+int kdb_stack_end;
+
+_initialize_standalone ()
+{
+  register char *next;
+
+  /* Find start of data on files.  */
+
+  files_start = heap;
+
+  /* Find the end of the data on files.  */
+
+  for (next - files_start; * (int *) next;
+       next += * (int *) next)
+    {}
+
+  /* That is where free storage starts for sbrk to give out.  */
+  next_free = next;
+
+  memory_limit = heap + sizeof heap;
+}
+
diff --git a/gdb/stddef.h b/gdb/stddef.h
new file mode 100755 (executable)
index 0000000..d95a815
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+/* Signed type of difference of two pointers.  */
+
+typedef long ptrdiff_t;
+
+/* Unsigned type of `sizeof' something.  */
+
+#ifndef _SIZE_T        /* in case <sys/types.h> has defined it. */
+#define _SIZE_T
+typedef unsigned long size_t;
+#endif /* _SIZE_T */
+
+/* A null pointer constant.  */
+
+#undef NULL            /* in case <stdio.h> has defined it. */
+#define NULL 0
+
+/* Offset of member MEMBER in a struct of type TYPE.  */
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif /* _STDDEF_H */
diff --git a/gdb/stdlib.h b/gdb/stdlib.h
new file mode 100755 (executable)
index 0000000..40ce167
--- /dev/null
@@ -0,0 +1,10 @@
+/* Fake stdlib.h supplying the stuff needed by malloc. */
+
+#ifndef __ONEFILE
+#include <stddef.h>
+#endif
+
+extern void EXFUN(abort, (void));
+extern void EXFUN(free, (PTR));
+extern PTR EXFUN(malloc, (size_t));
+extern PTR EXFUN(realloc, (PTR, size_t));
diff --git a/gdb/stuff.c b/gdb/stuff.c
new file mode 100644 (file)
index 0000000..2ffdc97
--- /dev/null
@@ -0,0 +1,174 @@
+/* Program to stuff files into a specially prepared space in kdb.
+   Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Written 13-Mar-86 by David Bridgham. */
+
+#include <stdio.h>
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <varargs.h>
+
+extern char *sys_errlist[];
+
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  register char *cp;
+  char *outfile;
+  register int i;
+  int offset;
+  int out_fd, in_fd;
+  struct stat stat_buf;
+  int size, pad;
+  char buf[1024];
+  static char zeros[4] = {0};
+
+  if (argc < 4)
+    err("Not enough arguments\nUsage: %s -o kdb file1 file2 ...\n",
+       argv[0]);
+
+  outfile = 0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "-o") == 0)
+       outfile = argv[++i];
+    }
+  if (outfile == 0)
+    err("Output file not specified\n");
+
+  offset = get_offset (outfile, "_heap");
+
+  out_fd = open (outfile, O_WRONLY);
+  if (out_fd < 0)
+    err ("Error opening %s for write: %s\n", outfile, sys_errlist[errno]);
+  if (lseek (out_fd, offset, 0) < 0)
+    err ("Error seeking to heap in %s: %s\n", outfile, sys_errlist[errno]);
+
+  /* For each file listed on the command line, write it into the
+   * 'heap' of the output file.  Make sure to skip the arguments
+   * that name the output file. */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "-o") == 0)
+       continue;
+      if ((in_fd = open (argv[i], O_RDONLY)) < 0)
+       err ("Error opening %s for read: %s\n", argv[i], sys_errlist[errno]);
+      if (fstat (in_fd, &stat_buf) < 0)
+       err ("Error stat'ing %s: %s\n", argv[i], sys_errlist[errno]);
+      size = strlen (argv[i]);
+      pad = 4 - (size & 3);
+      size += pad + stat_buf.st_size + sizeof (int);
+      write (out_fd, &size, sizeof (int));
+      write (out_fd, argv[i], strlen (argv[i]));
+      write (out_fd, zeros, pad);
+      while ((size = read (in_fd, buf, sizeof (buf))) > 0)
+       write (out_fd, buf, size);
+      close (in_fd);
+    }
+  size = 0;
+  write (out_fd, &size, sizeof (int));
+  close (out_fd);
+  return (0);
+}
+
+/* Read symbol table from file and returns the offset into the file
+ * where symbol sym_name is located.  If error, print message and
+ * exit. */
+get_offset (file, sym_name)
+     char *file;
+     char *sym_name;
+{
+  int f;
+  struct exec file_hdr;
+  struct nlist *symbol_table;
+  int size;
+  char *strings;
+
+  f = open (file, O_RDONLY);
+  if (f < 0)
+    err ("Error opening %s: %s\n", file, sys_errlist[errno]);
+  if (read (f, &file_hdr, sizeof (file_hdr)) < 0)
+    err ("Error reading exec structure: %s\n", sys_errlist[errno]);
+  if (N_BADMAG (file_hdr))
+    err ("File %s not an a.out file\n", file);
+
+  /* read in symbol table */
+  if ((symbol_table = (struct nlist *)malloc (file_hdr.a_syms)) == 0)
+    err ("Couldn't allocate space for symbol table\n");
+  if (lseek (f, N_SYMOFF (file_hdr), 0) == -1)
+    err ("lseek error: %s\n", sys_errlist[errno]);
+  if (read (f, symbol_table, file_hdr.a_syms) == -1)
+    err ("Error reading symbol table from %s: %s\n", file, sys_errlist[errno]);
+
+  /* read in string table */
+  if (read (f, &size, 4) == -1)
+    err ("reading string table size: %s\n", sys_errlist[errno]);
+  if ((strings = (char *)malloc (size)) == 0)
+    err ("Couldn't allocate memory for string table\n");
+  if (read (f, strings, size - 4) == -1)
+    err ("reading string table: %s\n", sys_errlist[errno]);
+
+  /* Find the core address at which the first byte of kdb text segment
+     should be loaded into core when kdb is run.  */
+  origin = find_symbol ("_etext", symbol_table, file_hdr.a_syms, strings)
+    - file_hdr.a_text;
+  /* Find the core address at which the heap will appear.  */
+  coreaddr = find_symbol (sym_name, symbol_table, file_hdr.a_syms, strings);
+  /* Return address in file of the heap data space.  */
+  return (N_TXTOFF (file_hdr) + core_addr - origin);
+}
+
+find_symbol (sym_name, symbol_table, length, strings)
+     char *sym_name;
+     struct nlist *symbol_table;
+     int length;
+     char *strings;
+{
+  register struct nlist *sym;
+
+  /* Find symbol in question */
+  for (sym = symbol_table;
+       sym != (struct nlist *)((char *)symbol_table + length);
+       sym++)
+      {
+       if ((sym->n_type & N_TYPE) != N_DATA) continue;
+       if (sym->n_un.n_strx == 0) continue;
+       if (strcmp (sym_name, strings + sym->n_un.n_strx - 4) == 0)
+         return sym->n_value;
+      }
+    err ("Data symbol %s not found in %s\n", sym_name, file);
+}
+
+/* VARARGS */
+void
+err (va_alist)
+     va_dcl
+{
+  va_list args;
+  char *string;
+
+  va_start (args);
+  string = va_arg (args, char *);
+  vfprintf (stderr, string, args);
+  va_end (args);
+  exit (-1);
+}
diff --git a/gdb/sun3-xdep.c b/gdb/sun3-xdep.c
new file mode 100644 (file)
index 0000000..6789cd6
--- /dev/null
@@ -0,0 +1,133 @@
+/* Sun-3 Machine-dependent code which would otherwise be in inflow.c and core.c,
+   for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "inferior.h"
+
+#include <sys/ptrace.h>
+#define KERNEL         /* To get floating point reg definitions */
+#include <machine/reg.h>
+
+#include "gdbcore.h"
+
+extern int errno;
+
+void
+fetch_inferior_registers ()
+{
+  struct regs inferior_registers;
+#ifdef FP0_REGNUM
+  struct fp_status inferior_fp_registers;
+#endif
+  extern char registers[];
+
+  registers_fetched ();
+  
+  ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
+#ifdef FP0_REGNUM
+  ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
+#endif 
+  
+  bcopy (&inferior_registers, registers, 16 * 4);
+#ifdef FP0_REGNUM
+  bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+        sizeof inferior_fp_registers.fps_regs);
+#endif 
+  *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
+  *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+#ifdef FP0_REGNUM
+  bcopy (&inferior_fp_registers.fps_control,
+        &registers[REGISTER_BYTE (FPC_REGNUM)],
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+#endif 
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+#ifdef FP0_REGNUM
+  struct fp_status inferior_fp_registers;
+#endif
+  extern char registers[];
+
+  bcopy (registers, &inferior_registers, 16 * 4);
+#ifdef FP0_REGNUM
+  bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+        sizeof inferior_fp_registers.fps_regs);
+#endif
+  inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
+  inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
+
+#ifdef FP0_REGNUM
+  bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+        &inferior_fp_registers.fps_control,
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
+#endif
+
+  ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
+#if FP0_REGNUM
+  ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
+#endif
+}
+
+/* Machine-dependent code for pulling registers out of a Sun-3 core file. */
+
+void
+fetch_core_registers (core_reg_sect, core_reg_size, which)
+     char *core_reg_sect;
+     unsigned core_reg_size;
+     int which;
+{
+  extern char registers[];
+  struct regs *regs = (struct regs *) core_reg_sect;
+
+  if (which == 0) {
+    if (core_reg_size < sizeof (struct regs))
+      error ("Can't find registers in core file");
+
+    bcopy ((char *)regs, registers, 16 * 4);
+    supply_register (PS_REGNUM, &regs->r_ps);
+    supply_register (PC_REGNUM, &regs->r_pc);
+
+  } else if (which == 2) {
+
+#define fpustruct  ((struct fpu *) core_reg_sect)
+
+    if (core_reg_size >= sizeof (struct fpu))
+      {
+       bcopy (fpustruct->f_fpstatus.fps_regs,
+             &registers[REGISTER_BYTE (FP0_REGNUM)],
+             sizeof fpustruct->f_fpstatus.fps_regs);
+       bcopy (&fpustruct->f_fpstatus.fps_control,
+             &registers[REGISTER_BYTE (FPC_REGNUM)],
+             sizeof fpustruct->f_fpstatus - 
+               sizeof fpustruct->f_fpstatus.fps_regs);
+      }
+    else
+      fprintf (stderr, "Couldn't read float regs from core file\n");
+  }
+}
diff --git a/gdb/sun386-xdep.c b/gdb/sun386-xdep.c
new file mode 100644 (file)
index 0000000..d9f1cb5
--- /dev/null
@@ -0,0 +1,252 @@
+/* Machine-dependent code for host Sun 386i's for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   Changes for sun386i by Jean Daniel Fekete (jdf@litp.univ-p6-7.fr),
+   C2V Paris, April 89.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "signame.h"
+#include "gdbcore.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/core.h>
+\f
+void
+fetch_inferior_registers ()
+{
+  struct regs inferior_registers;
+  struct fp_state inferior_fp_registers;
+  extern char registers[];
+
+  registers_fetched ();
+
+  ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
+  ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
+
+  bcopy (&inferior_registers, registers, sizeof inferior_registers);
+
+  bcopy (inferior_fp_registers.f_st,&registers[REGISTER_BYTE (FP0_REGNUM)],
+        sizeof inferior_fp_registers.f_st);
+  bcopy (&inferior_fp_registers.f_ctrl,
+        &registers[REGISTER_BYTE (FPC_REGNUM)],
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+
+store_inferior_registers (regno)
+     int regno;
+{
+  struct regs inferior_registers;
+  struct fp_state inferior_fp_registers;
+  extern char registers[];
+
+  bcopy (registers, &inferior_registers, 20 * 4);
+
+  bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],inferior_fp_registers.f_st,
+        sizeof inferior_fp_registers.f_st);
+  bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
+        &inferior_fp_registers.f_ctrl,
+        sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
+  
+#ifdef PTRACE_FP_BUG
+  if (regno == FP_REGNUM || regno == -1)
+    /* Storing the frame pointer requires a gross hack, in which an
+       instruction that moves eax into ebp gets single-stepped.  */
+    {
+      int stack = inferior_registers.r_reg[SP_REGNUM];
+      int stuff = ptrace (PTRACE_PEEKDATA, inferior_pid, stack);
+      int reg = inferior_registers.r_reg[EAX];
+      inferior_registers.r_reg[EAX] =
+       inferior_registers.r_reg[FP_REGNUM];
+      ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
+      ptrace (PTRACE_POKEDATA, inferior_pid, stack, 0xc589);
+      ptrace (PTRACE_SINGLESTEP, inferior_pid, stack, 0);
+      wait (0);
+      ptrace (PTRACE_POKEDATA, inferior_pid, stack, stuff);
+      inferior_registers.r_reg[EAX] = reg;
+    }
+#endif
+  ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
+  ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
+}
+
+/* Machine-dependent code which would otherwise be in core.c */
+/* Work with core files, for GDB. */
+
+\f
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+
+      {
+       struct core corestr;
+
+       val = myread (corechan, &corestr, sizeof corestr);
+       if (val < 0)
+         perror_with_name (filename);
+       if (corestr.c_magic != CORE_MAGIC)
+         error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
+                filename, corestr.c_magic, (int) CORE_MAGIC);
+       else if (sizeof (struct core) != corestr.c_len)
+         error ("\"%s\" has an invalid struct core length (%d, expected %d)",
+                filename, corestr.c_len, (int) sizeof (struct core));
+
+       data_start = exec_data_start;
+       data_end = data_start + corestr.c_dsize;
+       stack_start = stack_end - corestr.c_ssize;
+       data_offset = sizeof corestr;
+       stack_offset = sizeof corestr + corestr.c_dsize;
+
+       bcopy (&corestr.c_regs, registers, sizeof corestr.c_regs);
+
+       bcopy (corestr.c_fpu.f_fpstatus.f_st,
+              &registers[REGISTER_BYTE (FP0_REGNUM)],
+              sizeof corestr.c_fpu.f_fpstatus.f_st);
+       bcopy (&corestr.c_fpu.f_fpstatus.f_ctrl,
+              &registers[REGISTER_BYTE (FPC_REGNUM)],
+              sizeof corestr.c_fpu.f_fpstatus -
+              sizeof corestr.c_fpu.f_fpstatus.f_st);
+
+       /* the struct aouthdr of sun coff is not the struct exec stored
+          in the core file. */
+       bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec));
+#ifndef COFF_ENCAPSULATE
+       core_aouthdr.magic = corestr.c_aouthdr.a_info;
+       core_aouthdr.vstamp = /*SUNVERSION*/ 31252;
+#endif
+       printf ("Core file is from \"%s\".\n", corestr.c_cmdname);
+       if (corestr.c_signo > 0)
+         printf ("Program terminated with signal %d, %s.\n",
+                       corestr.c_signo,
+                       corestr.c_signo < NSIG
+                       ? sys_siglist[corestr.c_signo]
+                       : "(undocumented)");
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+      select_frame (get_current_frame (), 0);
+
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
+
+i387_to_double (from, to)
+     char *from;
+     char *to;
+{
+  long *lp;
+  /* push extended mode on 387 stack, then pop in double mode
+   *
+   * first, set exception masks so no error is generated -
+   * number will be rounded to inf or 0, if necessary 
+   */
+  asm ("pushl %eax");          /* grab a stack slot */
+  asm ("fstcw (%esp)");                /* get 387 control word */
+  asm ("movl (%esp),%eax");    /* save old value */
+  asm ("orl $0x3f,%eax");              /* mask all exceptions */
+  asm ("pushl %eax");
+  asm ("fldcw (%esp)");                /* load new value into 387 */
+  
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldt (%eax)");         /* push extended number on 387 stack */
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpl (%eax)");                /* pop double */
+  asm ("fwait");
+  
+  asm ("popl %eax");           /* flush modified control word */
+  asm ("fnclex");                      /* clear exceptions */
+  asm ("fldcw (%esp)");                /* restore original control word */
+  asm ("popl %eax");           /* flush saved copy */
+}
+
+double_to_i387 (from, to)
+     char *from;
+     char *to;
+{
+  /* push double mode on 387 stack, then pop in extended mode
+   * no errors are possible because every 64-bit pattern
+   * can be converted to an extended
+   */
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldl (%eax)");
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpt (%eax)");
+  asm ("fwait");
+}
diff --git a/gdb/symmetry-tdep.c b/gdb/symmetry-tdep.c
new file mode 100755 (executable)
index 0000000..aba21c3
--- /dev/null
@@ -0,0 +1,494 @@
+/* Sequent Symmetry target interface, for GDB when running under Unix.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* many 387-specific items of use taken from i386-dep.c */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include "gdbcore.h"
+#include <fcntl.h>
+
+static long i386_get_frame_setup ();
+static i386_follow_jump ();
+
+#include <sgtty.h>
+#define TERMINAL struct sgttyb
+
+exec_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+
+  /* Eliminate all traces of old exec file.
+     Mark text segment as empty.  */
+
+  if (execfile)
+    free (execfile);
+  execfile = 0;
+  data_start = 0;
+  data_end -= exec_data_start;
+  text_start = 0;
+  text_end = 0;
+  exec_data_start = 0;
+  exec_data_end = 0;
+  if (execchan >= 0)
+    close (execchan);
+  execchan = -1;
+
+  /* Now open and digest the file the user requested, if any.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+                       &execfile);
+      if (execchan < 0)
+       perror_with_name (filename);
+
+#ifdef COFF_FORMAT
+      {
+       int aout_hdrsize;
+       int num_sections;
+
+       if (read_file_hdr (execchan, &file_hdr) < 0)
+         error ("\"%s\": not in executable format.", execfile);
+
+       aout_hdrsize = file_hdr.f_opthdr;
+       num_sections = file_hdr.f_nscns;
+
+       if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
+         error ("\"%s\": can't read optional aouthdr", execfile);
+
+       if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
+                             aout_hdrsize) < 0)
+         error ("\"%s\": can't read text section header", execfile);
+
+       if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
+                             aout_hdrsize) < 0)
+         error ("\"%s\": can't read data section header", execfile);
+
+       text_start = exec_aouthdr.text_start;
+       text_end = text_start + exec_aouthdr.tsize;
+       text_offset = text_hdr.s_scnptr;
+       exec_data_start = exec_aouthdr.data_start;
+       exec_data_end = exec_data_start + exec_aouthdr.dsize;
+       exec_data_offset = data_hdr.s_scnptr;
+       data_start = exec_data_start;
+       data_end += exec_data_start;
+       exec_mtime = file_hdr.f_timdat;
+      }
+#else /* not COFF_FORMAT */
+      {
+       struct stat st_exec;
+
+       val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
+
+       if (val < 0)
+         perror_with_name (filename);
+
+       text_start = N_ADDRADJ(exec_aouthdr);
+        exec_data_start = round(exec_aouthdr.a_text, NBPG*CLSIZE);
+       text_offset = N_TXTOFF (exec_aouthdr);
+       exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
+       text_end = exec_aouthdr.a_text;
+        exec_data_end = exec_data_start + exec_aouthdr.a_data;
+       data_start = exec_data_start;
+       data_end = data_start + exec_aouthdr.a_data;
+       exec_data_offset = N_TXTOFF(exec_aouthdr);
+       fstat (execchan, &st_exec);
+       exec_mtime = st_exec.st_mtime;
+      }
+#endif /* not COFF_FORMAT */
+
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No exec file now.\n");
+
+  /* Tell display code (if any) about the changed file name.  */
+  if (exec_file_display_hook)
+    (*exec_file_display_hook) (filename);
+}
+
+/* rounds 'one' up to divide evenly by 'two' */
+
+int
+round(one,two)
+register int one, two;
+
+{
+    register int temp;
+    temp = (one/two)*two;
+    if (one != temp) {
+       temp += two;
+    }
+    return temp;
+}
+
+
+static CORE_ADDR codestream_next_addr;
+static CORE_ADDR codestream_addr;
+static unsigned char codestream_buf[sizeof (int)];
+static int codestream_off;
+static int codestream_cnt;
+
+#define codestream_tell() (codestream_addr + codestream_off)
+#define codestream_peek() (codestream_cnt == 0 ? \
+                          codestream_fill(1): codestream_buf[codestream_off])
+#define codestream_get() (codestream_cnt-- == 0 ? \
+                        codestream_fill(0) : codestream_buf[codestream_off++])
+
+
+static unsigned char 
+codestream_fill (peek_flag)
+{
+  codestream_addr = codestream_next_addr;
+  codestream_next_addr += sizeof (int);
+  codestream_off = 0;
+  codestream_cnt = sizeof (int);
+  read_memory (codestream_addr,
+              (unsigned char *)codestream_buf,
+              sizeof (int));
+  
+  if (peek_flag)
+    return (codestream_peek());
+  else
+    return (codestream_get());
+}
+
+static void
+codestream_seek (place)
+{
+  codestream_next_addr = place & -sizeof (int);
+  codestream_cnt = 0;
+  codestream_fill (1);
+  while (codestream_tell() != place)
+    codestream_get ();
+}
+
+static void
+codestream_read (buf, count)
+     unsigned char *buf;
+{
+  unsigned char *p;
+  int i;
+  p = buf;
+  for (i = 0; i < count; i++)
+    *p++ = codestream_get ();
+}
+
+/*
+ * Following macro translates i386 opcode register numbers to Symmetry
+ * register numbers.  This is used by FRAME_FIND_SAVED_REGS.
+ *
+ *           %eax  %ecx  %edx  %ebx  %esp  %ebp  %esi  %edi
+ * i386        0     1     2     3     4     5     6     7
+ * Symmetry    0     2     1     5    14    15     6     7
+ *
+ */
+#define I386_REGNO_TO_SYMMETRY(n) \
+((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n))
+
+/* from i386-dep.c */
+i386_frame_find_saved_regs (fip, fsrp)
+     struct frame_info *fip;
+     struct frame_saved_regs *fsrp;
+{
+  unsigned long locals;
+  unsigned char *p;
+  unsigned char op;
+  CORE_ADDR dummy_bottom;
+  CORE_ADDR adr;
+  int i;
+  
+  bzero (fsrp, sizeof *fsrp);
+  
+  /* if frame is the end of a dummy, compute where the
+   * beginning would be
+   */
+  dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH;
+  
+  /* check if the PC is in the stack, in a dummy frame */
+  if (dummy_bottom <= fip->pc && fip->pc <= fip->frame) 
+    {
+      /* all regs were saved by push_call_dummy () */
+      adr = fip->frame - 4;
+      for (i = 0; i < NUM_REGS; i++) 
+       {
+         fsrp->regs[i] = adr;
+         adr -= 4;
+       }
+      return;
+    }
+  
+  locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
+  
+  if (locals >= 0) 
+    {
+      adr = fip->frame - 4 - locals;
+      for (i = 0; i < 8; i++) 
+       {
+         op = codestream_get ();
+         if (op < 0x50 || op > 0x57)
+           break;
+         fsrp->regs[I386_REGNO_TO_SYMMETRY(op - 0x50)] = adr;
+         adr -= 4;
+       }
+    }
+  
+  fsrp->regs[PC_REGNUM] = fip->frame + 4;
+  fsrp->regs[FP_REGNUM] = fip->frame;
+}
+
+static long
+i386_get_frame_setup (pc)
+{
+  unsigned char op;
+  
+  codestream_seek (pc);
+  
+  i386_follow_jump ();
+  
+  op = codestream_get ();
+  
+  if (op == 0x58) /* popl %eax */
+    {
+      /*
+       * this function must start with
+       * 
+       *    popl %eax            0x58
+       *    xchgl %eax, (%esp)  0x87 0x04 0x24
+       * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
+       *
+       * (the system 5 compiler puts out the second xchg
+       * inst, and the assembler doesn't try to optimize it,
+       * so the 'sib' form gets generated)
+       * 
+       * this sequence is used to get the address of the return
+       * buffer for a function that returns a structure
+       */
+      int pos;
+      unsigned char buf[4];
+      static unsigned char proto1[3] = { 0x87,0x04,0x24 };
+      static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
+      pos = codestream_tell ();
+      codestream_read (buf, 4);
+      if (bcmp (buf, proto1, 3) == 0)
+       pos += 3;
+      else if (bcmp (buf, proto2, 4) == 0)
+       pos += 4;
+      
+      codestream_seek (pos);
+      op = codestream_get (); /* update next opcode */
+    }
+  
+  if (op == 0x55)                      /* pushl %esp */
+    {
+      if (codestream_get () != 0x8b)   /* movl %esp, %ebp (2bytes) */
+       return (-1);
+      if (codestream_get () != 0xec)
+       return (-1);
+      /*
+       * check for stack adjustment 
+       *
+       *  subl $XXX, %esp
+       *
+       * note: you can't subtract a 16 bit immediate
+       * from a 32 bit reg, so we don't have to worry
+       * about a data16 prefix 
+       */
+      op = codestream_peek ();
+      if (op == 0x83)  /* subl with 8 bit immed */
+       {
+         codestream_get ();
+         if (codestream_get () != 0xec)
+           return (-1);
+         /* subl with signed byte immediate 
+          * (though it wouldn't make sense to be negative)
+          */
+         return (codestream_get());
+       }
+      else if (op == 0x81)  /* subl with 32 bit immed */
+       {
+         int locals;
+         if (codestream_get () != 0xec)
+           return (-1);
+         /* subl with 32 bit immediate */
+         codestream_read ((unsigned char *)&locals, 4);
+         return (locals);
+       } 
+      else 
+       {
+         return (0);
+       }
+    } 
+  else if (op == 0xc8) 
+    {
+      /* enter instruction: arg is 16 unsigned immed */
+      unsigned short slocals;
+      codestream_read ((unsigned char *)&slocals, 2);
+      codestream_get (); /* flush final byte of enter instruction */
+      return (slocals);
+    }
+  return (-1);
+}
+
+/* next instruction is a jump, move to target */
+static
+i386_follow_jump ()
+{
+  int long_delta;
+  short short_delta;
+  char byte_delta;
+  int data16;
+  int pos;
+  
+  pos = codestream_tell ();
+  
+  data16 = 0;
+  if (codestream_peek () == 0x66)
+    {
+      codestream_get ();
+      data16 = 1;
+    }
+  
+  switch (codestream_get ())
+    {
+    case 0xe9:
+      /* relative jump: if data16 == 0, disp32, else disp16 */
+      if (data16)
+       {
+         codestream_read ((unsigned char *)&short_delta, 2);
+         pos += short_delta + 3; /* include size of jmp inst */
+       }
+      else
+       {
+         codestream_read ((unsigned char *)&long_delta, 4);
+         pos += long_delta + 5;
+       }
+      break;
+    case 0xeb:
+      /* relative jump, disp8 (ignore data16) */
+      codestream_read ((unsigned char *)&byte_delta, 1);
+      pos += byte_delta + 2;
+      break;
+    }
+  codestream_seek (pos + data16);
+}
+
+/* return pc of first real instruction */
+/* from i386-dep.c */
+
+i386_skip_prologue (pc)
+{
+  unsigned char op;
+  int i;
+  
+  if (i386_get_frame_setup (pc) < 0)
+    return (pc);
+  
+  /* found valid frame setup - codestream now points to 
+   * start of push instructions for saving registers
+   */
+  
+  /* skip over register saves */
+  for (i = 0; i < 8; i++)
+    {
+      op = codestream_peek ();
+      /* break if not pushl inst */
+      if (op < 0x50 || op > 0x57) 
+       break;
+      codestream_get ();
+    }
+  
+  i386_follow_jump ();
+  
+  return (codestream_tell ());
+}
+
+symmetry_extract_return_value(type, regbuf, valbuf)
+     struct type *type;
+     char *regbuf;
+     char *valbuf;
+{
+  union { 
+    double     d; 
+    int        l[2]; 
+  } xd; 
+  int i;
+  float f;
+
+  if (TYPE_CODE_FLT == TYPE_CODE(type)) { 
+    for (i = 0; i < misc_function_count; i++) {
+      if (!strcmp(misc_function_vector[i].name, "1167_flt"))
+       break;
+    }
+    if (i < misc_function_count) {
+      /* found "1167_flt" means 1167, %fp2-%fp3 */ 
+      /* float & double; 19= %fp2, 20= %fp3 */
+      /* no single precision on 1167 */
+      xd.l[1] = *((int *)&regbuf[REGISTER_BYTE(19)]);
+      xd.l[0] = *((int *)&regbuf[REGISTER_BYTE(20)]);
+      switch (TYPE_LENGTH(type)) {
+      case 4:
+       f = (float) xd.d;
+       bcopy(&f, valbuf, TYPE_LENGTH(type));
+       break;
+      case 8:
+       bcopy(&xd.d, valbuf, TYPE_LENGTH(type)); 
+       break;
+      default:
+       error("Unknown floating point size");
+       break;
+      }
+    } else { 
+      /* 387 %st(0), gcc uses this */ 
+      i387_to_double(((int *)&regbuf[REGISTER_BYTE(3)]),
+                    &xd.d); 
+      switch (TYPE_LENGTH(type)) {
+      case 4:                  /* float */
+       f = (float) xd.d;
+       bcopy(&f, valbuf, 4); 
+       break;
+      case 8:                  /* double */
+       bcopy(&xd.d, valbuf, 8);
+       break;
+      default:
+       error("Unknown floating point size");
+       break;
+      }
+    }
+  } else { 
+    bcopy (regbuf, valbuf, TYPE_LENGTH (type)); 
+  }
+}
diff --git a/gdb/symmetry-xdep.c b/gdb/symmetry-xdep.c
new file mode 100755 (executable)
index 0000000..3449678
--- /dev/null
@@ -0,0 +1,557 @@
+/* Sequent Symmetry host interface, for GDB when running under Unix.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* many 387-specific items of use taken from i386-dep.c */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/dir.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include "gdbcore.h"
+#include <fcntl.h>
+
+static long i386_get_frame_setup ();
+static i386_follow_jump ();
+
+#include <sgtty.h>
+#define TERMINAL struct sgttyb
+
+store_inferior_registers(regno)
+int regno;
+{
+  struct pt_regset regs;
+  int reg_tmp, i;
+  extern char registers[];
+  
+#if 0
+  /* PREPARE_TO_STORE deals with this.  */
+  if (-1 == regno)
+    {
+#endif
+      regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
+      regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
+      regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
+      regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
+      regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
+      regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
+      regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
+      regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
+      regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
+      regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
+      for (i = 0; i < 31; i++) {
+       regs.pr_fpa.fpa_regs[i] =
+         *(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)];
+      }
+#if 0
+    }
+  else
+    {
+      reg_tmp = *(int *)&registers[REGISTER_BYTE(regno)];
+      ptrace(XPT_RREGS, inferior_pid, &regs, 0);
+      switch (regno)
+       {
+       case 0:
+         regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
+         break;
+       case 5:
+         regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
+         break;
+       case 2:
+         regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
+         break;
+       case 1:
+         regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
+         break;
+       case 6:
+         regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
+         break;
+       case 7:
+         regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
+         break;
+       case 15:
+         regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
+         break;
+       case 14:
+         regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
+         break;
+       case 16:
+         regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
+         break;
+       case 17:
+         regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
+         break;
+       }
+    }
+#endif /* 0 */
+  ptrace(XPT_WREGS, inferior_pid, &regs, 0);
+}
+
+void
+fetch_inferior_registers()
+{
+    int i;
+    struct pt_regset regs;
+    extern char registers[];
+
+    registers_fetched ();
+    
+    ptrace(XPT_RREGS, inferior_pid, &regs, 0);
+    *(int *)&registers[REGISTER_BYTE(0)] = regs.pr_eax;
+    *(int *)&registers[REGISTER_BYTE(5)] = regs.pr_ebx;
+    *(int *)&registers[REGISTER_BYTE(2)] = regs.pr_ecx;
+    *(int *)&registers[REGISTER_BYTE(1)] = regs.pr_edx;
+    *(int *)&registers[REGISTER_BYTE(6)] = regs.pr_esi;
+    *(int *)&registers[REGISTER_BYTE(7)] = regs.pr_edi;
+    *(int *)&registers[REGISTER_BYTE(15)] = regs.pr_ebp;
+    *(int *)&registers[REGISTER_BYTE(14)] = regs.pr_esp;
+    *(int *)&registers[REGISTER_BYTE(16)] = regs.pr_eip;
+    *(int *)&registers[REGISTER_BYTE(17)] = regs.pr_flags;
+    for (i = 0; i < FPA_NREGS; i++) {
+       *(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)] = regs.pr_fpa.fpa_regs[i];
+    }
+    bcopy(regs.pr_fpu.fpu_stack[0], &registers[REGISTER_BYTE(3)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[1], &registers[REGISTER_BYTE(4)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[2], &registers[REGISTER_BYTE(8)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[3], &registers[REGISTER_BYTE(9)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[4], &registers[REGISTER_BYTE(10)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[5], &registers[REGISTER_BYTE(11)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[6], &registers[REGISTER_BYTE(12)], 10);
+    bcopy(regs.pr_fpu.fpu_stack[7], &registers[REGISTER_BYTE(13)], 10);
+}
+
+\f
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+#include "gdbcore.h"
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct user u;
+       int reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name (filename);
+       data_start = exec_data_start;
+
+       data_end = data_start + NBPG * (u.u_dsize - u.u_tsize);
+       stack_start = stack_end - NBPG * u.u_ssize;
+       data_offset = NBPG * UPAGES;
+       stack_offset = ctob(UPAGES + u.u_dsize - u.u_tsize);
+       reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
+printf("u.u_tsize= %#x, u.u_dsize= %#x, u.u_ssize= %#x, stack_off= %#x\n",
+       u.u_tsize, u.u_dsize, u.u_ssize, stack_offset);
+
+       core_aouthdr.a_magic = 0;
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < NUM_REGS; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             val = lseek (corechan, register_addr (regno, reg_offset), 0);
+             if (val < 0)
+               perror_with_name (filename);
+
+             val = myread (corechan, buf, sizeof buf);
+             if (val < 0)
+               perror_with_name (filename);
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame(create_new_frame(read_register(FP_REGNUM),
+                                        read_pc()));
+/*      set_current_frame (read_register (FP_REGNUM));*/
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
+
+/* from i386-dep.c */
+static
+print_387_control_word (control)
+unsigned short control;
+{
+  printf ("control 0x%04x: ", control);
+  printf ("compute to ");
+  switch ((control >> 8) & 3) 
+    {
+    case 0: printf ("24 bits; "); break;
+    case 1: printf ("(bad); "); break;
+    case 2: printf ("53 bits; "); break;
+    case 3: printf ("64 bits; "); break;
+    }
+  printf ("round ");
+  switch ((control >> 10) & 3) 
+    {
+    case 0: printf ("NEAREST; "); break;
+    case 1: printf ("DOWN; "); break;
+    case 2: printf ("UP; "); break;
+    case 3: printf ("CHOP; "); break;
+    }
+  if (control & 0x3f) 
+    {
+      printf ("mask:");
+      if (control & 0x0001) printf (" INVALID");
+      if (control & 0x0002) printf (" DENORM");
+      if (control & 0x0004) printf (" DIVZ");
+      if (control & 0x0008) printf (" OVERF");
+      if (control & 0x0010) printf (" UNDERF");
+      if (control & 0x0020) printf (" LOS");
+      printf (";");
+    }
+  printf ("\n");
+  if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n",
+                               control & 0xe080);
+}
+
+static
+print_387_status_word (status)
+     unsigned short status;
+{
+  printf ("status %#04x: ", status);
+  if (status & 0xff) {
+      printf ("exceptions:");  /* exception names match <machine/fpu.h> */
+      if (status & 0x0001) printf (" FLTINV");
+      if (status & 0x0002) printf (" FLTDEN");
+      if (status & 0x0004) printf (" FLTDIV");
+      if (status & 0x0008) printf (" FLTOVF");
+      if (status & 0x0010) printf (" FLTUND");
+      if (status & 0x0020) printf (" FLTPRE");
+      if (status & 0x0040) printf (" FLTSTK");
+      printf ("; ");
+    }
+  printf ("flags: %d%d%d%d; ",
+         (status & 0x4000) != 0,
+         (status & 0x0400) != 0,
+         (status & 0x0200) != 0,
+         (status & 0x0100) != 0);
+  
+  printf ("top %d\n", (status >> 11) & 7);
+}
+
+static
+print_fpu_status(ep)
+struct pt_regset ep;
+
+{
+    int i;
+    int bothstatus;
+    int top;
+    int fpreg;
+    unsigned char *p;
+    
+    printf("80387:");
+    if (ep.pr_fpu.fpu_ip == 0) {
+       printf(" not in use.\n");
+       return;
+    } else {
+       printf("\n");
+    }
+    if (ep.pr_fpu.fpu_status != 0) {
+       print_387_status_word (ep.pr_fpu.fpu_status);
+    }
+    print_387_control_word (ep.pr_fpu.fpu_control);
+    printf ("last exception: ");
+    printf ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4);
+    printf ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip);
+    printf ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel);
+    
+    top = (ep.pr_fpu.fpu_status >> 11) & 7;
+    
+    printf ("regno  tag  msb              lsb  value\n");
+    for (fpreg = 7; fpreg >= 0; fpreg--) 
+       {
+           double val;
+           
+           printf ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
+           
+           switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3) 
+               {
+               case 0: printf ("valid "); break;
+               case 1: printf ("zero  "); break;
+               case 2: printf ("trap  "); break;
+               case 3: printf ("empty "); break;
+               }
+           for (i = 9; i >= 0; i--)
+               printf ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]);
+           
+           i387_to_double (ep.pr_fpu.fpu_stack[fpreg], (char *)&val);
+           printf ("  %g\n", val);
+       }
+    if (ep.pr_fpu.fpu_rsvd1)
+       printf ("warning: rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1);
+    if (ep.pr_fpu.fpu_rsvd2)
+       printf ("warning: rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2);
+    if (ep.pr_fpu.fpu_rsvd3)
+       printf ("warning: rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3);
+    if (ep.pr_fpu.fpu_rsvd5)
+       printf ("warning: rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5);
+}
+
+
+print_1167_control_word(pcr)
+unsigned int pcr;
+
+{
+    int pcr_tmp;
+
+    pcr_tmp = pcr & FPA_PCR_MODE;
+    printf("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12);
+    switch (pcr_tmp & 12) {
+    case 0:
+       printf("RN (Nearest Value)");
+       break;
+    case 1:
+       printf("RZ (Zero)");
+       break;
+    case 2:
+       printf("RP (Positive Infinity)");
+       break;
+    case 3:
+       printf("RM (Negative Infinity)");
+       break;
+    }
+    printf("; IRND= %d ", pcr_tmp & 2);
+    if (0 == pcr_tmp & 2) {
+       printf("(same as RND)\n");
+    } else {
+       printf("(toward zero)\n");
+    }
+    pcr_tmp = pcr & FPA_PCR_EM;
+    printf("\tEM= %#x", pcr_tmp);
+    if (pcr_tmp & FPA_PCR_EM_DM) printf(" DM");
+    if (pcr_tmp & FPA_PCR_EM_UOM) printf(" UOM");
+    if (pcr_tmp & FPA_PCR_EM_PM) printf(" PM");
+    if (pcr_tmp & FPA_PCR_EM_UM) printf(" UM");
+    if (pcr_tmp & FPA_PCR_EM_OM) printf(" OM");
+    if (pcr_tmp & FPA_PCR_EM_ZM) printf(" ZM");
+    if (pcr_tmp & FPA_PCR_EM_IM) printf(" IM");
+    printf("\n");
+    pcr_tmp = FPA_PCR_CC;
+    printf("\tCC= %#x", pcr_tmp);
+    if (pcr_tmp & FPA_PCR_20MHZ) printf(" 20MHZ");
+    if (pcr_tmp & FPA_PCR_CC_Z) printf(" Z");
+    if (pcr_tmp & FPA_PCR_CC_C2) printf(" C2");
+    if (pcr_tmp & FPA_PCR_CC_C1) printf(" C1");
+    switch (pcr_tmp) {
+    case FPA_PCR_CC_Z:
+       printf(" (Equal)");
+       break;
+    case FPA_PCR_CC_C1:
+       printf(" (Less than)");
+       break;
+    case 0:
+       printf(" (Greater than)");
+       break;
+    case FPA_PCR_CC_Z | FPA_PCR_CC_C1 | FPA_PCR_CC_C2:
+       printf(" (Unordered)");
+       break;
+    default:
+       printf(" (Undefined)");
+       break;
+    }
+    printf("\n");
+    pcr_tmp = pcr & FPA_PCR_AE;
+    printf("\tAE= %#x", pcr_tmp);
+    if (pcr_tmp & FPA_PCR_AE_DE) printf(" DE");
+    if (pcr_tmp & FPA_PCR_AE_UOE) printf(" UOE");
+    if (pcr_tmp & FPA_PCR_AE_PE) printf(" PE");
+    if (pcr_tmp & FPA_PCR_AE_UE) printf(" UE");
+    if (pcr_tmp & FPA_PCR_AE_OE) printf(" OE");
+    if (pcr_tmp & FPA_PCR_AE_ZE) printf(" ZE");
+    if (pcr_tmp & FPA_PCR_AE_EE) printf(" EE");
+    if (pcr_tmp & FPA_PCR_AE_IE) printf(" IE");
+    printf("\n");
+}
+
+print_1167_regs(regs)
+long regs[FPA_NREGS];
+
+{
+    int i;
+
+    union {
+       double  d;
+       long    l[2];
+    } xd;
+    union {
+       float   f;
+       long    l;
+    } xf;
+
+
+    for (i = 0; i < FPA_NREGS; i++) {
+       xf.l = regs[i];
+       printf("%%fp%d: raw= %#x, single= %f", i+1, regs[i], xf.f);
+       if (!(i & 1)) {
+           printf("\n");
+       } else {
+           xd.l[1] = regs[i];
+           xd.l[0] = regs[i+1];
+           printf(", double= %f\n", xd.d);
+       }
+    }
+}
+
+print_fpa_status(ep)
+struct pt_regset ep;
+
+{
+
+    printf("WTL 1167:");
+    if (ep.pr_fpa.fpa_pcr !=0) {
+       printf("\n");
+       print_1167_control_word(ep.pr_fpa.fpa_pcr);
+       print_1167_regs(ep.pr_fpa.fpa_regs);
+    } else {
+       printf(" not in use.\n");
+    }
+}
+
+i386_float_info ()
+
+{
+    char ubuf[UPAGES*NBPG];
+    struct pt_regset regset;
+    extern int corechan;
+    
+    if (have_inferior_p()) {
+       call_ptrace(XPT_RREGS, inferior_pid, &regset, 0);
+    } else {
+       if (lseek (corechan, 0, 0) < 0) {
+           perror ("seek on core file");
+       }
+       if (myread (corechan, ubuf, UPAGES*NBPG) < 0) {
+           perror ("read on core file");
+       }
+       /* only interested in the floating point registers */
+       regset.pr_fpu = ((struct user *) ubuf)->u_fpusave;
+       regset.pr_fpa = ((struct user *) ubuf)->u_fpasave;
+    }
+    print_fpu_status(regset);
+    print_fpa_status(regset);
+}
+
+i387_to_double (from, to)
+     char *from;
+     char *to;
+{
+  long *lp;
+  /* push extended mode on 387 stack, then pop in double mode
+   *
+   * first, set exception masks so no error is generated -
+   * number will be rounded to inf or 0, if necessary 
+   */
+  asm ("pushl %eax");          /* grab a stack slot */
+  asm ("fstcw (%esp)");                /* get 387 control word */
+  asm ("movl (%esp),%eax");    /* save old value */
+  asm ("orl $0x3f,%eax");              /* mask all exceptions */
+  asm ("pushl %eax");
+  asm ("fldcw (%esp)");                /* load new value into 387 */
+  
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldt (%eax)");         /* push extended number on 387 stack */
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpl (%eax)");                /* pop double */
+  asm ("fwait");
+  
+  asm ("popl %eax");           /* flush modified control word */
+  asm ("fnclex");                      /* clear exceptions */
+  asm ("fldcw (%esp)");                /* restore original control word */
+  asm ("popl %eax");           /* flush saved copy */
+}
+
+double_to_i387 (from, to)
+     char *from;
+     char *to;
+{
+  /* push double mode on 387 stack, then pop in extended mode
+   * no errors are possible because every 64-bit pattern
+   * can be converted to an extended
+   */
+  asm ("movl 8(%ebp),%eax");
+  asm ("fldl (%eax)");
+  asm ("fwait");
+  asm ("movl 12(%ebp),%eax");
+  asm ("fstpt (%eax)");
+  asm ("fwait");
+}
diff --git a/gdb/tdesc.c b/gdb/tdesc.c
new file mode 100755 (executable)
index 0000000..9a632e3
--- /dev/null
@@ -0,0 +1,1650 @@
+/* This file has been modified by Data General Corporation, November 1989. */
+
+/*
+This file provides an abstract interface to "tdesc" information.
+      It is designed to be used in a uniform manner by several kinds
+      of debuggers:
+         (1) code in live debugged process (e.g., a traceback routine)
+         (2) a separate-process debugger debugging a live process
+         (3) a separate-process debugger debugging a memory dump
+
+      Dcontext model notes
+         * captures machine context
+            * partial: excludes memory
+         * frames
+            * kinds
+         * make one for starters, chain in reverse order to previous ones
+         * representation: pointer to opaque
+            * alloc/free protocol
+
+      Overall model
+         * access functions
+         * handle
+         * error handling
+*/
+
+
+
+typedef int dc_boolean_t;   /* range 0 .. 1 */
+#define DC_FALSE 0
+#define DC_TRUE 1
+
+
+typedef int dc_tristate_t;  /* range 0 .. 2 */
+#define DC_NO 0
+#define DC_YES 1
+#define DC_MAYBE 2
+
+
+/*
+   A word is 32 bits of information.  In memory, a word is word-aligned.
+
+   A common and important use of dc_word_t is to represent values in the
+   target process, including (byte) addresses in the target process.
+   In this case, C arithmetic can be used to simulate machine address
+   arithmetic on the target.  (Unsigned arithmetic is actually modulus
+   arithmetic.)
+*/
+typedef unsigned int dc_word_t;
+
+
+/* These bit operations number bits from 0 at the least significant end. */
+#define bit_test(word,bit) ((word) & (1 << (bit)))    /* returns 0 or other */
+#define bit_value(word,bit) (((word) >> (bit)) & 1)   /* returns 0 or 1 */
+#define bit_set(word,bit) ((word) |= (1 << (bit)))
+#define bit_clear(word,bit) ((word) &= ~(1 << (bit)))
+#define bit_assign(word, bit, bool) \
+   if (bool) bit_set(word, bit); else bit_clear(word, bit)
+
+
+/*----------------*/
+
+
+/* The exactness of locations may not be certainly known. */
+typedef dc_tristate_t dc_exactness_t;
+
+
+/*
+   The model includes five kinds of contexts.  Because each context
+   has an associated region and frame, these describe region kinds
+   and frame kinds as well.
+   [more description needed]
+   Currently, only call contexts exist.
+*/
+
+typedef int dc_kind_t;   /* range 0 .. 4 */
+#define DC_CALL_KIND          0
+#define DC_SAVE_KIND          1
+#define DC_EXCEPTION_KIND     2
+#define DC_PROTECTION_KIND    3
+#define DC_SPECIAL_KIND       4
+#define DC_NUM_KINDS          5
+
+#define DC_MIO_ENTRY_POINT            (1<< 0)
+#define DC_MIO_PROLOGUE_END           (1<< 1)
+#define DC_MIO_EPILOGUE_START         (1<< 2)
+#define DC_MIO_IMPLICIT_PROLOGUE_END  (1<<16)
+#define DC_MIO_LITERAL_ENTRY_POINT    (1<<17)
+#define DC_MIO_LITERAL_EPILOGUE_START (1<<18)
+
+#define DC_MII_PRECEDING_TDESC_END   (1<<0)
+#define DC_MII_FOLLOWING_TDESC_START (1<<1)
+
+typedef struct dc_debug_info {
+   unsigned int         protocol;            /* 1 for this structure */
+   dc_word_t               tdesc_ptr;
+   unsigned int         text_words_count;
+   dc_word_t               text_words_ptr;
+   unsigned int         data_words_count;
+   dc_word_t               data_words_ptr;
+} dc_debug_info_t;
+
+
+typedef struct tdesc_hdr {
+   unsigned int         map_protocol;        /* 1 for this structure */
+   unsigned int         end;                 /* address beyond end */
+} tdesc_hdr_t;
+
+
+typedef struct tdesc_chunk_hdr {
+   int                  zeroes : 8;
+   int                  info_length : 22;
+   int                  info_alignment : 2;
+   unsigned int         info_protocol;
+   dc_word_t               start_address;
+   dc_word_t               end_address;
+} tdesc_chunk_hdr_t;
+
+
+typedef struct tdesc_chunk_info1 {
+   int                  variant : 8;         /* 1 for this structure */
+   int                  register_save_mask : 17;
+   int                  pad1 : 1;
+   int                  return_address_info_discriminant : 1;
+   int                  frame_address_register : 5;
+   unsigned int         frame_address_offset;
+   unsigned int         return_address_info;
+   unsigned int         register_save_offset;
+} tdesc_chunk_info1_t;
+
+
+typedef struct tdesc_chunk1 {
+   tdesc_chunk_hdr_t    hdr;
+   tdesc_chunk_info1_t  info;
+} tdesc_chunk1_t;
+
+
+typedef struct dc_mstate {
+   dc_word_t reg[32];                      /* general registers */
+   dc_word_t xip;
+   dc_word_t nip;
+   dc_word_t fip;
+   dc_word_t fpsr;
+   dc_word_t fpcr;
+   dc_word_t psr;
+} dc_mstate_t;
+
+
+typedef struct dc_map_info_in {
+   dc_word_t flags;
+   dc_word_t preceding_tdesc_end;
+   dc_word_t following_tdesc_start;
+} dc_map_info_in_t;
+
+
+typedef struct dc_map_info_out {
+   dc_word_t flags;
+   dc_word_t entry_point;
+   dc_word_t prologue_end;
+   dc_word_t epilogue_start;
+} dc_map_info_out_t;
+
+
+#if 0
+
+   void error_fcn (env, continuable, message)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_boolean_t continuable;            /* whether error function may return */
+      char *message;                    /* string (no trailing newline) */
+
+   /* In the future, we probably want the error_fcn to be: */
+   void error_fcn (env, continuable, code, ...)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_boolean_t continuable;            /* whether error function may return */
+      int code;                         /* error code */
+      ...                               /* parameters to message associated
+                                           with the code */
+
+   void read_fcn (env, memory, length, buffer)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_word_t memory;                    /* start address in image */
+      int length;                       /* in bytes */
+      char *buffer;                     /* start address of buffer */
+      /* There are no alignment assumptions for the read function. */
+
+   void write_fcn (env, memory, length, buffer)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_word_t memory;                    /* start address in image */
+      int length;                       /* in bytes */
+      char *buffer;                     /* start address of buffer */
+      /* There are no alignment assumptions for the write function. */
+      /* The write function is optional.  It must be provided if changes
+         to writable registers are to be made. */
+
+   void exec_fcn (env, mstate)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_mstate_t *mstate;              /* machine state (read-write) */
+      /* The execute function is optional.  It would be used (in the future)
+         by the implementation of a procedurally specified tdesc mechanism. */
+
+#endif
+
+/*----------------*/
+
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+extern char *malloc();
+extern char *calloc();
+extern void qsort();
+
+
+/*
+   At initialization, create a tdesc table from the tdesc info.
+   A tdesc table is simply a sorted array of tdesc elements.
+   A tdesc element is the last 6 words of the tdesc chunk.
+   We require that all tdesc chunks have info protocol 1.
+*/
+
+typedef struct tdesc_elem {
+   dc_word_t start_address;
+   dc_word_t end_address;
+   tdesc_chunk_info1_t info;
+} tdesc_elem_t;
+
+typedef tdesc_elem_t *tdesc_table_t;
+
+void dc_correct_cr_data();
+
+int dc_compare_tdesc_elems (elem1, elem2)
+   char *elem1, *elem2;
+{
+   dc_word_t s1, s2, e1, e2;
+   s1 = ((tdesc_elem_t *) elem1)->start_address;
+   s2 = ((tdesc_elem_t *) elem2)->start_address;
+   if (s1 < s2) return -1;
+   if (s1 > s2) return +1;
+   e1 = ((tdesc_elem_t *) elem1)->end_address;
+   e2 = ((tdesc_elem_t *) elem2)->end_address;
+   if (e1 < e2) return -1;
+   if (e1 > e2) return +1;
+   return 0;
+}
+
+
+typedef struct handle_info {
+   dc_word_t debug_info_ptr;
+   void (*error_fcn)();
+   dc_word_t error_env;
+   void (*read_fcn)();
+   dc_word_t read_env;
+   void (*write_fcn)();                 /* NULL => absent */
+   dc_word_t write_env;
+   void (*exec_fcn)();                  /* NULL => absent */
+   dc_word_t exec_env;
+   void (*map_fcn)();                  /* NULL => absent */
+   dc_word_t map_env;
+   tdesc_table_t tdesc_table;
+   int tdesc_table_size;
+} handle_info_t;
+
+typedef handle_info_t *dc_handle_t;
+
+
+/*
+   Errors detected in this module are funnelled through dc_error or dc_warn,
+   as appropriate.  Both routines call dc_exception, which invokes the error
+   handler supplied by the user.
+
+   Currently, dc_exception substitutes parameters into the message given
+   it and passes the resulting string to the user error handler.
+   In the future, dc_exception should simply pass an error code and
+   the parameters on to the user error handler.
+*/
+
+#include <varargs.h>
+extern int vsprintf();
+
+/* Exit status for exception-processing machinery failure */
+#define DC_EXCEPTION_FAILURE    250
+
+void dc_exception(continuable, args)
+   dc_boolean_t continuable;
+   va_list args;
+{
+   dc_handle_t handle;
+   char *format;
+   char buffer[1024];
+
+   handle = va_arg(args, dc_handle_t);
+   format = va_arg(args, char *);
+   (void) vsprintf(buffer, format, args);
+   (*(handle->error_fcn)) (handle->error_env, continuable, buffer);
+   if (!continuable)
+      exit(DC_EXCEPTION_FAILURE);  /* User error handler should never return in this case. */
+}
+
+
+void dc_error(va_alist)  /* (handle, format, args... ) */
+   va_dcl
+{
+   va_list args;
+
+   va_start(args);
+   dc_exception(DC_FALSE, args);
+   va_end(args);
+}
+
+
+void dc_warn(va_alist)  /* (handle, format, args... ) */
+   va_dcl
+{
+   va_list args;
+
+   va_start(args);
+   dc_exception(DC_TRUE, args);
+   va_end(args);
+}
+
+
+
+#define MALLOC_FAILURE_MESSAGE "Heap space exhausted (malloc failed)."
+#define CALLOC_FAILURE_MESSAGE "Heap space exhausted (Calloc failed)."
+
+
+/* Commonize memory allocation call so failure diagnosis is easier */
+
+char* dc_malloc( handle, size )
+    dc_handle_t handle;
+    int         size;
+{
+    char* space = malloc( size );
+    if (space == (char *)NULL)
+        dc_error( handle, MALLOC_FAILURE_MESSAGE );
+
+    return space;
+}
+
+
+/* Commonize memory allocation call so failure diagnosis is easier */
+
+char* dc_calloc( handle,nelem, size )
+    dc_handle_t handle;
+    int         nelem;
+    int                size;
+{
+    char* space = calloc( nelem, size );
+    if (space == (char *)NULL)
+        dc_error( handle, CALLOC_FAILURE_MESSAGE );
+
+    return space;
+}
+
+
+dc_word_t dc_read_word (handle, address)
+   dc_handle_t handle;
+   dc_word_t address;
+{
+   dc_word_t word;
+   (*(handle->read_fcn)) (handle->read_env, address,
+                          sizeof(dc_word_t), (char *)(&(word)));
+   return word;
+}
+
+
+void dc_write_word (handle, address, value)
+   dc_handle_t handle;
+   dc_word_t address;
+   dc_word_t value;
+{
+   dc_word_t word;
+   word = value;
+   if (handle->write_fcn) {
+      (*(handle->write_fcn)) (handle->write_env, address,
+                              sizeof(dc_word_t), (char *)(&(word)));
+   } else {
+      dc_error (handle, "Writing is disabled.");
+   }
+}
+
+
+void dc_write_masked_word (handle, address, mask, value)
+   dc_handle_t handle;
+   dc_word_t address;
+   dc_word_t mask;
+   dc_word_t value;
+{
+   dc_write_word (handle, address,
+      (value & mask) | (dc_read_word(handle, address) & ~mask));
+}
+
+
+dc_handle_t dc_initiate (debug_info_ptr,
+                        error_fcn, error_env,
+                         read_fcn, read_env,
+                         write_fcn, write_env,
+                         exec_fcn, exec_env,
+                         map_fcn, map_env)
+   dc_word_t debug_info_ptr;
+   void (*error_fcn)();
+   dc_word_t error_env;
+   void (*read_fcn)();
+   dc_word_t read_env;
+   void (*write_fcn)();                 /* NULL => absent */
+   dc_word_t write_env;
+   void (*exec_fcn)();                  /* NULL => absent */
+   dc_word_t exec_env;
+   void (*map_fcn)();                  /* NULL => absent */
+   dc_word_t map_env;
+   /* write_fcn may be given as NULL if no writing is required. */
+   /* exec_fcn may be given as NULL if no execution is required.
+      Currently, no execution is required.  It would be if the
+      implementation needed to invoke procedures in the debugged process. */
+{
+   dc_handle_t handle;
+   unsigned int debug_info_protocol;
+   dc_debug_info_t debug_info;
+   unsigned int tdesc_map_protocol;
+   tdesc_hdr_t tdesc_hdr;
+   dc_word_t tdesc_info_start;
+   dc_word_t tdesc_info_end;
+   dc_word_t tdesc_info_length;
+
+   /* Set up handle enough for dc_error. */
+   handle = (dc_handle_t) malloc(sizeof(handle_info_t));
+   /* Cant use dc_malloc() as handle is being created ... */
+   /* if (handle == NULL) (*error_fcn)( error_env, MALLOC_FAILURE_MESSAGE ) */
+   handle->error_fcn = error_fcn;
+   handle->error_env = error_env;
+   handle->read_fcn = read_fcn;
+   handle->read_env = read_env;
+   handle->write_fcn = write_fcn;
+   handle->write_env = write_env;
+   handle->exec_fcn = exec_fcn;
+   handle->exec_env = exec_env;
+/****************************************************************/
+/* BUG 9/19/89 Found by hls.  Map functions not initialized.    */
+/****************************************************************/
+   handle->map_fcn = map_fcn;
+   handle->map_env = map_env;
+   handle->debug_info_ptr = debug_info_ptr;
+   handle->tdesc_table = (tdesc_table_t)NULL;
+
+   /* Find tdesc info. */
+   if (debug_info_ptr) {
+      (*read_fcn) (read_env, debug_info_ptr, sizeof(unsigned int),
+                  (char *)(&debug_info_protocol));
+      if (debug_info_protocol != 1)
+        dc_error (handle, "Unrecognized debug info protocol: %d",
+                  debug_info_protocol);
+      (*read_fcn) (read_env, debug_info_ptr, sizeof(dc_debug_info_t),
+                  (char *)(&debug_info));
+      (*read_fcn) (read_env, debug_info.tdesc_ptr, sizeof(unsigned int),
+                  (char *)(&tdesc_map_protocol));
+      if (tdesc_map_protocol != 1)
+        dc_error (handle, "Unrecognized tdesc map protocol: %d",
+                  tdesc_map_protocol);
+      (*read_fcn) (read_env, debug_info.tdesc_ptr, sizeof(tdesc_hdr_t),
+                  (char *)(&tdesc_hdr));
+      tdesc_info_start = debug_info.tdesc_ptr + sizeof(tdesc_hdr_t);
+      tdesc_info_end = tdesc_hdr.end;
+      tdesc_info_length = tdesc_info_end - tdesc_info_start;
+
+      /* Create tdesc table from tdesc info. */
+      {
+        /* Over-allocate in order to avoid second pass over tdesc info. */
+        tdesc_table_t tt = (tdesc_table_t) dc_malloc(handle, tdesc_info_length);
+        dc_word_t p = tdesc_info_start;
+        dc_word_t q = tdesc_info_end - sizeof(tdesc_chunk1_t);
+        int n = 0;
+        tdesc_chunk1_t chunk;
+        dc_word_t start_address, end_address;
+        int i;
+
+        for (; p <= q; ) {
+           (*read_fcn) (read_env, p, sizeof(tdesc_chunk1_t), (char *)(&chunk));
+           if (chunk.hdr.zeroes != 0) {
+              /* Skip padding. */
+              p += sizeof(dc_word_t);
+              continue;
+           }
+           if (chunk.hdr.info_protocol != 1) {
+              dc_warn (handle, "Unrecognized tdesc info protocol: %d",
+                        chunk.hdr.info_protocol);
+              goto next_chunk;
+           }
+           if (chunk.hdr.info_length != 16) {
+              dc_warn (handle, "Incorrect tdesc info length: %d",
+                        chunk.hdr.info_length);
+              goto next_chunk;
+           }
+           if (chunk.hdr.info_alignment > 2) {
+              dc_warn (handle, "Incorrect tdesc info alignment: %d",
+                        chunk.hdr.info_alignment);
+              goto next_chunk;
+           }
+           start_address = chunk.hdr.start_address;
+           end_address = chunk.hdr.end_address;
+           if ((start_address&3)!=0) {
+              dc_warn (handle,
+                 "Tdesc start address is not word-aligned: %#.8X",
+                 start_address);
+              goto next_chunk;
+           }
+           if ((end_address&3)!=0) {
+              dc_warn (handle,
+                 "Tdesc end address is not word-aligned: %#.8X",
+                 end_address);
+              goto next_chunk;
+           }
+           if (start_address > end_address) {
+                    /* Note that the range may be null. */
+              dc_warn (handle,
+                 "Tdesc start address (%#.8X) follows end address (%#.8X).",
+                 start_address, end_address);
+              goto next_chunk;
+           }
+           if (chunk.info.variant != 1) {
+              dc_warn (handle, "Invalid tdesc chunk variant: %d",
+                 chunk.info.variant);
+              goto next_chunk;
+           }
+           if (chunk.info.pad1 != 0) {
+              dc_warn (handle, "Tdesc chunk padding is not zero.");
+              goto next_chunk;
+           }
+           if (chunk.info.return_address_info_discriminant != 0) {
+              if ((chunk.info.return_address_info & 3) != 0) {
+                 dc_warn (handle,
+                    "Tdesc return address offset is not word-aligned: %#.8X",
+                    chunk.info.return_address_info);
+                 goto next_chunk;
+              }
+           } else {
+              if ((chunk.info.return_address_info & ~31) != 0) {
+                 dc_warn (handle,
+                    "Invalid tdesc return address register: %d",
+                    chunk.info.return_address_info);
+                 goto next_chunk;
+              }
+           }
+           if ((chunk.info.register_save_offset & 3) != 0) {
+              dc_warn (handle,
+                 "Tdesc register save offset is not word-aligned: %#.8X",
+                 chunk.info.register_save_offset);
+              goto next_chunk;
+           }
+
+           tt[n].start_address = start_address;
+           tt[n].end_address = end_address;
+           tt[n].info = chunk.info;
+           n++;
+
+   next_chunk:
+           p += sizeof(tdesc_chunk1_t);
+        }
+        /* Leftover (less than a tdesc_chunk1_t in size) is padding or
+           in error.  Ignore it in either case. */
+
+        if (n != 0) {
+
+                /* Sort table by start address. */
+                qsort ((char *)tt, n, sizeof(tdesc_elem_t), dc_compare_tdesc_elems);
+
+                /* Check for overlap among tdesc chunks. */
+                for (i=0; i<(n-1); i++) {
+                   if (tt[i].end_address > tt[i+1].start_address)
+                      dc_error (handle, "Text chunks overlap.");
+                }
+        }
+
+        /* Finish setting up handle. */
+        handle->tdesc_table = tt;
+        handle->tdesc_table_size = n;
+      }
+   } else {
+      handle->tdesc_table_size = 0;
+   }
+
+   return (dc_handle_t) handle;
+}
+
+
+void dc_terminate (handle)
+   dc_handle_t handle;
+{
+   if (((dc_handle_t)handle)->tdesc_table) {
+      free((char *)(((dc_handle_t)handle)->tdesc_table));
+   }
+   free((char *)handle);
+}
+
+
+
+/*
+
+   Dcontext Model
+
+   For each interesting register (word-sized piece of machine state),
+   a word of value information is kept.  This word may
+   be either the value of the register, or the address in
+   subject memory where the value can be found (and changed).  In
+   addition, the register may be invalid (in which case the value
+   information is undefined).  These three cases are encoded for
+   a given register in the same-numbered bit of two words of flags:
+
+      flags[0] bit  flags[1] bit  meaning
+      ------------  ------------  -------
+            0             0       register is invalid; info is undefined
+            0             1       register is readable; info is value
+            1             0       register is writable; info is address
+            1             1       (reserved)
+
+   The general registers (r0-r31) are handled by reg_info and
+   reg_flags.  The bit number for a register is that register's number.
+   The other registers are grouped together for convenience and are
+   handled by aux_info and aux_flags.  The bit numbers for these
+   registers are:
+
+      bit number     register
+      ----------     --------
+           0         location
+           1         SXIP
+           2         SNIP
+           3         SFIP
+           4         FPSR
+           5         FPCR
+
+   The SXIP, SNIP, and SFIP are the exception-time values of the
+   XIP, NIP, and FIP registers.  They are valid only in the topmost frame.
+   (That is, in any context obtained from dc_previous_context, they
+   are invalid.)
+
+   "location" is a pseudo-register of this model and represents the
+   location of the context.  It is always valid.  It also has an
+   exactness associated with it.  The location and its exactness of a
+   context obtained from dc_previous_context are taken from the
+   return address and its exactness of the context given as an argument
+   to dc_previous_context.
+
+   The following model is recommended for dealing with the partial
+   redundancy between location and the SXIP, SNIP, and SFIP values
+   in the topmost frame.  The location should be set to either the
+   SNIP or SXIP value, and its exactness should be set to DC_NO.  A
+   change to the register whose value the location is set to should
+   be accompanied by an identical change to the location.
+
+   The PSR is handled separately, because it is a diverse collection
+   of flags.  The PSR, as a whole, is always valid.  A separate
+   psr_ind flag tells whether the psr_info data is a value or
+   an address.  Each bit of the PSR has its own pair of flag bits to
+   mark validity and writability.
+
+*/
+
+
+/* The following value means "other", because state is stored in 2 bits. */
+#define DC_RESERVED 3
+
+
+#define RSTATE(flags, bit) \
+   ((bit_value((flags)[0], bit) << 1) + bit_value((flags)[1], bit))
+
+#define REG_STATE(dcontext, reg) RSTATE(dcontext->reg_flags, reg)
+#define AUX_STATE(dcontext, reg) RSTATE(dcontext->aux_flags, reg)
+#define PSR_STATE(dcontext, reg) RSTATE(dcontext->psr_flags, reg)
+
+
+#define SET_INVALID(flags, bit) \
+   { bit_clear ((flags)[0], bit); bit_clear ((flags)[1], bit); }
+
+#define SET_READABLE(flags, bit) \
+   { bit_clear ((flags)[0], bit); bit_set   ((flags)[1], bit); }
+
+#define SET_WRITABLE(flags, bit) \
+   { bit_set   ((flags)[0], bit); bit_clear ((flags)[1], bit); }
+
+#define ASSIGN_RSTATE(to_flags, to_bit, from_flags, from_bit) \
+   { bit_assign ((to_flags)[0], to_bit, bit_value((from_flags)[0], from_bit));\
+     bit_assign ((to_flags)[1], to_bit, bit_value((from_flags)[1], from_bit));}
+
+
+#define CHECK_REG_READ(dcontext, reg) \
+   if (REG_STATE(dcontext, reg) == DC_INVALID) \
+      dc_error (dcontext->handle, \
+         "General register %d is not readable.", reg)
+
+#define CHECK_REG_WRITE(dcontext, reg) \
+   if (REG_STATE(dcontext, reg) != DC_WRITABLE) \
+      dc_error (dcontext->handle, \
+         "General register %d is not writable.", reg)
+
+#define CHECK_AUX_READ(dcontext, reg) \
+   if (AUX_STATE(dcontext, reg) == DC_INVALID) \
+      dc_error (dcontext->handle, \
+         "Auxiliary register %d is not readable.", reg)
+
+#define CHECK_AUX_WRITE(dcontext, reg) \
+   if (AUX_STATE(dcontext, reg) != DC_WRITABLE) \
+      dc_error (dcontext->handle, \
+         "Auxiliary register %d is not writable.", reg)
+
+
+
+#define DC_REG_RA   1
+#define DC_REG_FP  30
+#define DC_REG_SP  31
+#define DC_NUM_REG 32
+
+#define DC_AUX_LOC  0
+   /* DC_AUX_LOC must be first, with value 0 */
+#define DC_AUX_SXIP 1
+#define DC_AUX_SNIP 2
+#define DC_AUX_SFIP 3
+#define DC_AUX_FPSR 4
+#define DC_AUX_FPCR 5
+#define DC_NUM_AUX  6
+
+
+
+#define CHECK_REG(dcontext, reg) \
+   if ((reg < 0) || (reg >= DC_NUM_REG)) \
+      dc_error (dcontext->handle, \
+         "Bad general register number: %d", reg)
+
+#define CHECK_AUX(dcontext, reg) \
+   if ((reg < 1) || (reg >= DC_NUM_AUX)) \
+      dc_error (dcontext->handle, \
+         "Bad auxiliary register number: %d", reg)
+   /* CHECK_AUX is not used for location pseudo-register. */
+
+#define CHECK_BIT(dcontext, bit) \
+   if ((bit < 0) || (bit >= 32)) \
+      dc_error (dcontext->handle, \
+         "Bad bit number: %d", bit)
+
+
+
+typedef struct cr_value {
+   int reg;
+   unsigned int off;
+ } dc_cr_value_t;
+
+#define DC_UNDEF 32
+
+/*
+   A "dc_cr_value" represents an execution-time value symbolically, in
+   terms of the initial value of a register (the value on entry to
+   the procedure being analyzed) and a known offset.  A value with
+   a 'reg' field value of 0 through 31 represents the value obtained
+   by summing (using 32-bit modulus arithmetic) the initial value of
+   register 'reg' and the value 'off'.  Note that the value (0,k)
+   represents the constant value k, that (31,0) represents the CFA, and
+   that (1,0) represents the return address.  A value with a 'reg' field
+   of DC_UNDEF represents an indeterminable value; in this case the
+   'off' field is undefined.  Other values of 'reg' are erroneous.
+*/
+
+typedef struct cr_data {
+   dc_cr_value_t reg_val[DC_NUM_REG];
+   dc_word_t saved;
+   dc_word_t how;
+   unsigned int where[DC_NUM_REG];
+} dc_cr_data_t;
+
+/*
+   'cr_data' collects all the information needed to represent the
+   symbolic machine state during code reading.
+
+   The 'reg_val' array gives the current dc_cr_value for each register.
+   
+   The 'saved', 'how', and 'where' fields combine to describe what
+   registers have been saved, and where.  The 'saved' and 'how' fields
+   are implicitly bit arrays over 0..31, where the numbering is from
+   0 on the right.  (Hence, 1<<r gives the mask for register r.)
+   If saved[r] is 0, the register is not saved, and how[r] and where[r]
+   are undefined.  If saved[r] is 1, then how[r] tells whether register r
+   was saved in another register (how[r]==0) or in the frame (how[r]==1).
+   In the former case, where[r] gives the register number; in the latter
+   case, where[r] gives the frame position.
+*/
+
+
+typedef int dc_register_state_t;    /* range 0 to 2 */
+
+#define DC_INVALID  0
+#define DC_READABLE 1
+#define DC_WRITABLE 2
+
+
+
+
+typedef struct dcontext_info {
+   dc_handle_t handle;                     /* environment of context */
+   dc_word_t reg_info[DC_NUM_REG];
+   dc_word_t reg_flags[2];
+   dc_word_t aux_info[DC_NUM_AUX];
+   dc_word_t aux_flags[2];
+   dc_exactness_t loc_exact;
+   dc_word_t psr_info;                     /* value or address */
+   dc_word_t psr_ind;                      /* DC_TRUE iff address */
+   dc_word_t psr_flags[2];                 /* per-PSR-bit flags */
+   unsigned int code_reading;                 /* no tdesc therefore must read code*/
+        union {
+          tdesc_elem_t *tdesc_elem_ptr;       /* locates tdesc chunk */
+          dc_cr_data_t *cr_data_ptr;          /* or code reading data */
+        } info_ptr;
+} dcontext_info_t;
+
+typedef dcontext_info_t *dc_dcontext_t;
+
+dc_word_t dc_get_value (handle, info, flags, pos)
+   dc_handle_t handle;
+   dc_word_t info[];
+   dc_word_t flags[2];
+   int pos;
+   /* Assumes either DC_READABLE or DC_WRITABLE. */
+{
+   if (bit_test(flags[0], pos)) {
+      /* DC_WRITABLE case */
+      return dc_read_word(handle, info[pos]);
+   } else {
+      /* DC_READABLE case */
+      return info[pos];
+   }
+}
+
+void dc_set_value (handle, info, flags, pos, value)
+   dc_handle_t handle;
+   dc_word_t info[];
+   dc_word_t flags[2];
+   int pos;
+   dc_word_t value;
+   /* Assumes DC_WRITABLE. */
+{
+   dc_write_word(handle, info[pos], value);
+}
+
+
+#define GET_REG_VALUE(dcontext, reg) \
+   dc_get_value(dcontext->handle, dcontext->reg_info, dcontext->reg_flags, reg)
+
+#define SET_REG_VALUE(dcontext, reg, value) \
+   dc_set_value(dcontext->handle, dcontext->reg_info, dcontext->reg_flags, reg, \
+      value)
+
+#define GET_AUX_VALUE(dcontext, reg) \
+   dc_get_value(dcontext->handle, dcontext->aux_info, dcontext->aux_flags, reg)
+
+#define SET_AUX_VALUE(dcontext, reg, value) \
+   dc_set_value(dcontext->handle, dcontext->aux_info, dcontext->aux_flags, reg, \
+      value)
+
+
+
+void dc_check_dcontext (dc)
+   dc_dcontext_t dc;
+   /* Check consistency of information supplied to make a dcontext. */
+{
+   int i;
+
+   if ((REG_STATE(dc, 0) != DC_READABLE) || (dc->reg_info[0] != 0))
+      dc_error (dc->handle, "Register 0 is misspecified");
+   for (i = 1; i < DC_NUM_REG; i++)
+      if (REG_STATE(dc, i) == DC_RESERVED)
+         dc_error (dc->handle,
+            "State for general register %d is incorrect", i);
+   for (i = 0; i < DC_NUM_AUX; i++)
+      if (AUX_STATE(dc, i) == DC_RESERVED)
+         dc_error (dc->handle,
+            "State for auxiliary register %d is incorrect", i);
+   if (AUX_STATE(dc, DC_AUX_LOC) == DC_INVALID)
+      dc_error (dc->handle, "Location is specified as invalid");
+   if (GET_AUX_VALUE(dc, DC_AUX_LOC) == 0)
+      dc_error (dc->handle, "Location is zero.");
+   if (dc->loc_exact >= 3)
+      dc_error (dc->handle, "Location exactness is incorrectly specified: %d",
+         dc->loc_exact);
+   if (dc->psr_ind >= 2)
+      dc_error (dc->handle,
+         "PSR indirection flag is incorrectly specified: %d",
+         dc->psr_ind);
+   for (i = 0; i < 32; i++)
+      if (PSR_STATE(dc, i) == DC_RESERVED)
+         dc_error (dc->handle, "State for PSR bit %d is incorrect", i);
+}
+
+
+
+tdesc_elem_t * dc_tdesc_lookup (loc, tt, tt_size, map_info_in_ptr)
+   dc_word_t loc;
+   tdesc_table_t tt;
+   int tt_size;
+   dc_map_info_in_t *map_info_in_ptr;
+   /* Return address of tdesc_elem_t for given location, or NULL if
+      there is no tdesc chunk for the location.
+   */
+{
+   int l = 0;
+   int h = tt_size;
+   int m;
+
+   if (tt_size == 0) {
+      map_info_in_ptr->flags = 0;
+      return (tdesc_elem_t *)NULL;
+   }
+   for (;;) {
+      m = (l + h) / 2;
+      if (m == l) break;
+      if (loc >= tt[m].start_address)
+         l = m;
+      else
+         h = m;
+   }
+   if (loc >= tt[m].end_address) {
+      map_info_in_ptr->preceding_tdesc_end = tt[m].end_address;
+      if (m+1 < tt_size) {
+        map_info_in_ptr->following_tdesc_start = tt[m+1].start_address;
+        map_info_in_ptr->flags = DC_MII_PRECEDING_TDESC_END |
+                                 DC_MII_FOLLOWING_TDESC_START;
+      } else {
+        map_info_in_ptr->flags = DC_MII_PRECEDING_TDESC_END;
+      }
+      return (tdesc_elem_t *)NULL;
+   } else if (loc < tt[m].start_address) {
+      map_info_in_ptr->following_tdesc_start = tt[m].start_address;
+      map_info_in_ptr->flags = DC_MII_FOLLOWING_TDESC_START;
+      return (tdesc_elem_t *)NULL;
+   } else {
+      return (&tt[m]);
+   }
+}
+
+
+
+dc_dcontext_t dc_make_dcontext (handle,
+                                reg_info, reg_flags,
+                                aux_info, aux_flags, loc_exact,
+                                psr_info, psr_ind, psr_flags)
+   dc_handle_t handle;
+   dc_word_t reg_info[DC_NUM_REG];
+   dc_word_t reg_flags[2];
+   dc_word_t aux_info[DC_NUM_AUX];
+   dc_word_t aux_flags[2];
+   dc_exactness_t loc_exact;
+   dc_word_t psr_info;
+   dc_boolean_t psr_ind;
+   dc_word_t psr_flags[2];
+{
+   dc_dcontext_t dc = (dc_dcontext_t) dc_malloc (handle, sizeof(dcontext_info_t));
+   int i;
+   dc_map_info_in_t map_info_in;
+
+   /* Fill in supplied content. */
+   dc->handle = ((dc_handle_t)handle);
+   for (i = 0; i < DC_NUM_REG; i++) dc->reg_info[i]  = reg_info[i];
+   for (i = 0; i < 2; i++)       dc->reg_flags[i] = reg_flags[i];
+   for (i = 0; i < DC_NUM_AUX; i++) dc->aux_info[i]  = aux_info[i];
+   for (i = 0; i < 2; i++)       dc->aux_flags[i] = aux_flags[i];
+   dc->loc_exact = loc_exact;
+   dc->psr_info = psr_info;
+   dc->psr_ind = psr_ind;
+   for (i = 0; i < 2; i++)       dc->psr_flags[i] = psr_flags[i];
+
+   dc_check_dcontext(dc);
+
+   /* Find tdesc information for the text chunk. */
+   {
+/***************************************************************/
+/* BUG 8/16/89 Found by hls.  Not zeroing EV bits of location. */
+/*                            SHOULD USE dc_location()!        */
+/*      dc_word_t loc = GET_AUX_VALUE(dc, DC_AUX_LOC);         */
+/***************************************************************/
+      dc_word_t loc = GET_AUX_VALUE(dc, DC_AUX_LOC) & ~3;
+      tdesc_elem_t *tep =
+         dc_tdesc_lookup(loc, ((dc_handle_t)handle)->tdesc_table,
+             ((dc_handle_t)handle)->tdesc_table_size,&map_info_in);
+      if (tep) {
+                dc->code_reading = 0;
+         dc->info_ptr.tdesc_elem_ptr = tep;
+      } else {
+         dc->code_reading = 1;
+         if (!dc->handle->map_fcn) {
+             dc_error (dc->handle, "No tdesc information for %#.8X and no map function supplied.",loc);
+         }
+/****************************************************************/
+/* BUG 9/18/89 Found by hls.  Not using dc_malloc()             */
+/* dc->info_ptr.cr_data_ptr= (dc_cr_data_t *)malloc(sizeof(dc_cr_data_t )); */
+/****************************************************************/
+         dc->info_ptr.cr_data_ptr= (dc_cr_data_t *)dc_calloc(dc->handle,1,sizeof(dc_cr_data_t ));
+         dc_read_code(loc,dc,map_info_in,dc->info_ptr.cr_data_ptr);
+      }
+   }
+
+   return (dc_dcontext_t) dc;
+}
+
+
+
+void dc_free_dcontext (dcontext)
+   dc_dcontext_t dcontext;
+{
+/****************************************************************/
+/* BUG 9/19/89 Found by hls.  Freeing non-pointer value.        */
+/*       free((char *)dcontext->code_reading);                 */
+/****************************************************************/
+   if (dcontext->code_reading)
+         free((char *)dcontext->info_ptr.cr_data_ptr);
+   free((char *)dcontext);
+}
+
+
+
+dc_register_state_t dc_location_state (dcontext)
+   dc_dcontext_t dcontext;
+{
+   return AUX_STATE(((dc_dcontext_t)dcontext), DC_AUX_LOC);
+}
+
+
+dc_exactness_t dc_location_exactness (dcontext)
+   dc_dcontext_t dcontext;
+{
+   return ((dc_dcontext_t)dcontext)->loc_exact;
+}
+
+
+dc_word_t dc_location (dcontext)
+   dc_dcontext_t dcontext;
+   /* Return high 30 bits only. */
+{
+   /* Don't need: CHECK_AUX_READ (((dc_dcontext_t)dcontext), DC_AUX_LOC); */
+   return GET_AUX_VALUE (((dc_dcontext_t)dcontext), DC_AUX_LOC) & ~3;
+}
+
+
+dc_boolean_t dc_location_in_text_chunk( dcontext, value )
+   dc_dcontext_t dcontext;
+   dc_word_t value;
+{
+   /* Check that new location is still within same text chunk. */
+   tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr;
+/********************************************************************/
+/* Bug in predicate -- LS adjusted according to OCS documentation.. */
+/*  if ((value < tep->start_address) || (value >= tep->end_address))*/
+/********************************************************************/
+   if ((value >= tep->start_address) && (value < tep->end_address))
+        return DC_TRUE;
+    else
+        return DC_FALSE;
+
+}
+
+
+void dc_set_location (dcontext, value)
+   dc_dcontext_t dcontext;
+   dc_word_t value;
+   /* Set high 30 bits only. */
+{
+   if (dc_location_in_text_chunk( dcontext, value ) != DC_TRUE)
+      dc_warn (((dc_dcontext_t)dcontext)->handle,
+         "New location is not in same text chunk.");
+
+   CHECK_AUX_WRITE (((dc_dcontext_t)dcontext), DC_AUX_LOC);
+   dc_write_masked_word (((dc_dcontext_t)dcontext)->handle,
+      ((dc_dcontext_t)dcontext)->aux_info[DC_AUX_LOC], ~3, value);
+}
+
+
+
+dc_register_state_t dc_general_register_state (dcontext, reg)
+   dc_dcontext_t dcontext;
+   int reg;
+{
+   CHECK_REG (((dc_dcontext_t)dcontext), reg);
+   return REG_STATE(((dc_dcontext_t)dcontext), reg);
+}
+
+
+dc_word_t dc_general_register (dcontext, reg)
+   dc_dcontext_t dcontext;
+   int reg;
+{
+   CHECK_REG (((dc_dcontext_t)dcontext), reg);
+   CHECK_REG_READ (((dc_dcontext_t)dcontext), reg);
+   return GET_REG_VALUE(((dc_dcontext_t)dcontext), reg);
+}
+
+
+void dc_set_general_register (dcontext, reg, value)
+   dc_dcontext_t dcontext;
+   int reg;
+   dc_word_t value;
+{
+   CHECK_REG (((dc_dcontext_t)dcontext), reg);
+   CHECK_REG_WRITE (((dc_dcontext_t)dcontext), reg);
+   SET_REG_VALUE (((dc_dcontext_t)dcontext), reg, value);
+}
+
+
+
+dc_register_state_t dc_auxiliary_register_state (dcontext, reg)
+   dc_dcontext_t dcontext;
+   int reg;
+{
+   CHECK_AUX (((dc_dcontext_t)dcontext), reg);
+   return AUX_STATE(((dc_dcontext_t)dcontext), reg);
+}
+
+
+dc_word_t dc_auxiliary_register (dcontext, reg)
+   dc_dcontext_t dcontext;
+   int reg;
+{
+   CHECK_AUX (((dc_dcontext_t)dcontext), reg);
+   CHECK_AUX_READ (((dc_dcontext_t)dcontext), reg);
+   return GET_AUX_VALUE(((dc_dcontext_t)dcontext), reg);
+}
+
+
+void dc_set_auxiliary_register (dcontext, reg, value)
+   dc_dcontext_t dcontext;
+   int reg;
+   dc_word_t value;
+{
+   CHECK_AUX (((dc_dcontext_t)dcontext), reg);
+   CHECK_AUX_WRITE (((dc_dcontext_t)dcontext), reg);
+   SET_AUX_VALUE (((dc_dcontext_t)dcontext), reg, value);
+}
+
+
+
+dc_register_state_t dc_psr_register_bit_state (dcontext, bit)
+   dc_dcontext_t dcontext;
+   int bit;
+{
+   CHECK_BIT (((dc_dcontext_t)dcontext), bit);
+   return PSR_STATE(((dc_dcontext_t)dcontext), bit);
+}
+
+
+dc_word_t dc_psr_register (dcontext)
+   dc_dcontext_t dcontext;
+{
+   if (((dc_dcontext_t)dcontext)->psr_ind) {
+      return dc_read_word(((dc_dcontext_t)dcontext)->handle,
+                       ((dc_dcontext_t)dcontext)->psr_info);
+   } else {
+      return ((dc_dcontext_t)dcontext)->psr_info;
+   }
+}
+
+
+void dc_set_psr_register (dcontext, mask, value)
+   dc_dcontext_t dcontext;
+   dc_word_t mask;
+   dc_word_t value;
+   /* Set bits of PSR corresponding to 1 bits in mask. */
+{
+   if (((dc_dcontext_t)dcontext)->psr_ind) {
+      if (((((dc_dcontext_t)dcontext)->psr_flags[0] & mask) != mask) ||
+          ((((dc_dcontext_t)dcontext)->psr_flags[1] & mask) != 0))
+         dc_error (((dc_dcontext_t)dcontext)->handle,
+            "Some PSR bits specified are not writable.");
+      dc_write_masked_word (((dc_dcontext_t)dcontext)->handle,
+                         ((dc_dcontext_t)dcontext)->psr_info, mask, value);
+   } else {
+      dc_error (((dc_dcontext_t)dcontext)->handle, "PSR is not writable.");
+   }
+}
+
+
+
+dc_word_t dc_frame_address (dcontext)
+   dc_dcontext_t dcontext;
+{
+  if (!dcontext->code_reading) {
+        tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr;
+        return dc_general_register(dcontext,
+               tep->info.frame_address_register) + tep->info.frame_address_offset;
+  } else {
+        if (dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_FP].reg == DC_REG_SP) {
+               return (dc_general_register(dcontext,DC_REG_FP)
+                       - dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_FP].off);
+        }
+        if (dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_SP].reg == DC_REG_SP) {
+               return (dc_general_register(dcontext,DC_REG_SP)
+                       - dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_SP].off);
+        }
+     dc_error (((dc_dcontext_t)dcontext)->handle, "Cannot locate frame pointer.");
+  }
+}
+
+
+
+dc_kind_t dc_context_kind (dcontext)
+   dc_dcontext_t dcontext;
+{
+   return DC_CALL_KIND;
+}
+
+
+
+
+/* operations valid for call contexts only */
+
+
+dc_register_state_t dc_return_address_state (dcontext)
+   dc_dcontext_t dcontext;
+{
+   tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr;
+   int reg;
+
+   if (!dcontext->code_reading) {
+         if (tep->info.return_address_info_discriminant) {
+                return DC_WRITABLE;
+         } else {
+                return REG_STATE(((dc_dcontext_t)dcontext), tep->info.return_address_info);
+         }
+   } else {
+         reg= DC_REG_RA;
+         if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,DC_REG_RA)) {
+               if (bit_test(dcontext->info_ptr.cr_data_ptr->how,DC_REG_RA)) {
+                  return DC_WRITABLE;
+               } else {
+                  reg= dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA];
+               }
+         }
+               return REG_STATE(((dc_dcontext_t)dcontext),reg);
+
+         
+   }
+}
+
+
+dc_exactness_t dc_return_address_exactness (dcontext)
+   dc_dcontext_t dcontext;
+{
+   return DC_MAYBE;
+}
+
+
+dc_word_t dc_return_address (dcontext)
+   dc_dcontext_t dcontext;
+   /* Return high 30 bits only. */
+{
+   tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr;
+   dc_word_t rai = tep->info.return_address_info;
+   dc_word_t val;
+   int reg;
+
+   if (!dcontext->code_reading) {
+        if (tep->info.return_address_info_discriminant) {
+               val = dc_read_word (((dc_dcontext_t)dcontext)->handle,
+                                                dc_frame_address(dcontext) + rai);
+        } else {
+               val = dc_general_register (dcontext, rai);
+        }
+   } else {
+         reg=DC_REG_RA;
+         if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,reg)) {
+                 if (bit_test(dcontext->info_ptr.cr_data_ptr->how,reg)) {
+                        val = dc_read_word (((dc_dcontext_t)dcontext)->handle,
+                                                  dc_frame_address(dcontext) + 
+                                                   (dcontext->info_ptr.cr_data_ptr->where[reg]));
+                 } else {
+                        reg= dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA];
+                        val = dc_general_register (dcontext, reg);
+                 }
+         } else {
+                val = dc_general_register (dcontext, reg);
+         }
+   }
+        return val & ~3;
+}
+
+
+void dc_set_return_address (dcontext, value)
+   dc_dcontext_t dcontext;
+   dc_word_t value;
+   /* Set high 30 bits only. */
+{
+  if (!dcontext->code_reading) {
+        tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr;
+        dc_word_t rai = tep->info.return_address_info;
+
+        if (tep->info.return_address_info_discriminant) {
+               dc_write_masked_word (((dc_dcontext_t)dcontext)->handle,
+                  dc_frame_address(dcontext) + rai, ~3, value);
+        } else {
+      dc_set_general_register (dcontext, rai,
+         (value & ~3) | (dc_general_register(dcontext, rai) & 3));
+   }
+ } else {
+       if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,DC_REG_RA)) {
+               if (bit_test(dcontext->info_ptr.cr_data_ptr->how,DC_REG_RA)) {
+                  dc_write_masked_word (((dc_dcontext_t)dcontext)->handle,
+                     dc_frame_address(dcontext)
+                          + dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA], ~3, value);
+                 } else {
+                        dc_set_general_register( dcontext,
+                                                                 dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]);
+                 }
+         } else {
+                 dc_set_general_register( dcontext,
+                                                         dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]);
+         }
+   }
+}
+
+
+
+/* operations valid for save contexts only */
+
+/* (none) */
+
+
+
+/* operations valid for exception contexts only */
+
+
+void dc_get_exception_info (dcontext, handler, datum)
+   dc_dcontext_t dcontext;
+   dc_word_t *handler;
+   dc_word_t *datum;
+{
+   dc_error (((dc_dcontext_t)dcontext)->handle,
+      "dc_get_exception_info is not yet implemented.");
+}
+
+
+
+/* operations valid for protection contexts only */
+
+
+void dc_get_protection_info (dcontext, handler, datum)
+   dc_dcontext_t dcontext;
+   dc_word_t *handler;
+   dc_word_t *datum;
+{
+   dc_error (((dc_dcontext_t)dcontext)->handle,
+      "dc_get_protection_info is not yet implemented.");
+}
+
+
+
+/* operations valid for special contexts only */
+
+
+void dc_get_special_info (dcontext, kind, datum)
+   dc_dcontext_t dcontext;
+   dc_word_t *kind;
+   dc_word_t *datum;
+{
+   dc_error (((dc_dcontext_t)dcontext)->handle,
+      "dc_get_special_info is not yet implemented.");
+}
+
+
+
+/* operations valid for all contexts (again) */
+
+
+dc_dcontext_t dc_previous_dcontext (dcontext)
+   dc_dcontext_t dcontext;
+   /* Return NULL if there is no previous context. */
+{
+   dc_dcontext_t old = (dc_dcontext_t) dcontext;
+   dcontext_info_t new;    /* to serve as temporary storage only */
+   tdesc_elem_t *tep;
+       dc_cr_data_t *cdp;
+   dc_word_t cfa;
+   int rsm;
+   dc_word_t offset;
+   dc_word_t rai;
+   int r;
+
+   if (dc_return_address_state((dc_dcontext_t)old) == DC_INVALID)
+      dc_error (old->handle, "Return address is invalid.");
+
+   if (dc_return_address((dc_dcontext_t)old) == 0)
+      return (dc_dcontext_t)NULL;  /* end of the chain */
+
+   /* Copy over old contents. */
+   new = *old;
+
+   cfa = dc_frame_address(old);
+       /* Restore stack pointer. */
+       new.reg_info[DC_REG_SP] = cfa;
+       SET_READABLE (new.reg_flags, DC_REG_SP);
+
+   /* Invalidate temporary registers. */
+   for (r = 1; r <= 13; r++) SET_INVALID (new.reg_flags, r);
+
+       if (!old->code_reading) {
+               tep = old->info_ptr.tdesc_elem_ptr;
+               /* Restore preserved registers. */
+               rsm = tep->info.register_save_mask;
+               offset = cfa + tep->info.register_save_offset;
+               for (r = 14; r <= 30; r++) {
+                       if (bit_test(rsm, 30-r)) {
+                               new.reg_info[r] = offset;
+                               SET_WRITABLE (new.reg_flags, r);
+                               offset += sizeof(dc_word_t);
+                       }
+               }
+
+               /* Set location from old return address. */
+               rai = tep->info.return_address_info;
+               if (tep->info.return_address_info_discriminant) {
+                       new.aux_info[DC_AUX_LOC] = cfa + rai;
+                       SET_WRITABLE (new.aux_flags, DC_AUX_LOC);
+               } else {
+                       new.aux_info[DC_AUX_LOC] = old->reg_info[rai];
+                       ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, old->reg_flags, rai);
+               }
+       } else {
+               cdp = old->info_ptr.cr_data_ptr;
+               
+               /* Restore preserved registers. */
+               for (r = 14; r <= 30; r++) { 
+                       if (bit_test(cdp->saved,r)) {
+                               if (bit_test(cdp->how,r)){ /* saved in the frame */
+                                       new.reg_info[r] = cfa+cdp->where[r];
+                                       SET_WRITABLE (new.reg_flags, r);
+                               } else { /* saved in the in a register */
+                                       new.reg_info[r] = dc_general_register(old,cdp->where[r]);
+                                       ASSIGN_RSTATE (new.aux_flags, r, old->reg_flags, cdp->where[r]);
+                               }
+                       }  /* not saved, therefore, already valid , no else*/
+               }
+
+               /* Set location from old return address. */
+               if (bit_test(cdp->saved,DC_REG_RA)) {
+                       if (bit_test(cdp->how,DC_REG_RA)){ /* saved in the frame */
+                               new.aux_info[DC_AUX_LOC] = 
+                                       new.reg_info[DC_REG_RA] = cfa+cdp->where[DC_REG_RA];
+                               SET_WRITABLE (new.reg_flags, DC_REG_RA);
+                               SET_WRITABLE (new.aux_flags, DC_AUX_LOC);
+                       } else { /* saved in the in a register */
+                               new.reg_info[DC_REG_RA] =
+                                       new.aux_info[DC_AUX_LOC] =
+                                                       dc_general_register(old,cdp->where[DC_REG_RA]);
+                               ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, 
+                                                                       old->reg_flags, cdp->where[DC_REG_RA]);
+                       }
+               } else { /* not saved, therefore, already valid , set DC_AUX_LOC only*/
+                               new.aux_info[DC_AUX_LOC] =
+                                               dc_general_register(old,DC_REG_RA);
+                               ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, 
+                                                                       old->reg_flags, DC_REG_RA);
+               }
+       }
+
+   /* Invalidate instruction pointers. */
+   SET_INVALID (new.aux_flags, DC_AUX_SXIP);
+   SET_INVALID (new.aux_flags, DC_AUX_SNIP);
+   SET_INVALID (new.aux_flags, DC_AUX_SFIP);
+
+   /* No change to FCR registers. */
+
+   /* No change to PSR register. */
+
+   return dc_make_dcontext ((dc_handle_t)new.handle,
+                            new.reg_info, new.reg_flags,
+                            new.aux_info, new.aux_flags, new.loc_exact,
+                            new.psr_info, new.psr_ind, new.psr_flags);
+}
+
+
+
+/* extensions for nonlocal goto */
+
+#if 0
+
+typedef
+   struct label {
+      ???
+   } label_t;
+
+
+label_t dc_make_label (dcontext, location)
+   dc_dcontext_t dcontext;
+   dc_word_t location;
+{
+}
+
+#endif
+
+/* procedure for reading code */
+
+dc_read_code(loc,dc,map_info_in,cdp)
+dc_word_t loc;
+dc_dcontext_t dc;
+dc_cr_data_t *cdp;
+dc_map_info_in_t map_info_in;
+{
+dc_map_info_out_t map_info_out;
+dc_word_t pc;
+dc_boolean_t found_branch=DC_FALSE;
+dc_word_t instr;
+
+       (*dc->handle->map_fcn)(dc->handle->map_env,loc,map_info_in,&map_info_out);
+       if (map_info_out.flags & DC_MIO_ENTRY_POINT 
+               && (!(map_info_in.flags & DC_MII_PRECEDING_TDESC_END)
+                   || map_info_out.entry_point >= map_info_in.preceding_tdesc_end
+                       || map_info_out.flags & DC_MIO_LITERAL_ENTRY_POINT)) {
+          dc_init_cr_data(cdp,(tdesc_elem_t *)NULL);
+          pc= map_info_out.entry_point;
+       } else if (map_info_in.flags & DC_MII_PRECEDING_TDESC_END) { 
+               /**/
+               /* tdesc_lookup gets the tep for the preceeding tdesc information
+               /* so we call it with one less than the preceding tdesc end since
+               /* tdesc information is exclusive of the ending address
+               /**/
+          dc_init_cr_data(cdp, 
+                                          dc_tdesc_lookup(map_info_in.preceding_tdesc_end-1, 
+                                                                       ((dc_handle_t)dc->handle)->tdesc_table,
+                                                       ((dc_handle_t)dc->handle)->tdesc_table_size,
+                                                                       &map_info_in));
+          pc= map_info_in.preceding_tdesc_end;
+       } else {
+      dc_error (dc->handle, "Insufficient information for code reading.");
+       }
+       for (;;pc+=4) {
+               if (pc==loc) {
+                  return (DC_TRUE);
+               }
+               instr= dc_read_word(dc->handle,pc);
+               found_branch= dc_decode_finds_branch(dc,instr);
+               if ((map_info_out.flags & DC_MIO_PROLOGUE_END) 
+                         && (pc==map_info_out.prologue_end)) {
+                       break;
+               }
+               if (found_branch) {
+                       if (DC_MIO_IMPLICIT_PROLOGUE_END & map_info_out.flags) {
+                               break;
+                       } else {
+                       dc_error (dc->handle, "Found branch before end of prologue.");
+                       }
+               }
+       }
+       if (!(map_info_out.flags & DC_MIO_LITERAL_EPILOGUE_START)
+                && (map_info_out.epilogue_start >= loc 
+                               || !(map_info_out.flags & DC_MIO_EPILOGUE_START))) {
+               return (DC_TRUE);
+       }
+       dc_correct_cr_data(cdp,dc->handle);
+       for (pc=map_info_out.epilogue_start;pc<loc;pc+=4) {
+               instr= dc_read_word(dc->handle,pc);
+               if (dc_decode_finds_branch(dc,instr)) {
+                       return (DC_FALSE);
+               }
+       }
+       return (DC_TRUE);
+
+}
+
+
+
+dc_init_cr_data(cdp,tep)
+dc_cr_data_t *cdp;
+tdesc_elem_t *tep;
+{
+int reg;
+dc_word_t rai;
+dc_word_t raid;
+dc_word_t rsm;
+dc_word_t frpos;
+
+       if (tep){
+
+          /* Start off with all registers undefined and none saved. */
+          for (reg = 0; reg < DC_NUM_REG; reg++) {
+                 cdp->reg_val[reg].reg = DC_UNDEF;
+          }
+          cdp->saved = 0;
+
+          /* Overwrite with what tdesc element says. */
+
+          cdp->reg_val[tep->info.frame_address_register].reg = DC_REG_SP;
+          cdp->reg_val[tep->info.frame_address_register].off =
+                                 - tep->info.frame_address_offset;
+
+          rai = tep->info.return_address_info;
+          raid = tep->info.return_address_info_discriminant;
+          if (raid || rai != DC_REG_RA) {
+                 bit_set(cdp->saved,DC_REG_RA);
+                 bit_assign(cdp->how,DC_REG_RA,raid);
+                 cdp->where[DC_REG_RA] = rai;
+          }
+
+          rsm = tep->info.register_save_mask;
+          frpos = tep->info.register_save_offset;
+          for (reg = 14; reg <= 30; reg++) {
+                       if (bit_test(rsm, 30-reg)) {
+                               bit_set(cdp->saved,reg);
+                               bit_set(cdp->how,reg);
+                               cdp->where[reg] = frpos;
+                               frpos += sizeof(dc_word_t);
+                       } else {
+                                       cdp->reg_val[reg].reg = reg;
+                                       cdp->reg_val[reg].off = 0;
+                       }
+          }
+
+          cdp->reg_val[0].reg = 0;   /* guarantee what hardware does */
+          cdp->reg_val[0].off = 0;
+
+       } else {
+          /* Each register has its own initial value. */
+          for (reg = 0; reg < DC_NUM_REG; reg++) {
+                 cdp->reg_val[reg].reg = reg;
+                 cdp->reg_val[reg].off = 0;
+          }
+   /* No register is yet saved. */
+   cdp->saved = 0;
+   cdp->how = 0;
+       }
+}
+void dc_correct_cr_data(cdp,handle)
+dc_cr_data_t *cdp;
+dc_handle_t handle;
+{
+long sr,r;
+dc_word_t save_regs = 0;  /* registers used to save others */
+   for (r = 1; r < DC_REG_SP; r++) {
+      if (bit_test(cdp->saved,r) && !bit_test(cdp->how,r)) {
+         sr = cdp->where[r];
+         if (bit_test(save_regs,sr)) {
+            dc_error(handle, "Same register used to save two others.");
+        }
+         bit_set(save_regs,sr);
+      }
+   }
+   for (r = 1; r < DC_REG_FP; r++) {
+      if ((r < 14 || bit_test(cdp->saved,r)) && !bit_test(save_regs,r)) {
+         cdp->reg_val[r].reg = DC_UNDEF;
+      }
+   }
+   if (bit_test(cdp->saved,DC_REG_FP) &&
+       cdp->reg_val[DC_REG_FP].reg == DC_REG_SP) {  /* is r30 the far? */
+      cdp->reg_val[DC_REG_SP].reg = DC_UNDEF;  /* trash sp */
+   } else if (cdp->reg_val[DC_REG_SP].reg == DC_REG_SP) { /* is r31 the far? */
+      if (bit_test(cdp->saved,DC_REG_FP) && !bit_test(save_regs,DC_REG_FP)) {
+         cdp->reg_val[DC_REG_FP].reg = DC_UNDEF;  /* trash r30 */
+      }
+   }
+}
diff --git a/gdb/tdesc.h b/gdb/tdesc.h
new file mode 100755 (executable)
index 0000000..3936330
--- /dev/null
@@ -0,0 +1,329 @@
+/* This file has been modified by Data General Corporation, November 1989. */
+
+#ifndef _tdesc_h
+#define _tdesc_h
+#ifdef __STDC__ 
+#define _ARGS(x)       x
+#else
+#define _ARGS(x)       ()
+#endif
+
+/*
+      This file provides an abstract interface to "tdesc" information.
+      It is designed to be used in a uniform manner by several kinds
+      of debuggers:
+         (1) code in live debugged process (e.g., a traceback routine)
+         (2) a separate-process debugger debugging a live process
+         (3) a separate-process debugger debugging a memory dump
+
+      Dcontext model notes
+         * captures machine context
+            * partial: excludes memory
+         * frames
+            * kinds
+         * make one for starters, chain in reverse order to previous ones
+         * representation: pointer to opaque
+            * alloc/free protocol
+
+      Overall model
+         * access functions
+         * handle
+         * error handling
+*/
+
+
+
+typedef int dc_boolean_t;   /* range 0 .. 1 */
+#define DC_FALSE 0
+#define DC_TRUE 1
+
+
+typedef int dc_tristate_t;  /* range 0 .. 2 */
+#define DC_NO 0
+#define DC_YES 1
+#define DC_MAYBE 2
+
+
+#define DC_MII_PRECEDING_TDESC_END   (1<<0)
+#define DC_MII_FOLLOWING_TDESC_START (1<<1)
+
+#define DC_MIO_ENTRY_POINT            (1<< 0)
+#define DC_MIO_PROLOGUE_END           (1<< 1)
+#define DC_MIO_EPILOGUE_START         (1<< 2)
+#define DC_MIO_IMPLICIT_PROLOGUE_END  (1<<16)
+#define DC_MIO_LITERAL_ENTRY_POINT    (1<<17)
+#define DC_MIO_LITERAL_EPILOGUE_START (1<<18)
+
+
+/*
+   A word is 32 bits of information.  In memory, a word is word-aligned.
+
+   A common and important use of word_t is to represent values in the
+   target process, including (byte) addresses in the target process.
+   In this case, C arithmetic can be used to simulate machine address
+   arithmetic on the target.  (Unsigned arithmetic is actually modulus
+   arithmetic.)
+*/
+typedef unsigned int dc_word_t;
+
+
+/*----------------*/
+
+
+/* The exactness of locations may not be certainly known. */
+typedef dc_tristate_t dc_exactness_t;
+
+
+/*
+   The model includes five kinds of contexts.  Because each context
+   has an associated region and frame, these describe region kinds
+   and frame kinds as well.
+   [more description needed]
+   Currently, only call contexts exist.
+*/
+
+typedef int dc_kind_t;   /* range 0 .. 4 */
+#define DC_CALL_KIND          0
+#define DC_SAVE_KIND          1
+#define DC_EXCEPTION_KIND     2
+#define DC_PROTECTION_KIND    3
+#define DC_SPECIAL_KIND       4
+#define DC_NUM_KINDS          5
+
+
+typedef struct dc_debug_info {
+   unsigned int            protocol;            /* 1 for this structure */
+   dc_word_t               tdesc_ptr;
+   unsigned int            text_words_count;
+   dc_word_t               text_words_ptr;
+   unsigned int            data_words_count;
+   dc_word_t               data_words_ptr;
+} dc_debug_info_t;
+
+
+typedef struct dc_mstate {
+   dc_word_t reg[32];                      /* general registers */
+   dc_word_t xip;
+   dc_word_t nip;
+   dc_word_t fip;
+   dc_word_t fpsr;
+   dc_word_t fpcr;
+   dc_word_t psr;
+} dc_mstate_t;
+
+
+
+#if 0
+
+   void error_fcn (env, continuable, message)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      boolean_t continuable;            /* whether error function may return */
+      char *message;                    /* string (no trailing newline) */
+
+   /* In the future, we probably want the error_fcn to be: */
+   void error_fcn (env, continuable, code, ...)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      boolean_t continuable;            /* whether error function may return */
+      int code;                         /* error code */
+      ...                               /* parameters to message associated
+                                           with the code */
+
+   void read_fcn (env, memory, length, buffer)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_word_t memory;                    /* start address in image */
+      int length;                       /* in bytes */
+      char *buffer;                     /* start address of buffer */
+      /* There are no alignment assumptions for the read function. */
+
+   void write_fcn (env, memory, length, buffer)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_word_t memory;                    /* start address in image */
+      int length;                       /* in bytes */
+      char *buffer;                     /* start address of buffer */
+      /* There are no alignment assumptions for the write function. */
+      /* The write function is optional.  It must be provided if changes
+         to writable registers are to be made. */
+
+   void exec_fcn (env, mstate)
+      dc_word_t env;                       /* environment (arbitrary datum) */
+      dc_mstate_t *mstate;              /* machine state (read-write) */
+      /* The execute function is optional.  It would be used (in the future)
+         by the implementation of a procedurally specified tdesc mechanism. */
+
+#endif
+
+/*----------------*/
+
+
+typedef struct dc_map_info_in {
+   dc_word_t flags;
+   dc_word_t preceding_tdesc_end;
+   dc_word_t following_tdesc_start;
+} dc_map_info_in_t;
+
+
+typedef struct dc_map_info_out {
+   dc_word_t flags;
+   dc_word_t entry_point;
+   dc_word_t prologue_end;
+   dc_word_t epilogue_start;
+} dc_map_info_out_t;
+
+
+typedef void *dc_handle_t;
+
+typedef void (*tdesc_error_fcn_type) _ARGS((
+      dc_word_t env,                   /* environment (arbitrary datum) */
+      dc_boolean_t continuable,        /* whether error function may return */
+      const char *message              /* string (no trailing newline) */
+));
+typedef void (*tdesc_io_fcn_type) _ARGS((
+      dc_word_t env,                       /* environment (arbitrary datum) */
+      dc_word_t memory,                    /* start address in image */
+      int length,                       /* in bytes */
+      void *buffer                     /* start address of buffer */
+));
+typedef void (*tdesc_exec_fcn_type) _ARGS((
+      dc_word_t env,                       /* environment (arbitrary datum) */
+      dc_mstate_t *mstate              /* machine state (read-write) */
+));
+typedef void (*tdesc_map_fcn_type) _ARGS((
+      dc_word_t map_env,
+      dc_word_t loc,
+      dc_map_info_in_t map_info_in,
+      dc_map_info_out_t *map_info_out
+));
+
+
+extern dc_handle_t dc_initiate _ARGS((
+   dc_word_t debug_info_ptr,
+   tdesc_error_fcn_type error_fcn,
+   dc_word_t error_env,
+   tdesc_io_fcn_type read_fcn,
+   dc_word_t read_env,
+   tdesc_io_fcn_type write_fcn, /* NULL => absent */
+   dc_word_t write_env,
+   tdesc_exec_fcn_type exec_fcn, /* NULL => absent */
+   dc_word_t exec_env,
+   tdesc_map_fcn_type map_fcn, /* NULL => absent */
+   dc_word_t map_env
+));
+extern void dc_terminate _ARGS((
+   dc_handle_t handle
+));
+
+typedef int dc_register_state_t;    /* range 0 to 2 */
+
+#define DC_INVALID  0
+#define DC_READABLE 1
+#define DC_WRITABLE 2
+
+#define DC_NUM_REG 32
+
+#define DC_AUX_LOC  0
+#define DC_AUX_SXIP 1
+#define DC_AUX_SNIP 2
+#define DC_AUX_SFIP 3
+#define DC_AUX_FPSR 4
+#define DC_AUX_FPCR 5
+#define DC_NUM_AUX  6
+
+
+typedef void *dc_dcontext_t;
+
+extern dc_dcontext_t dc_make_dcontext _ARGS((
+   dc_handle_t handle,
+   dc_word_t reg_info[DC_NUM_REG],
+   dc_word_t reg_flags[2],
+   dc_word_t aux_info[DC_NUM_AUX],
+   dc_word_t aux_flags[2],
+   dc_exactness_t loc_exact,
+   dc_word_t psr_info,
+   dc_boolean_t psr_ind,
+   dc_word_t psr_flags[2]
+));
+extern void dc_free_dcontext _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_register_state_t dc_location_state _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_exactness_t dc_location_exactness _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_word_t dc_location _ARGS((
+   dc_dcontext_t dcontext
+));
+extern void dc_set_location _ARGS((
+   dc_dcontext_t dcontext,
+   dc_word_t value
+));
+extern dc_register_state_t dc_general_register_state _ARGS((
+   dc_dcontext_t dcontext,
+   int reg
+));
+extern dc_word_t dc_general_register _ARGS((
+   dc_dcontext_t dcontext,
+   int reg
+));
+extern void dc_set_general_register _ARGS((
+   dc_dcontext_t dcontext,
+   int reg,
+   dc_word_t value
+));
+extern dc_register_state_t dc_auxiliary_register_state _ARGS((
+   dc_dcontext_t dcontext,
+   int reg
+));
+extern dc_word_t dc_auxiliary_register _ARGS((
+   dc_dcontext_t dcontext,
+   int reg
+));
+extern void dc_set_auxiliary_register _ARGS((
+   dc_dcontext_t dcontext,
+   int reg,
+   dc_word_t value
+));
+extern dc_register_state_t dc_psr_register_bit_state _ARGS((
+   dc_dcontext_t dcontext,
+   int bit
+));
+extern dc_word_t dc_psr_register _ARGS((
+   dc_dcontext_t dcontext
+));
+extern void dc_set_psr_register _ARGS((
+   dc_dcontext_t dcontext,
+   dc_word_t mask,
+   dc_word_t value
+));
+extern dc_word_t dc_frame_address _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_kind_t dc_context_kind _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_register_state_t dc_return_address_state _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_exactness_t dc_return_address_exactness _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_word_t dc_return_address _ARGS((
+   dc_dcontext_t dcontext
+));
+extern void dc_set_return_address _ARGS((
+   dc_dcontext_t dcontext,
+   dc_word_t value
+));
+extern void dc_get_exception_info();
+extern void dc_get_protection_info();
+extern void dc_get_special_info();
+extern dc_dcontext_t dc_previous_dcontext _ARGS((
+   dc_dcontext_t dcontext
+));
+extern dc_boolean_t dc_location_in_text_chunk _ARGS((
+   dc_dcontext_t dcontext,
+   dc_word_t value
+));
+
+#endif
diff --git a/gdb/tm-29k.h b/gdb/tm-29k.h
new file mode 100644 (file)
index 0000000..4594622
--- /dev/null
@@ -0,0 +1,653 @@
+/* Parameters for target machine of AMD 29000, for GDB, the GNU debugger.
+   Copyright 1990, 1991 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Parameters for an EB29K (a board which plugs into a PC and is
+   accessed through EBMON software running on the PC, which we
+   use as we'd use a remote stub (see remote-eb.c).
+
+   If gdb is ported to other 29k machines/systems, the
+   machine/system-specific parts should be removed from this file (a
+   la tm-68k.h).  */
+
+/* Byte order is configurable, but this machine runs big-endian.  */
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Floating point uses IEEE representations.  */
+#define IEEE_FLOAT
+
+/* We can either use a.out, encapsulated, or can use COFF */
+#ifndef COFF_ENCAPSULATE
+#define COFF_FORMAT
+/* This just has to do with what coff header files are in use.  */
+#define COFF_CHECK_X_ZEROES
+#endif
+
+/* Recognize our magic number.  */
+#define BADMAG(x) ((x)->f_magic != 0572)
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc) \
+  { pc = skip_prologue (pc); }
+CORE_ADDR skip_prologue ();
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) (read_register (LR0_REGNUM))
+
+/* I'm not sure about the exact value of this, but based on looking
+   at the stack pointer when we get to main this seems to be right.
+
+   This is the register stack; We call it "CONTROL" in GDB for consistency
+   with Pyramid.  */
+#define CONTROL_END_ADDR 0x80200000
+
+/* Memory stack.  This is for the default register stack size, which is
+   only 0x800 bytes.  Perhaps we should let the user specify stack sizes
+   (and tell EBMON with the "ZS" command).  */
+#define STACK_END_ADDR 0x801ff800
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Stack must be aligned on 32-bit word boundaries.  */
+#define STACK_ALIGN(ADDR) (((ADDR) + 3) & ~3)
+
+/* Sequence of bytes for breakpoint instruction.  */
+/* ASNEQ 0x50, gr1, gr1
+   The trap number 0x50 is chosen arbitrarily.  */
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+#define BREAKPOINT {0x72, 0x50, 0x01, 0x01}
+#else /* Target is little-endian.  */
+#define BREAKPOINT {0x01, 0x01, 0x50, 0x72}
+#endif /* Target is little-endian.  */
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 4
+
+/* Nonzero if instruction at PC is a return instruction.
+   On the 29k, this is a "jmpi l0" instruction.  */
+
+#define ABOUT_TO_RETURN(pc) \
+  ((read_memory_integer (pc, 4) & 0xff0000ff) == 0xc0000080)
+
+/* Return 1 if P points to an invalid floating point value.  */
+
+#define INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 205
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.
+
+   FIXME, add floating point registers and support here.
+
+   Also note that this list does not attempt to deal with kernel
+   debugging (in which the first 32 registers are gr64-gr95).  */
+
+#define REGISTER_NAMES \
+{"gr96", "gr97", "gr98", "gr99", "gr100", "gr101", "gr102", "gr103", "gr104", \
+ "gr105", "gr106", "gr107", "gr108", "gr109", "gr110", "gr111", "gr112", \
+ "gr113", "gr114", "gr115", "gr116", "gr117", "gr118", "gr119", "gr120", \
+ "gr121", "gr122", "gr123", "gr124", "gr125", "gr126", "gr127",                 \
+ "lr0", "lr1", "lr2", "lr3", "lr4", "lr5", "lr6", "lr7", "lr8", "lr9",   \
+ "lr10", "lr11", "lr12", "lr13", "lr14", "lr15", "lr16", "lr17", "lr18", \
+ "lr19", "lr20", "lr21", "lr22", "lr23", "lr24", "lr25", "lr26", "lr27", \
+ "lr28", "lr29", "lr30", "lr31", "lr32", "lr33", "lr34", "lr35", "lr36", \
+ "lr37", "lr38", "lr39", "lr40", "lr41", "lr42", "lr43", "lr44", "lr45", \
+ "lr46", "lr47", "lr48", "lr49", "lr50", "lr51", "lr52", "lr53", "lr54", \
+ "lr55", "lr56", "lr57", "lr58", "lr59", "lr60", "lr61", "lr62", "lr63", \
+ "lr64", "lr65", "lr66", "lr67", "lr68", "lr69", "lr70", "lr71", "lr72", \
+ "lr73", "lr74", "lr75", "lr76", "lr77", "lr78", "lr79", "lr80", "lr81", \
+ "lr82", "lr83", "lr84", "lr85", "lr86", "lr87", "lr88", "lr89", "lr90", \
+ "lr91", "lr92", "lr93", "lr94", "lr95", "lr96", "lr97", "lr98", "lr99", \
+ "lr100", "lr101", "lr102", "lr103", "lr104", "lr105", "lr106", "lr107", \
+ "lr108", "lr109", "lr110", "lr111", "lr112", "lr113", "lr114", "lr115", \
+ "lr116", "lr117", "lr118", "lr119", "lr120", "lr121", "lr122", "lr123", \
+ "lr124", "lr125", "lr126", "lr127",                                    \
+  "AI0", "AI1", "AI2", "AI3", "AI4", "AI5", "AI6", "AI7", "AI8", "AI9",  \
+  "AI10", "AI11", "AI12", "AI13", "AI14", "AI15", "FP",                         \
+  "bp", "fc", "cr", "q",                                                \
+  "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",         \
+  "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "int", "fps", "exo", "gr1",  \
+  "alu", "ipc", "ipa", "ipb" }
+
+/* Special register #x.  */
+#define SR_REGNUM(x) \
+  ((x) < 15  ? VAB_REGNUM + (x)                                         \
+   : (x) >= 128 && (x) < 131 ? IPC_REGNUM + (x)                         \
+   : (x) == 131 ? Q_REGNUM                                      \
+   : (x) == 132 ? ALU_REGNUM                                    \
+   : (x) >= 133 && (x) < 136 ? BP_REGNUM + (x)                  \
+   : (x) >= 160 && (x) < 163 ? FPE_REGNUM + (x)                         \
+   : (x) == 164 ? EXO_REGNUM                                     \
+   : (error ("Internal error in SR_REGNUM"), 0))
+#define GR96_REGNUM 0
+#define GR1_REGNUM 200
+/* This needs to be the memory stack pointer, not the register stack pointer,
+   to make call_function work right.  */
+#define SP_REGNUM MSP_REGNUM
+#define FP_REGNUM 33 /* lr1 */
+/* Large Return Pointer (gr123).  */
+#define LRP_REGNUM (123 - 96 + GR96_REGNUM)
+/* Static link pointer (gr124).  */
+#define SLP_REGNUM (124 - 96 + GR96_REGNUM)
+/* Memory Stack Pointer (gr125).  */
+#define MSP_REGNUM (125 - 96 + GR96_REGNUM)
+/* Register allocate bound (gr126).  */
+#define RAB_REGNUM (126 - 96 + GR96_REGNUM)
+/* Register Free Bound (gr127).  */
+#define RFB_REGNUM (127 - 96 + GR96_REGNUM)
+/* Register Stack Pointer.  */
+#define RSP_REGNUM GR1_REGNUM
+#define LR0_REGNUM 32
+#define PC_REGNUM 192 /* pc1 */
+#define NPC_REGNUM 191 /* pc0 */
+#define PC2_REGNUM 193
+#define BP_REGNUM 177
+#define FC_REGNUM 178
+#define CR_REGNUM 179
+#define Q_REGNUM 180
+#define VAB_REGNUM 181
+#define LRU_REGNUM 195
+#define FPE_REGNUM 196
+#define INT_REGNUM 197
+#define FPS_REGNUM 198
+#define EXO_REGNUM 199
+#define PS_REGNUM 201
+#define ALU_REGNUM 201
+#define IPC_REGNUM 202
+#define IPB_REGNUM 204
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+#define REGISTER_BYTE(N)  ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+/* All regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) (4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  */
+
+/* All regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) (4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE (4)
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE (4)
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
+{ bcopy ((FROM), (TO), 4); }
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+{ bcopy ((FROM), (TO), 4); }
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+  (((N) == PC_REGNUM || (N) == LRP_REGNUM || (N) == SLP_REGNUM         \
+    || (N) == MSP_REGNUM || (N) == RAB_REGNUM || (N) == RFB_REGNUM     \
+    || (N) == GR1_REGNUM || (N) == FP_REGNUM || (N) == LR0_REGNUM       \
+    || (N) == NPC_REGNUM || (N) == PC2_REGNUM)                           \
+   ? lookup_pointer_type (builtin_type_void) : builtin_type_int)
+\f
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+/* On the 29k the LRP points to the part of the structure beyond the first
+   16 words.  */
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  write_register (LRP_REGNUM, (ADDR) + 16 * 4);
+
+/* Should call_function allocate stack space for a struct return?  */
+/* On the 29k objects over 16 words require the caller to allocate space.  */
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 16 * 4)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF)             \
+  {                                                                               \
+    int reg_length = TYPE_LENGTH (TYPE);                                  \
+    if (reg_length > 16 * 4)                                              \
+      {                                                                           \
+       reg_length = 16 * 4;                                               \
+       read_memory (*((int *)(REGBUF) + LRP_REGNUM), (VALBUF) + 16 * 4,   \
+                    TYPE_LENGTH (TYPE) - 16 * 4);                         \
+      }                                                                           \
+    bcopy (((int *)(REGBUF))+GR96_REGNUM, (VALBUF), reg_length);          \
+  }
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  {                                                                      \
+    int reg_length = TYPE_LENGTH (TYPE);                                 \
+    if (reg_length > 16 * 4)                                             \
+      {                                                                          \
+        reg_length = 16 * 4;                                             \
+        write_memory (read_register (LRP_REGNUM),                        \
+                     (char *)(VALBUF) + 16 * 4,                          \
+                     TYPE_LENGTH (TYPE) - 16 * 4);                       \
+      }                                                                          \
+    write_register_bytes (REGISTER_BYTE (GR96_REGNUM), (char *)(VALBUF),  \
+                         TYPE_LENGTH (TYPE));                            \
+  }
+\f
+/* The am29k user's guide documents well what the stacks look like.
+   But what isn't so clear there is how this interracts with the
+   symbols, or with GDB.
+   In the following saved_msp, saved memory stack pointer (which functions
+   as a memory frame pointer), means either
+   a register containing the memory frame pointer or, in the case of
+   functions with fixed size memory frames (i.e. those who don't use
+   alloca()), the result of the calculation msp + msize.
+
+   LOC_ARG, LOC_LOCAL - For GCC, these are relative to saved_msp.
+     For high C, these are relative to msp (making alloca impossible).
+   LOC_REGISTER, LOC_REGPARM - The register number is the number at the
+     time the function is running (after the prologue), or in the case
+     of LOC_REGPARM, may be a register number in the range 160-175.
+
+   The compilers do things like store an argument into memory, and then put out
+   a LOC_ARG for it, or put it into global registers and put out a
+   LOC_REGPARM.  Thus is it important to execute the first line of
+   code (i.e. the line of the open brace, i.e. the prologue) of a function
+   before trying to print arguments or anything.
+
+   The following diagram attempts to depict what is going on in memory
+   (see also the _am29k user's guide_) and also how that interacts with
+   GDB frames.  We arbitrarily pick fci->frame to point the same place
+   as the register stack pointer; since we set it ourself in
+   INIT_EXTRA_FRAME_INFO, and access it only through the FRAME_*
+   macros, it doesn't really matter exactly how we
+   do it.  However, note that FRAME_FP is used in two ways in GDB:
+   (1) as a "magic cookie" which uniquely identifies frames (even over
+   calls to the inferior), (2) (in PC_IN_CALL_DUMMY [!CANNOT_EXECUTE_STACK])
+   as the value of SP_REGNUM before the dummy frame was pushed.  These
+   two meanings would be incompatible for the 29k if we didn't define
+   CANNOT_EXECUTE_STACK (but we do, so don't worry about it).
+   Also note that "lr1" below, while called a frame pointer
+   in the user's guide, has only one function:  To determine whether
+   registers need to be filled in the function epilogue.
+
+   Consider the code:
+              < call bar>
+               loc1: . . .
+        bar:  sub gr1,gr1,rsize_b
+             . . .
+             add mfp,msp,0
+             sub msp,msp,msize_b
+             . . .
+             < call foo >
+       loc2: . . .
+        foo:  sub gr1,gr1,rsize_f
+             . . .
+             add mfp,msp,0
+             sub msp,msp,msize_f
+             . . .
+        loc3: < suppose the inferior stops here >
+
+                   memory stack      register stack
+                  |           |     |____________|
+                  |           |     |____loc1____|
+         +------->|___________|     |            |   ^
+         |        | ^         |     |  locals_b  |   |
+         |        | |         |     |____________|   |
+         |        | |         |     |            |   | rsize_b
+         |        | | msize_b |     | args_to_f  |   |
+         |        | |         |     |____________|   |
+         |        | |         |     |____lr1_____|   V
+         |        | V         |     |____loc2____|<----------------+
+         |   +--->|___________|<---------mfp     |   ^             |
+         |   |    | ^         |     |  locals_f  |   |             |
+         |   |    | | msize_f |     |____________|   |             |
+         |   |    | |         |     |            |   | rsize_f     |
+         |   |    | V         |     |   args     |   |             |
+         |   |    |___________|<msp |____________|   |             |
+         |   |                      |_____lr1____|   V             |
+         |   |                      |___garbage__| <- gr1 <----+   |
+         |   |                                                 |   |
+          |   |                                                |   |
+         |   |                      pc=loc3                    |   |
+         |   |                                                 |   |
+         |   |                                                 |   |
+         |   |            frame cache                          |   |
+          |   |       |_________________|                      |   |
+          |   |       |rsize=rsize_b    |                      |   |
+          |   |       |msize=msize_b    |                      |   |
+          +---|--------saved_msp        |                      |   |
+              |       |frame------------------------------------|---+
+              |       |pc=loc2          |                       |
+              |       |_________________|                       |
+              |       |rsize=rsize_f    |                       |
+              |       |msize=msize_f    |                       |
+              +--------saved_msp        |                       |
+                      |frame------------------------------------+
+                      |pc=loc3          |
+                      |_________________|
+
+   So, is that sufficiently confusing?  Welcome to the 29000.
+   Notes:
+   * The frame for foo uses a memory frame pointer but the frame for
+     bar does not.  In the latter case the saved_msp is
+     computed by adding msize to the saved_msp of the
+     next frame.
+   * msize is in the frame cache only for high C's sake.  */
+
+void read_register_stack ();
+long read_register_stack_integer ();
+\f
+#define EXTRA_FRAME_INFO  \
+  CORE_ADDR saved_msp;    \
+  unsigned int rsize;     \
+  unsigned int msize;
+
+/* Because INIT_FRAME_PC gets passed fromleaf, that's where we init
+   not only ->pc and ->frame, but all the extra stuff, when called from
+   get_prev_frame_info, that is.  */
+#define INIT_EXTRA_FRAME_INFO(fci) \
+  init_extra_frame_info(fci);
+void init_extra_frame_info ();
+#define INIT_FRAME_PC(fromleaf, fci) \
+  init_frame_pc(fromleaf, fci);
+void init_frame_pc ();
+\f
+/* FRAME_CHAIN takes a FRAME
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* On the 29k, the nominal address of a frame is the address on the
+   register stack of the return address (the one next to the incoming
+   arguments, not down at the bottom so nominal address == stack pointer).
+
+   GDB expects "nominal address" to equal contents of FP_REGNUM,
+   at least when it comes time to create the innermost frame.
+   However, that doesn't work for us, so when creating the innermost
+   frame we set ->frame ourselves in INIT_EXTRA_FRAME_INFO.  */
+
+/* These are mostly dummies for the 29k because INIT_FRAME_PC
+   sets prev->frame instead.  */
+#define FRAME_CHAIN(thisframe) (0)
+
+/* Not sure how to figure out where the bottom frame is.  There is
+   no frame for start.  In my tests so far the
+   pc has been outside the text segment, though, so check for that.
+   However, allow a pc in a call dummy.  */
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (outside_startup_file (FRAME_SAVED_PC (thisframe))   \
+   && FRAME_SAVED_PC (thisframe) >= text_start         \
+   && FRAME_SAVED_PC (thisframe) < text_end + CALL_DUMMY_LENGTH)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (0)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+/* Saved pc (i.e. return address).  */
+#define FRAME_SAVED_PC(fraim) \
+  (read_register_stack_integer ((fraim)->frame + (fraim)->rsize, 4))
+
+/* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their
+   offsets being relative to the memory stack pointer (high C) or
+   saved_msp (gcc).  */
+
+#define FRAME_LOCALS_ADDRESS(fi) frame_locals_address (fi)
+extern CORE_ADDR frame_locals_address ();
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+/* While we could go the effort of finding the tags word and getting
+   the argcount field from it,
+   (1) It only counts arguments in registers, i.e. the first 16 words
+       of arguments
+   (2) It gives the number of arguments the function was declared with
+       not how many it was called with (or some variation, like all 16
+       words for varadic functions).  This makes argcount pretty much
+       redundant with -g info, even for varadic functions.
+   So don't bother.  */
+#define FRAME_NUM_ARGS(numargs, fi) ((numargs) = -1)
+
+#define FRAME_ARGS_ADDRESS(fi) FRAME_LOCALS_ADDRESS (fi)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Provide our own get_saved_register.  HAVE_REGISTER_WINDOWS is insufficient
+   because registers get renumbered on the 29k without getting saved.  */
+
+#define GET_SAVED_REGISTER
+\f
+/* Call function stuff.  */
+
+/* The dummy frame looks like this (see also the general frame picture
+   above):
+
+                                       register stack
+
+                                     |                |  frame for function
+                                             |   locals_sproc |  executing at time
+                                      |________________|  of call_function.
+                                     |                |  We must not disturb
+                                     | args_out_sproc |  it.
+        memory stack                 |________________|
+                                     |____lr1_sproc___|
+       |            |                |__retaddr_sproc_| <- gr1 (at start)
+       |____________|<-msp 0 <-----------mfp_dummy_____|
+       |            |  (at start)     |                |
+       | arg_slop   |                |  saved regs    |
+       | (16 words) |                | gr96-gr124     |
+       |____________|<-msp 1--after   | sr128-sr135    |
+       |            | PUSH_DUMMY_FRAME|                |
+       | struct ret |                 |________________|
+       | 17+        |                 |                |
+       |____________|<- lrp           | args_out_dummy |
+       | struct ret |                |  (16 words)    |
+       | 16         |                |________________|
+       | (16 words) |                 |____lr1_dummy___|
+       |____________|<- msp 2--after  |_retaddr_dummy__|<- gr1 after
+       |            | struct ret      |                |   PUSH_DUMMY_FRAME
+       | margs17+   | area allocated  |  locals_inf    |
+       |            |                 |________________|    called
+       |____________|<- msp 4--when   |                |    function's
+       |            |   inf called    | args_out_inf   |    frame (set up
+       | margs16    |                 |________________|    by called
+       | (16 words) |                 |_____lr1_inf____|    function).
+       |____________|<- msp 3--after  |       .        |
+       |            |   args pushed   |       .        |
+       |            |                |       .        |
+                                      |                |
+
+   arg_slop: This area is so that when the call dummy adds 16 words to
+      the msp, it won't end up larger than mfp_dummy (it is needed in the
+      case where margs and struct_ret do not add up to at least 16 words).
+   struct ret:  This area is allocated by GDB if the return value is more
+      than 16 words.  struct ret_16 is not used on the 29k.
+   margs:  Pushed by GDB.  The call dummy copies the first 16 words to
+      args_out_dummy.
+   retaddr_sproc:  Contains the PC at the time we call the function.
+      set by PUSH_DUMMY_FRAME and read by POP_FRAME.
+   retaddr_dummy:  This points to a breakpoint instruction in the dummy.  */
+\f
+/* Rsize for dummy frame, in bytes.  */
+
+/* Bytes for outgoing args, lr1, and retaddr.  */
+#define DUMMY_ARG (2 * 4 + 16 * 4)
+
+/* Number of special registers (sr128-) to save.  */
+#define DUMMY_SAVE_SR128 8
+/* Number of general (gr96-) registers to save.  */
+#define DUMMY_SAVE_GR96 29
+
+#define DUMMY_FRAME_RSIZE \
+(4 /* mfp_dummy */                                        \
+ + DUMMY_SAVE_GR96 * 4                             \
+ + DUMMY_SAVE_SR128 * 4                                   \
+ + DUMMY_ARG                                      \
+ )
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME push_dummy_frame();
+extern void push_dummy_frame ();
+
+/* Discard from the stack the innermost frame,
+   restoring all saved registers.  */
+
+#define POP_FRAME pop_frame ();
+extern void pop_frame ();
+
+/* This sequence of words is the instructions
+   mtsrim cr, 15
+   loadm 0, 0, lr2, msp     ; load first 16 words of arguments into registers
+   add msp, msp, 16 * 4     ; point to the remaining arguments
+  CONST_INSN:
+   const gr96,inf
+   consth gr96,inf
+   calli lr0, gr96
+   aseq 0x40,gr1,gr1   ; nop
+   asneq 0x50,gr1,gr1  ; breakpoint
+   */
+
+/* Position of the "const" instruction within CALL_DUMMY in bytes.  */
+#define CONST_INSN (3 * 4)
+#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
+#define CALL_DUMMY {0x0400870f, 0x3600827d, 0x157d7d40, 0x03ff60ff,    \
+                   0x02ff60ff, 0xc8008060, 0x70400101, 0x72500101}
+#else /* Byte order differs.  */
+  you lose
+#endif /* Byte order differs.  */
+#define CALL_DUMMY_LENGTH (8 * 4)
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Helper macro for FIX_CALL_DUMMY.  WORDP is a long * which points to a
+   word in target byte order; bits 0-7 and 16-23 of *WORDP are replaced with
+   bits 0-7 and 8-15 of DATA (which is in host byte order).  */
+
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+#define STUFF_I16(WORDP, DATA) \
+  { \
+    *((char *)(WORDP) + 3) = ((DATA) & 0xff);\
+    *((char *)(WORDP) + 1) = (((DATA) >> 8) & 0xff);\
+  }
+#else /* Target is little endian.  */
+#define STUFF_I16(WORDP, DATA) \
+  {
+    *(char *)(WORDP) = ((DATA) & 0xff);
+    *((char *)(WORDP) + 2) = (((DATA) >> 8) & 0xff);
+  }
+#endif /* Target is little endian.  */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+/* Currently this stuffs in the address of the function that we are calling.
+   If different 29k systems use different breakpoint instructions, it
+   could also stuff BREAKPOINT in the right place (to avoid having to
+   duplicate CALL_DUMMY in each tm-*.h file).  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+  {\
+    STUFF_I16((char *)dummyname + CONST_INSN, fun);\
+    STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16);\
+  }
+
+/* At least our 29k board has separate data & instruction memories and can't
+   execute the data memory.  Also, there should be space after text_end;
+   we won't get a SIGSEGV or scribble on data space.  */
+
+#define CALL_DUMMY_LOCATION AFTER_TEXT_END
+
+/* How to translate register numbers in the .stab's into gdb's internal register
+   numbers.  We don't translate them, but we warn if an invalid register
+   number is seen.  Note that FIXME, we use the value "sym" as an implicit
+   argument in printing the error message.  It happens to be available where
+   this macro is used.  (This macro definition appeared in a late revision
+   of gdb-3.91.6 and is not well tested.  Also, it should be a "complaint".) */
+
+#define        STAB_REG_TO_REGNUM(num) \
+       (((num) > LR0_REGNUM + 127) \
+          ? fprintf(stderr,    \
+               "Invalid register number %d in symbol table entry for %s\n", \
+                (num), SYMBOL_NAME (sym)), (num)       \
+          : (num))
diff --git a/gdb/tm-3b1.h b/gdb/tm-3b1.h
new file mode 100644 (file)
index 0000000..65143a9
--- /dev/null
@@ -0,0 +1,108 @@
+/* Parameters for targeting to a 3b1.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define BREAKPOINT { 0x4e, 0x41 }
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in COFF format.  */
+
+#define COFF_FORMAT
+#define COFF_NO_LONG_FILE_NAMES
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0x300000
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+  register int regnum;                             \
+  sp = push_word (sp, read_register (PC_REGNUM));   \
+  sp = push_word (sp, read_register (FP_REGNUM));   \
+  write_register (FP_REGNUM, sp);                  \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)  \
+    sp = push_word (sp, read_register (regnum));    \
+  sp = push_word (sp, read_register (PS_REGNUM));   \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                                \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                      \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     bpt
+     nop
+Note this is 24 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 24
+
+#define CALL_DUMMY_START_OFFSET 8
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type)     \
+{ *(int *)((char *) dummyname + 16) = nargs * 4;  \
+  *(int *)((char *) dummyname + 10) = fun; }
+\f
+#include "tm-68k.h"
diff --git a/gdb/tm-68k.h b/gdb/tm-68k.h
new file mode 100644 (file)
index 0000000..120ea08
--- /dev/null
@@ -0,0 +1,473 @@
+/* Parameters for execution on a 68000 series machine.
+   Copyright (C) 1986, 1987, 1989, 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Generic 68000 stuff, to be included by other m-*.h files.
+   Define HAVE_68881 if that is the case.  */
+
+#if defined (HAVE_68881)
+#define IEEE_FLOAT 1
+#endif
+
+/* Define the bit, byte, and word ordering of the machine.  */
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)   \
+{ register int op = read_memory_integer (pc, 2);       \
+  if (op == 0047126)                                   \
+    pc += 4;   /* Skip link #word */                   \
+  else if (op == 0044016)                              \
+    pc += 6;   /* Skip link #long */                   \
+  /* Not sure why branches are here.  */                \
+  /* From m-isi.h, m-altos.h */                         \
+  else if (op == 0060000)                              \
+    pc += 4;   /* Skip bra #word */                    \
+  else if (op == 00600377)                             \
+    pc += 6;   /* skip bra #long */                    \
+  else if ((op & 0177400) == 0060000)                  \
+    pc += 2;   /* skip bra #char */                    \
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+read_memory_integer (read_register (SP_REGNUM), 4)
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.
+   This is a TRAP instruction.  The last 4 bits (0xf below) is the
+   vector.  Systems which don't use 0xf should define BREAKPOINT
+   themselves before including this file.  */
+
+#if !defined (BREAKPOINT)
+#define BREAKPOINT {0x4e, 0x4f}
+#endif
+
+/* If your kernel resets the pc after the trap happens you may need to
+   define this in m-68k.h.  */
+
+#if !defined (DECR_PC_AFTER_BREAK)
+#define DECR_PC_AFTER_BREAK 2
+#endif
+
+/* Nonzero if instruction at PC is a return instruction.  */
+/* Allow any of the return instructions, including a trapv and a return
+   from interupt.  */
+
+#define ABOUT_TO_RETURN(pc) ((read_memory_integer (pc, 2) & ~0x3) == 0x4e74)
+
+/* Return 1 if P points to an invalid floating point value.  */
+
+#define INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
+
+/* Say how long registers are.  */
+
+#define REGISTER_TYPE long
+
+#if defined (HAVE_68881)
+#  if defined (sun)
+    /* Sun3 status includes fpflags, which shows whether the FPU has been used
+       by the process, and whether the FPU was done with an instruction or 
+       was interrupted in the middle of a long instruction.  See
+       <machine/reg.h>.  */
+    /*                      a&d, pc,sr, fp, fpstat, fpflags   */
+#    define NUM_REGS 31
+#    define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4 + 4)
+#  else /* Not sun3.  */
+#    define NUM_REGS 29
+#    define REGISTER_BYTES (16*4 + 8 + 8*12 + 3*4)
+#  endif /* Not sun3.  */
+#else /* No 68881.  */
+#  define NUM_REGS 18
+#  define REGISTER_BYTES (16*4 + 8)
+#endif /* No 68881.  */
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#if defined (HAVE_68881)
+#define REGISTER_BYTE(N)  \
+ ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168   \
+  : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
+  : (N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the 68000, all regs are 4 bytes
+   except the floating point regs which are 12 bytes.  */
+/* Note that the unsigned cast here forces the result of the
+   subtraction to very high positive values if N < FP0_REGNUM */
+
+#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the 68000, all regs are 4 bytes
+   except the floating point regs which are 8-byte doubles.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 12
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+{ \
+  extern struct ext_format ext_format_68881 [];        \
+  \
+  if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
+    ieee_extended_to_double (ext_format_68881, (FROM), (TO));  \
+  else                                 \
+    bcopy ((FROM), (TO), 4);   \
+}
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+{ \
+  extern struct ext_format ext_format_68881 [];        \
+  \
+  if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
+    double_to_ieee_extended (ext_format_68881, (FROM), (TO));  \
+  else                                 \
+    bcopy ((FROM), (TO), 4);   \
+}
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+/* Note, for registers which contain addresses return
+   pointer to void, not pointer to char, because we don't
+   want to attempt to print the string after printing the address.  */
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double :           \
+  (N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM ?         \
+  lookup_pointer_type (builtin_type_void) : builtin_type_int)
+
+#else /* no 68881.  */
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N)  ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the 68000, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the 68000, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)  bcopy ((FROM), (TO), 4);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)  bcopy ((FROM), (TO), 4);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N)  builtin_type_int
+
+#endif /* No 68881.  */
+
+/* Initializer for an array of names of registers.
+   Entries beyond the first NUM_REGS are ignored.  */
+
+#define REGISTER_NAMES  \
+ {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
+  "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
+  "ps", "pc",  \
+  "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
+  "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define A1_REGNUM 9
+#define FP_REGNUM 14           /* Contains address of executing stack frame */
+#define SP_REGNUM 15           /* Contains address of top of stack */
+#define PS_REGNUM 16           /* Contains processor status */
+#define PC_REGNUM 17           /* Contains program counter */
+#if defined (HAVE_68881)
+#define FP0_REGNUM 18          /* Floating point register 0 */
+#define FPC_REGNUM 26          /* 68881 control register */
+#define FPS_REGNUM 27          /* 68881 status register */
+#endif /* 68881.  */
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { write_register (A1_REGNUM, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  This is assuming that floating point values are returned
+   as doubles in d0/d1.  */
+
+#if !defined (EXTRACT_RETURN_VALUE)
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+#endif
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  Assumes floats are passed
+   in d0/d1.  */
+
+#if !defined (STORE_RETURN_VALUE)
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+#endif
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the 68000, the frame's nominal address
+   is the address of a 4-byte word containing the calling frame's address.  */
+
+#define FRAME_CHAIN(thisframe)  \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && outside_startup_file (FRAME_SAVED_PC (thisframe)))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+   Can set VAL to -1, meaning no way to tell.  */
+
+/* We can't tell how many args there are
+   now that the C compiler delays popping them.  */
+#if !defined (FRAME_NUM_ARGS)
+#define FRAME_NUM_ARGS(val,fi) (val = -1)
+#endif
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#if !defined (FRAME_FIND_SAVED_REGS)
+#if defined (HAVE_68881)
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{ register int regnum;                                                 \
+  register int regmask;                                                        \
+  register CORE_ADDR next_addr;                                                \
+  register CORE_ADDR pc;                                               \
+  int nextinsn;                                                                \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
+      && (frame_info)->pc <= (frame_info)->frame)                              \
+    { next_addr = (frame_info)->frame;                                 \
+      pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
+  else                                                                 \
+    { pc = get_pc_function_start ((frame_info)->pc);                   \
+      /* Verify we have a link a6 instruction next;                    \
+        if not we lose.  If we win, find the address above the saved   \
+        regs using the amount of storage from the link instruction.  */\
+      if (044016 == read_memory_integer (pc, 2))                       \
+       next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
+      else if (047126 == read_memory_integer (pc, 2))                  \
+       next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
+      else goto lose;                                                  \
+      /* If have an addal #-n, sp next, adjust next_addr.  */          \
+      if ((0177777 & read_memory_integer (pc, 2)) == 0157774)          \
+       next_addr += read_memory_integer (pc += 2, 4), pc += 4;         \
+    }                                                                  \
+  /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */     \
+  regmask = read_memory_integer (pc + 2, 2);                           \
+  /* But before that can come an fmovem.  Check for it.  */            \
+  nextinsn = 0xffff & read_memory_integer (pc, 2);                     \
+  if (0xf227 == nextinsn                                               \
+      && (regmask & 0xff00) == 0xe000)                                 \
+    { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
+      for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)             \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr -= 12);         \
+      regmask = read_memory_integer (pc + 2, 2); }                     \
+  if (0044327 == read_memory_integer (pc, 2))                          \
+    { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
+      for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)           \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; }    \
+  else if (0044347 == read_memory_integer (pc, 2))                     \
+    { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
+      for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)          \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr -= 4); }                \
+  else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))           \
+    { regnum = 0xf & read_memory_integer (pc, 2); pc += 2;             \
+      (frame_saved_regs).regs[regnum] = (next_addr -= 4); }            \
+  /* fmovemx to index of sp may follow.  */                            \
+  regmask = read_memory_integer (pc + 2, 2);                           \
+  nextinsn = 0xffff & read_memory_integer (pc, 2);                     \
+  if (0xf236 == nextinsn                                               \
+      && (regmask & 0xff00) == 0xf000)                                 \
+    { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
+      for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)             \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12;    \
+      regmask = read_memory_integer (pc + 2, 2); }                     \
+  /* clrw -(sp); movw ccr,-(sp) may follow.  */                                \
+  if (0x426742e7 == read_memory_integer (pc, 4))                       \
+    (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4);             \
+  lose: ;                                                              \
+  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame;            \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;                \
+}
+#else /* no 68881.  */
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{ register int regnum;                                                 \
+  register int regmask;                                                        \
+  register CORE_ADDR next_addr;                                                \
+  register CORE_ADDR pc;                                               \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 \
+      && (frame_info)->pc <= (frame_info)->frame)                              \
+    { next_addr = (frame_info)->frame;                                 \
+      pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4; }\
+  else                                                                 \
+    { pc = get_pc_function_start ((frame_info)->pc);                   \
+      /* Verify we have a link a6 instruction next;                    \
+        if not we lose.  If we win, find the address above the saved   \
+        regs using the amount of storage from the link instruction.  */\
+      if (044016 == read_memory_integer (pc, 2))                       \
+       next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
+      else if (047126 == read_memory_integer (pc, 2))                  \
+       next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
+      else goto lose;                                                  \
+      /* If have an addal #-n, sp next, adjust next_addr.  */          \
+      if ((0177777 & read_memory_integer (pc, 2)) == 0157774)          \
+       next_addr += read_memory_integer (pc += 2, 4), pc += 4;         \
+    }                                                                  \
+  /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */     \
+  regmask = read_memory_integer (pc + 2, 2);                           \
+  if (0044327 == read_memory_integer (pc, 2))                          \
+    { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
+      for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)           \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; }    \
+  else if (0044347 == read_memory_integer (pc, 2))                     \
+    { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
+      for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)          \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr -= 4); }                \
+  else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2))             \
+    { regnum = 0xf & read_memory_integer (pc, 2); pc += 2;             \
+      (frame_saved_regs).regs[regnum] = (next_addr -= 4); }            \
+  /* clrw -(sp); movw ccr,-(sp) may follow.  */                                \
+  if (0x426742e7 == read_memory_integer (pc, 4))                       \
+    (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4);             \
+  lose: ;                                                              \
+  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame;            \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;                \
+}
+#endif /* no 68881.  */
+#endif /* no FIND_FRAME_SAVED_REGS.  */
+
+/* Note that stuff for calling inferior functions is not in this file
+   because the call dummy is different for different breakpoint
+   instructions, which are different on different systems.  Perhaps
+   they could be merged, but I haven't bothered.  */
diff --git a/gdb/tm-altos.h b/gdb/tm-altos.h
new file mode 100644 (file)
index 0000000..ea92f8b
--- /dev/null
@@ -0,0 +1,130 @@
+/* Definitions to make GDB run on an Altos 3068 (m68k running SVR2)
+   Copyright (C) 1987,1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0x4e, 0x4e}
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#undef NAMES_HAVE_UNDERSCORE
+
+/* Exec files and symbol tables are in COFF format */
+
+#define COFF_FORMAT
+#define COFF_NO_LONG_FILE_NAMES
+
+/* Address of end of stack space.  */
+
+/*#define STACK_END_ADDR (0xffffff)*/
+#define STACK_END_ADDR (0x1000000)
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.
+   On the Altos, the kernel resets the pc to the trap instr */
+
+#define DECR_PC_AFTER_BREAK 0
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                         \
+  register CORE_ADDR fp;                                               \
+  register int regnum;                                                 \
+  struct frame_saved_regs fsr;                                         \
+  struct frame_info *fi;                                               \
+  char raw_buffer[12];                                                 \
+  fi = get_frame_info (frame);                                         \
+  fp = fi->frame;                                                      \
+  get_frame_saved_regs (fi, &fsr);                                     \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    if (fsr.regs[regnum])                                              \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    if (fsr.regs[regnum])                                              \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                             \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
+  write_register (SP_REGNUM, fp + 8);                                  \
+  flush_cached_frames ();                                              \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     fmovem 0xff,-(sp)
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     bpt
+     nop
+Note this is 28 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4e4e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
+\f
+#include "tm-68k.h"
diff --git a/gdb/tm-altosgas.h b/gdb/tm-altosgas.h
new file mode 100644 (file)
index 0000000..eb342ea
--- /dev/null
@@ -0,0 +1,28 @@
+/* Definitions to make GDB run on an Altos 3068 using COFF encapsulation.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define COFF_ENCAPSULATE
+
+#include "m-altos.h"
+
+#undef COFF_FORMAT
+#undef COFF_NO_LONG_FILE_NAMES
+#define NAMES_HAVE_UNDERSCORE
+
+#define READ_DBX_FORMAT
diff --git a/gdb/tm-arm.h b/gdb/tm-arm.h
new file mode 100644 (file)
index 0000000..c061399
--- /dev/null
@@ -0,0 +1,415 @@
+/* Definitions to make GDB target for an ARM under RISCiX (4.3bsd).
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* IEEE format floating point */
+
+#define IEEE_FLOAT
+
+/* I provide my own xfer_core_file to cope with shared libraries */
+
+#define XFER_CORE_FILE
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc) pc = skip_prologue(pc)
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) (read_register (LR_REGNUM) & 0x03fffffc)
+
+/* I don't know the real values for these.  */
+#define TARGET_UPAGES UPAGES
+#define TARGET_NBPG NBPG
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0x01000000 - (TARGET_UPAGES * TARGET_NBPG))
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0x00,0x00,0x18,0xef} /* BKPT_SWI from <sys/ptrace.h> */
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) \
+      ((read_memory_integer(pc, 4) & 0x0fffffff == 0x01b0f00e) || \
+       (read_memory_integer(pc, 4) & 0x0ffff800 == 0x09eba800))
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes.  */
+
+#define INVALID_FLOAT(p, len) 0
+
+/* code to execute to print interesting information about the
+ * floating point processor (if any)
+ * No need to define if there is nothing to do.
+ */
+#define FLOAT_INFO { arm_float_info (); }
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+/* Note: I make a fake copy of the pc in register 25 (calling it ps) so
+   that I can clear the status bits from pc (register 15) */
+
+#define NUM_REGS 26
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES \
+      { "a1", "a2", "a3", "a4",                                        \
+       "v1", "v2", "v3", "v4", "v5", "v6",                     \
+        "sl", "fp", "ip", "sp", "lr", "pc",                    \
+        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "fps", "ps" }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define AP_REGNUM 11
+#define FP_REGNUM 11           /* Contains address of executing stack frame */
+#define SP_REGNUM 13           /* Contains address of top of stack */
+#define LR_REGNUM 14           /* address to return to from a function call */
+#define PC_REGNUM 15           /* Contains program counter */
+#define F0_REGNUM 16           /* first floating point register */
+#define FPS_REGNUM 24          /* floating point status register */
+#define PS_REGNUM 25           /* Contains processor status */
+
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (16*4 + 12*8 + 4 + 4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) (((N) < F0_REGNUM) ? (N)*4 : \
+                         (((N) < PS_REGNUM) ? 16*4 + ((N) - 16)*12 : \
+                          16*4 + 8*12 + ((N) - FPS_REGNUM) * 4))
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the vax, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) (((N) < F0_REGNUM || (N) >= FPS_REGNUM) ? 4 : 12)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the vax, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((N) < F0_REGNUM || (N) >= FPS_REGNUM) ? 4 : 8)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 12
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) ((unsigned)(N) - F0_REGNUM < 8)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  if (REGISTER_CONVERTIBLE(REGNUM))                                    \
+      convert_from_extended((FROM), (TO));                             \
+  else                                                                 \
+      bcopy ((FROM), (TO), 4);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  if (REGISTER_CONVERTIBLE(REGNUM))                    \
+    convert_to_extended((FROM), (TO));                 \
+  else                                                 \
+    bcopy ((FROM), (TO), 4);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((unsigned)(N) - F0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
+\f
+/* The system C compiler uses a similar structure return convention to gcc */
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 4)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { write_register (0, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)                               \
+    convert_from_extended(REGBUF + REGISTER_BYTE (F0_REGNUM), VALBUF); \
+  else                                                                 \
+    bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) {                             \
+    char _buf[MAX_REGISTER_RAW_SIZE];                                  \
+    convert_to_extended(VALBUF, _buf);                                 \
+    write_register_bytes (REGISTER_BYTE (F0_REGNUM), _buf, MAX_REGISTER_RAW_SIZE); \
+  } else                                                               \
+    write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+/* Specify that for the native compiler variables for a particular
+   lexical context are listed after the beginning LBRAC instead of
+   before in the executables list of symbols.  */
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (!(gcc_p))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the ARM, the frame's nominal address is the FP value,
+   and 12 bytes before comes the saved previous FP value as a 4-byte word.  */
+
+#define FRAME_CHAIN(thisframe)  \
+  ((thisframe)->pc >= first_object_file_end ? \
+   read_memory_integer ((thisframe)->frame - 12, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+{                                                      \
+  CORE_ADDR func_start, after_prologue;                        \
+  func_start = (get_pc_function_start ((FI)->pc) +     \
+               FUNCTION_START_OFFSET);                 \
+  after_prologue = func_start;                         \
+  SKIP_PROLOGUE (after_prologue);                      \
+  (FRAMELESS) = (after_prologue == func_start);                \
+}
+
+/* Saved Pc.  */
+
+#define FRAME_SAVED_PC(FRAME) \
+  (read_memory_integer ((FRAME)->frame - 4, 4) & 0x03fffffc)
+
+#define FRAME_ARGS_ADDRESS(fi) (fi->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi) (numargs = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{                                                                              \
+    register int regnum;                                                       \
+    register int frame;                                                                \
+    register int next_addr;                                                    \
+    register int return_data_save;                                             \
+    register int saved_register_mask;                                          \
+    bzero (&frame_saved_regs, sizeof frame_saved_regs);                                \
+    frame = (frame_info)->frame;                                               \
+    return_data_save = read_memory_integer(frame, 4) & 0x03fffffc - 12;                \
+    saved_register_mask =                                                      \
+       read_memory_integer(return_data_save, 4);                               \
+    next_addr = frame - 12;                                                    \
+    for (regnum = 4; regnum < 10; regnum++)                                    \
+       if (saved_register_mask & (1<<regnum)) {                                \
+           next_addr -= 4;                                                     \
+           (frame_saved_regs).regs[regnum] = next_addr;                        \
+       }                                                                       \
+    if (read_memory_integer(return_data_save + 4, 4) == 0xed6d7103) {          \
+       next_addr -= 12;                                                        \
+       (frame_saved_regs).regs[F0_REGNUM + 7] = next_addr;                     \
+    }                                                                          \
+    if (read_memory_integer(return_data_save + 8, 4) == 0xed6d6103) {          \
+       next_addr -= 12;                                                        \
+       (frame_saved_regs).regs[F0_REGNUM + 6] = next_addr;                     \
+    }                                                                          \
+    if (read_memory_integer(return_data_save + 12, 4) == 0xed6d5103) {         \
+       next_addr -= 12;                                                        \
+       (frame_saved_regs).regs[F0_REGNUM + 5] = next_addr;                     \
+    }                                                                          \
+    if (read_memory_integer(return_data_save + 16, 4) == 0xed6d4103) {         \
+       next_addr -= 12;                                                        \
+       (frame_saved_regs).regs[F0_REGNUM + 4] = next_addr;                     \
+    }                                                                          \
+    (frame_saved_regs).regs[SP_REGNUM] = next_addr;                            \
+    (frame_saved_regs).regs[PC_REGNUM] = frame - 4;                            \
+    (frame_saved_regs).regs[PS_REGNUM] = frame - 4;                            \
+    (frame_saved_regs).regs[FP_REGNUM] = frame - 12;                           \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{                                                              \
+    register CORE_ADDR sp = read_register (SP_REGNUM);         \
+    register int regnum;                                       \
+    /* opcode for ldmdb fp,{v1-v6,fp,ip,lr,pc}^ */             \
+    sp = push_word(sp, 0xe92dbf0); /* dummy return_data_save ins */ \
+    /* push a pointer to the dummy instruction minus 12 */     \
+    sp = push_word(sp, read_register (SP_REGNUM) - 16);                \
+    sp = push_word(sp, read_register (PS_REGNUM));             \
+    sp = push_word(sp, read_register (SP_REGNUM));             \
+    sp = push_word(sp, read_register (FP_REGNUM));             \
+    for (regnum = 9; regnum >= 4; regnum --)                   \
+       sp = push_word(sp, read_register (regnum));             \
+    write_register (FP_REGNUM, read_register (SP_REGNUM) - 8); \
+    write_register (SP_REGNUM, sp); }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME \
+{                                                                      \
+    register CORE_ADDR fp = read_register (FP_REGNUM);                 \
+    register unsigned long return_data_save =                          \
+       read_memory_integer ( (read_memory_integer (fp, 4) &            \
+                              0x03fffffc)  - 12, 4);                   \
+    register int regnum;                                               \
+    write_register (PS_REGNUM, read_memory_integer (fp - 4, 4));       \
+    write_register (PC_REGNUM, read_register (PS_REGNUM) & 0x03fffffc);        \
+    write_register (SP_REGNUM, read_memory_integer (fp - 8, 4));       \
+    write_register (FP_REGNUM, read_memory_integer (fp - 12, 4));      \
+    fp -= 12;                                                          \
+    for (regnum = 9; regnum >= 4; regnum--)                            \
+       if (return_data_save & (1<<regnum)) {                           \
+           fp -= 4;                                                    \
+           write_register (regnum, read_memory_integer(fp, 4));        \
+       }                                                               \
+    flush_cached_frames ();                                            \
+    set_current_frame (create_new_frame (read_register (FP_REGNUM),    \
+                                        read_pc ()));                  \
+}
+
+/* This sequence of words is the instructions
+
+     ldmia     sp!,{a1-a4}
+     mov       lk,pc
+     bl                *+8
+     swi       bkpt_swi
+
+   Note this is 16 bytes.  */
+
+#define CALL_DUMMY {0xe8bd000f, 0xe1a0e00f, 0xeb000000, 0xef180000}
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{                                                                              \
+    register enum type_code code = TYPE_CODE (type);                           \
+    register nargs_in_registers, struct_return = 0;                            \
+    /* fix the load-arguments mask to move the first 4 or less arguments       \
+       into a1-a4 but make sure the structure return address in a1 is          \
+       not disturbed if the function is returning a structure */               \
+    if ((code == TYPE_CODE_STRUCT ||                                           \
+        code == TYPE_CODE_UNION ||                                             \
+        code == TYPE_CODE_ARRAY) &&                                            \
+       TYPE_LENGTH (type) > 4) {                                               \
+       nargs_in_registers = min(nargs + 1, 4);                                 \
+       struct_return = 1;                                                      \
+    } else                                                                     \
+       nargs_in_registers = min(nargs, 4);                                     \
+    *(char *) dummyname = (1 << nargs_in_registers) - 1 - struct_return;       \
+    *(int *)((char *) dummyname + 8) =                                         \
+       (((fun - (pc + 16)) / 4) & 0x00ffffff) | 0xeb000000; }
diff --git a/gdb/tm-bigmips.h b/gdb/tm-bigmips.h
new file mode 100644 (file)
index 0000000..7d6bae5
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+#include "tm-mips.h"
diff --git a/gdb/tm-convex.h b/gdb/tm-convex.h
new file mode 100644 (file)
index 0000000..5a001f1
--- /dev/null
@@ -0,0 +1,563 @@
+/* Definitions to make GDB run on Convex Unix (4bsd)
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* I don't know if this will work for cross-debugging, even if you do get
+   the right files.  */
+/* Include certain files for dbxread.c  */
+#include <convex/filehdr.h>
+#include <convex/opthdr.h>
+#include <convex/scnhdr.h>
+#include <nlist.h>
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* There is come problem with the debugging symbols generated by the
+   compiler such that the debugging symbol for the first line of a
+   function overlap with the function prologue.  */
+#define PROLOGUE_FIRSTLINE_OVERLAP
+
+/* When convex pcc says CHAR or SHORT, it provides the correct address.  */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Symbol types to ignore.  */
+/* 0xc4 is N_MONPT.  Use the numeric value for the benefit of people
+   with (rather) old OS's.  */
+#define IGNORE_SYMBOL(TYPE) \
+    (((TYPE) & ~N_EXT) == N_TBSS       \
+     || ((TYPE) & ~N_EXT) == N_TDATA   \
+     || ((TYPE) & ~N_EXT) == 0xc4)
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.
+   Convex prolog is:
+       [sub.w #-,sp]           in one of 3 possible sizes
+       [mov psw,-              fc/vc main program prolog
+        and #-,-                 (skip it because the "mov psw" saves the
+       mov -,psw]                 T bit, so continue gets a surprise trap)
+       [and #-,sp]             fc/vc O2 main program prolog
+       [ld.- -(ap),-]          pcc/gcc register arg loads
+*/
+
+#define SKIP_PROLOGUE(pc)  \
+{ int op, ix;                                                          \
+  op = read_memory_integer (pc, 2);                                    \
+  if ((op & 0xffc7) == 0x5ac0) pc += 2;                                        \
+  else if (op == 0x1580) pc += 4;                                      \
+  else if (op == 0x15c0) pc += 6;                                      \
+  if ((read_memory_integer (pc, 2) & 0xfff8) == 0x7c40                 \
+      && (read_memory_integer (pc + 2, 2) & 0xfff8) == 0x1240          \
+      && (read_memory_integer (pc + 8, 2) & 0xfff8) == 0x7c48)         \
+    pc += 10;                                                          \
+  if (read_memory_integer (pc, 2) == 0x1240) pc += 6;                  \
+  for (;;) {                                                           \
+    op = read_memory_integer (pc, 2);                                  \
+    ix = (op >> 3) & 7;                                                        \
+    if (ix != 6) break;                                                        \
+    if ((op & 0xfcc0) == 0x3000) pc += 4;                              \
+    else if ((op & 0xfcc0) == 0x3040) pc += 6;                         \
+    else if ((op & 0xfcc0) == 0x2800) pc += 4;                         \
+    else if ((op & 0xfcc0) == 0x2840) pc += 6;                         \
+    else break;}}
+
+/* Immediately after a function call, return the saved pc.
+   (ignore frame and return *$sp so we can handle both calls and callq) */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+    read_memory_integer (read_register (SP_REGNUM), 4)
+
+/* Address of end of stack space.
+   This is ((USRSTACK + 0xfff) & -0x1000)) from <convex/vmparam.h> but
+   that expression depends on the kernel version; instead, fetch a
+   page-zero pointer and get it from that.  This will be invalid if
+   they ever change the way bkpt signals are delivered.  */
+
+#define STACK_END_ADDR (0xfffff000 & *(unsigned *) 0x80000050)
+
+/* User-mode traps push an extended rtn block,
+   then fault with one of the following PCs */
+
+#define is_trace_pc(pc)  ((unsigned) ((pc) - (*(int *) 0x80000040)) <= 4)
+#define is_arith_pc(pc)  ((unsigned) ((pc) - (*(int *) 0x80000044)) <= 4)
+#define is_break_pc(pc)  ((unsigned) ((pc) - (*(int *) 0x80000050)) <= 4)
+
+/* We need to manipulate trap bits in the psw */
+
+#define PSW_TRAP_FLAGS 0x69670000
+#define PSW_T_BIT      0x08000000
+#define PSW_S_BIT      0x01000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction. (bkpt)  */
+
+#define BREAKPOINT {0x7d,0x50}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT but not always.
+   (The break PC needs to be decremented by 2, but we do it when the
+   break frame is recognized and popped.  That way gdb can tell breaks
+   from trace traps with certainty.) */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction. (rtn or rtnq) */
+
+#define ABOUT_TO_RETURN(pc) \
+    ((read_memory_integer (pc, 2) & 0xffe0) == 0x7c80)
+
+/* Return 1 if P points to an invalid floating point value. */
+
+#define INVALID_FLOAT(p,len)   0
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long long
+
+/* Number of machine registers */
+
+#define NUM_REGS 26
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES {"pc","psw","fp","ap","a5","a4","a3","a2","a1","sp",\
+                       "s7","s6","s5","s4","s3","s2","s1","s0",\
+                       "S7","S6","S5","S4","S3","S2","S1","S0"}
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define S0_REGNUM 25           /* the real S regs */
+#define S7_REGNUM 18
+#define s0_REGNUM 17           /* low-order halves of S regs */
+#define s7_REGNUM 10
+#define SP_REGNUM 9            /* A regs */
+#define A1_REGNUM 8
+#define A5_REGNUM 4
+#define AP_REGNUM 3
+#define FP_REGNUM 2            /* Contains address of executing stack frame */
+#define PS_REGNUM 1            /* Contains processor status */
+#define PC_REGNUM 0            /* Contains program counter */
+
+/* convert dbx stab register number (from `r' declaration) to a gdb REGNUM */
+
+#define STAB_REG_TO_REGNUM(value) \
+      ((value) < 8 ? S0_REGNUM - (value) : SP_REGNUM - ((value) - 8))
+
+/* Vector register numbers, not handled as ordinary regs.
+   They are treated as convenience variables whose values are read
+   from the inferior when needed.  */
+
+#define V0_REGNUM 0
+#define V7_REGNUM 7
+#define VM_REGNUM 8
+#define VS_REGNUM 9
+#define VL_REGNUM 10
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (4*10 + 8*8)
+
+/* Index within `registers' of the first byte of the space for
+   register N.
+   NB: must match structure of struct syscall_context for correct operation */
+
+#define REGISTER_BYTE(N) ((N) < s7_REGNUM ? 4*(N) : \
+                         (N) < S7_REGNUM ? 44 + 8 * ((N)-s7_REGNUM) : \
+                                           40 + 8 * ((N)-S7_REGNUM))
+
+/* Number of bytes of storage in the actual machine representation
+   for register N. */
+
+#define REGISTER_RAW_SIZE(N) ((N) < S7_REGNUM ? 4 : 8)
+
+/* Number of bytes of storage in the program's representation
+   for register N.   */
+
+#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+   bcopy ((FROM), (TO), REGISTER_RAW_SIZE (REGNUM));
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), REGISTER_RAW_SIZE (REGNUM));
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+   ((N) < S7_REGNUM ? builtin_type_int : builtin_type_long_long)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { write_register (A1_REGNUM, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (&((char *) REGBUF) [REGISTER_BYTE (S0_REGNUM) + \
+                            8 - TYPE_LENGTH (TYPE)],\
+        VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+    write_register_bytes (REGISTER_BYTE (S0_REGNUM), VALBUF, 8)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+    (*(int *) & ((char *) REGBUF) [REGISTER_BYTE (s0_REGNUM)])
+
+/* Define trapped internal variable hooks to read and write
+   vector and communication registers.  */
+
+#define IS_TRAPPED_INTERNALVAR is_trapped_internalvar
+#define VALUE_OF_TRAPPED_INTERNALVAR value_of_trapped_internalvar
+#define SET_TRAPPED_INTERNALVAR set_trapped_internalvar
+
+extern struct value *value_of_trapped_internalvar ();
+
+/* Hooks to read data from soff exec and core files,
+   and to describe the files.  */
+
+#define XFER_CORE_FILE
+#define FILES_INFO_HOOK print_maps
+
+/* Hook to call to print a typeless integer value, normally printed in decimal.
+   For convex, use hex instead if the number looks like an address.  */
+
+#define PRINT_TYPELESS_INTEGER decout
+
+/* For the native compiler, variables for a particular lexical context
+   are listed after the beginning LBRAC instead of before in the
+   executables list of symbols.  Using "gcc_compiled." to distinguish
+   between GCC and native compiler doesn't work on Convex because the
+   linker sorts the symbols to put "gcc_compiled." in the wrong place.
+   desc is nonzero for native, zero for gcc.   */
+#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (desc != 0)
+
+/* Pcc occaisionally puts an SO where there should be an SOL.   */
+#define PCC_SOL_BROKEN
+
+/* Cannot execute with pc on the stack.  */
+#define CANNOT_EXECUTE_STACK
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame_info with a frame's nominal address in fi->frame,
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* (caller fp is saved at 8(fp)) */
+
+#define FRAME_CHAIN(fi)   (read_memory_integer ((fi)->frame + 8, 4))
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.
+   On convex, check at the return address for `callq' -- if so, frameless,
+   otherwise, not.  */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+{                                                                      \
+  extern CORE_ADDR text_start, text_end;                               \
+  CORE_ADDR call_addr = SAVED_PC_AFTER_CALL (FI);                      \
+  (FRAMELESS) = (call_addr >= text_start && call_addr < text_end       \
+                && read_memory_integer (call_addr - 6, 1) == 0x22);    \
+}
+
+#define FRAME_SAVED_PC(fi) (read_memory_integer ((fi)->frame, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) (read_memory_integer ((fi)->frame + 12, 4))
+
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)  \
+{ numargs = read_memory_integer (FRAME_ARGS_ADDRESS (fi) - 4, 4); \
+  if (numargs < 0 || numargs >= 256) numargs = -1;}
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+/* Normal (short) frames save only PC, FP, (callee's) AP.  To reasonably
+   handle gcc and pcc register variables, scan the code following the
+   call for the instructions the compiler inserts to reload register
+   variables from stack slots and record the stack slots as the saved
+   locations of those registers.  This will occasionally identify some
+   random load as a saved register; this is harmless.  vc does not
+   declare its register allocation actions in the stabs.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{ register int regnum;                                                 \
+  register int frame_length =  /* 3 short, 2 long, 1 extended, 0 context */\
+      (read_memory_integer ((frame_info)->frame + 4, 4) >> 25) & 3;    \
+  register CORE_ADDR frame_fp =                                                \
+      read_memory_integer ((frame_info)->frame + 8, 4);                        \
+  register CORE_ADDR next_addr;                                                \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 0;                \
+  (frame_saved_regs).regs[PS_REGNUM] = (frame_info)->frame + 4;                \
+  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[AP_REGNUM] = frame_fp + 12;                  \
+  next_addr = (frame_info)->frame + 12;                                        \
+  if (frame_length < 3)                                                        \
+    for (regnum = A5_REGNUM; regnum < SP_REGNUM; ++regnum)             \
+      (frame_saved_regs).regs[regnum] = (next_addr += 4);              \
+  if (frame_length < 2)                                                        \
+    (frame_saved_regs).regs[SP_REGNUM] = (next_addr += 4);             \
+  next_addr -= 4;                                                      \
+  if (frame_length < 3)                                                        \
+    for (regnum = S7_REGNUM; regnum < S0_REGNUM; ++regnum)             \
+      (frame_saved_regs).regs[regnum] = (next_addr += 8);              \
+  if (frame_length < 2)                                                        \
+    (frame_saved_regs).regs[S0_REGNUM] = (next_addr += 8);             \
+  else                                                                 \
+    (frame_saved_regs).regs[SP_REGNUM] = next_addr + 8;                        \
+  if (frame_length == 3) {                                             \
+    CORE_ADDR pc = read_memory_integer ((frame_info)->frame, 4);       \
+    int op, ix, disp;                                                  \
+    op = read_memory_integer (pc, 2);                                  \
+    if ((op & 0xffc7) == 0x1480) pc += 4;      /* add.w #-,sp */       \
+    else if ((op & 0xffc7) == 0x58c0) pc += 2; /* add.w #-,sp */       \
+    op = read_memory_integer (pc, 2);                                  \
+    if ((op & 0xffc7) == 0x2a06) pc += 4;      /* ld.w -,ap */         \
+    for (;;) {                                                         \
+      op = read_memory_integer (pc, 2);                                        \
+      ix = (op >> 3) & 7;                                              \
+      if ((op & 0xfcc0) == 0x2800) {           /* ld.- -,ak */         \
+        regnum = SP_REGNUM - (op & 7);                                 \
+       disp = read_memory_integer (pc + 2, 2);                         \
+       pc += 4;}                                                       \
+      else if ((op & 0xfcc0) == 0x2840) {      /* ld.- -,ak */         \
+        regnum = SP_REGNUM - (op & 7);                                 \
+       disp = read_memory_integer (pc + 2, 4);                         \
+       pc += 6;}                                                       \
+      if ((op & 0xfcc0) == 0x3000) {           /* ld.- -,sk */         \
+        regnum = S0_REGNUM - (op & 7);                                 \
+       disp = read_memory_integer (pc + 2, 2);                         \
+       pc += 4;}                                                       \
+      else if ((op & 0xfcc0) == 0x3040) {      /* ld.- -,sk */         \
+        regnum = S0_REGNUM - (op & 7);                                 \
+       disp = read_memory_integer (pc + 2, 4);                         \
+       pc += 6;}                                                       \
+      else if ((op & 0xff00) == 0x7100) {      /* br crossjump */      \
+        pc += 2 * (char) op;                                           \
+        continue;}                                                     \
+      else if (op == 0x0140) {                 /* jmp crossjump */     \
+        pc = read_memory_integer (pc + 2, 4);                          \
+        continue;}                                                     \
+      else break;                                                      \
+      if ((frame_saved_regs).regs[regnum])                             \
+       break;                                                          \
+      if (ix == 7) disp += frame_fp;                                   \
+      else if (ix == 6) disp += read_memory_integer (frame_fp + 12, 4);        \
+      else if (ix != 0) break;                                         \
+      (frame_saved_regs).regs[regnum] =                                        \
+       disp - 8 + (1 << ((op >> 8) & 3));                              \
+      if (regnum >= S7_REGNUM)                                         \
+        (frame_saved_regs).regs[regnum - S0_REGNUM + s0_REGNUM] =      \
+         disp - 4 + (1 << ((op >> 8) & 3));                            \
+    }                                                                  \
+  }                                                                    \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char buf[8];                                                         \
+  long word;                                                           \
+  for (regnum = S0_REGNUM; regnum >= S7_REGNUM; --regnum) {            \
+    read_register_bytes (REGISTER_BYTE (regnum), buf, 8);              \
+    sp = push_bytes (sp, buf, 8);}                                     \
+  for (regnum = SP_REGNUM; regnum >= FP_REGNUM; --regnum) {            \
+    word = read_register (regnum);                                     \
+    sp = push_bytes (sp, &word, 4);}                                           \
+  word = (read_register (PS_REGNUM) &~ (3<<25)) | (1<<25);             \
+  sp = push_bytes (sp, &word, 4);                                      \
+  word = read_register (PC_REGNUM);                                    \
+  sp = push_bytes (sp, &word, 4);                                      \
+  write_register (SP_REGNUM, sp);                                      \
+  write_register (FP_REGNUM, sp);                                      \
+  write_register (AP_REGNUM, sp);}
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  do {\
+  register CORE_ADDR fp = read_register (FP_REGNUM);       \
+  register int regnum;                                     \
+  register int frame_length =  /* 3 short, 2 long, 1 extended, 0 context */ \
+      (read_memory_integer (fp + 4, 4) >> 25) & 3;          \
+  char buf[8];                                             \
+  write_register (PC_REGNUM, read_memory_integer (fp, 4));  \
+  write_register (PS_REGNUM, read_memory_integer (fp += 4, 4));  \
+  write_register (FP_REGNUM, read_memory_integer (fp += 4, 4));  \
+  write_register (AP_REGNUM, read_memory_integer (fp += 4, 4));  \
+  if (frame_length < 3)                                     \
+    for (regnum = A5_REGNUM; regnum < SP_REGNUM; ++regnum)   \
+      write_register (regnum, read_memory_integer (fp += 4, 4)); \
+  if (frame_length < 2)                                             \
+    write_register (SP_REGNUM, read_memory_integer (fp += 4, 4)); \
+  fp -= 4;                                                     \
+  if (frame_length < 3)                                        \
+    for (regnum = S7_REGNUM; regnum < S0_REGNUM; ++regnum) {   \
+      read_memory (fp += 8, buf, 8);                           \
+      write_register_bytes (REGISTER_BYTE (regnum), buf, 8);}   \
+  if (frame_length < 2)        {                                       \
+    read_memory (fp += 8, buf, 8);                             \
+    write_register_bytes (REGISTER_BYTE (regnum), buf, 8);}     \
+  else write_register (SP_REGNUM, fp + 8);                     \
+  flush_cached_frames ();                                      \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM), \
+                                      read_pc ()));            \
+} while (0)
+
+/* This sequence of words is the instructions
+     mov sp,ap
+     pshea 69696969
+     calls 32323232
+     bkpt
+   Note this is 16 bytes.  */
+
+#define CALL_DUMMY {0x50860d4069696969LL,0x2140323232327d50LL}
+
+#define CALL_DUMMY_LENGTH 16
+
+#define CALL_DUMMY_START_OFFSET 0
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ *(int *)((char *) dummyname + 4) = nargs;    \
+  *(int *)((char *) dummyname + 10) = fun; }
+\f
+/* Defs to read soff symbol tables, see dbxread.c */
+
+#define NUMBER_OF_SYMBOLS    ((long) opthdr.o_nsyms)
+#define STRING_TABLE_OFFSET  ((long) filehdr.h_strptr)
+#define SYMBOL_TABLE_OFFSET  ((long) opthdr.o_symptr)
+#define STRING_TABLE_SIZE    ((long) filehdr.h_strsiz)
+#define SIZE_OF_TEXT_SEGMENT ((long) txthdr.s_size)
+#define ENTRY_POINT          ((long) opthdr.o_entry)
+
+#define READ_STRING_TABLE_SIZE(BUFFER) \
+    (BUFFER = STRING_TABLE_SIZE)
+
+#define DECLARE_FILE_HEADERS \
+  FILEHDR filehdr;                                                     \
+  OPTHDR opthdr;                                                       \
+  SCNHDR txthdr
+
+#define READ_FILE_HEADERS(DESC,NAME) \
+{                                                                      \
+  int n;                                                               \
+  val = myread (DESC, &filehdr, sizeof filehdr);                       \
+  if (val < 0)                                                         \
+    perror_with_name (NAME);                                           \
+  if (! IS_SOFF_MAGIC (filehdr.h_magic))                               \
+    error ("%s: not an executable file.", NAME);                       \
+  lseek (DESC, 0L, 0);                                                 \
+  if (myread (DESC, &filehdr, sizeof filehdr) < 0)                     \
+    perror_with_name (NAME);                                           \
+  if (myread (DESC, &opthdr, filehdr.h_opthdr) <= 0)                   \
+    perror_with_name (NAME);                                           \
+  for (n = 0; n < filehdr.h_nscns; n++)                                        \
+    {                                                                  \
+      if (myread (DESC, &txthdr, sizeof txthdr) < 0)                   \
+       perror_with_name (NAME);                                        \
+      if ((txthdr.s_flags & S_TYPMASK) == S_TEXT)                      \
+       break;                                                          \
+    }                                                                  \
+}
diff --git a/gdb/tm-hp300bsd.h b/gdb/tm-hp300bsd.h
new file mode 100644 (file)
index 0000000..d4601bf
--- /dev/null
@@ -0,0 +1,142 @@
+/* Parameters for execution on a Hewlett-Packard 9000/300, running bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Configuration file for HP9000/300 series machine running
+ * University of Utah's 4.3bsd port.  This is NOT for HP-UX.
+ * Problems to hpbsd-bugs@cs.utah.edu
+ */
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+#define TARGET_NBPG 4096
+#define TARGET_UPAGES 3
+
+/* On the HP300, sigtramp is in the u area.  Gak!  User struct is not
+   mapped to the same virtual address in user/kernel address space
+   (hence STACK_END_ADDR as opposed to KERNEL_U_ADDR).  This tests
+   for the whole u area, since we don't necessarily have hp300bsd
+   include files around.  */
+#define IN_SIGTRAMP(pc, name) \
+  ((pc) >= STACK_END_ADDR   \
+   && (pc) < STACK_END_ADDR + TARGET_UPAGES * TARGET_NBPG \
+   )
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0xfff00000
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0x4e, 0x42}
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_gen (regnum, raw_buffer);                          \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                        \
+  char raw_buffer[12];                                          \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)         \
+    if (fsr.regs[regnum])                                       \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                 \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                      \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     fmovem 0xff,-(sp)
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     trap #2
+     nop
+Note this is 28 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e424e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
+\f
+#define HAVE_68881
+
+#include "tm-68k.h"
diff --git a/gdb/tm-hp300hpux.h b/gdb/tm-hp300hpux.h
new file mode 100644 (file)
index 0000000..67c9323
--- /dev/null
@@ -0,0 +1,122 @@
+/* Parameters for execution on an HP 9000 model 320, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0x4e, 0x41}
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0xFFF00000
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                        \
+  char raw_buffer[12];                                          \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)         \
+    if (fsr.regs[regnum])                                       \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                 \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                      \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
+                                      read_pc ()));}
+
+/* This sequence of words is the instructions
+     fmovem 0xff,-(sp)
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     bpt
+     nop
+Note this is 28 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
+\f
+#include HAVE_68881
+
+#include "tm-68k.h"
diff --git a/gdb/tm-i386v-g.h b/gdb/tm-i386v-g.h
new file mode 100644 (file)
index 0000000..e1dc3fd
--- /dev/null
@@ -0,0 +1,38 @@
+/* Macro definitions for i386 using the GNU object file format.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ * 
+ * i386gnu: COFF_ENCAPSULATE
+ */
+
+
+#define COFF_ENCAPSULATE
+
+#include "tm-i386v.h"
+
+/* The version in m-i386.h is for COFF.  */
+#undef N_SET_MAGIC
+
+#define NAMES_HAVE_UNDERSCORE
+
+#undef COFF_FORMAT
+#define READ_DBX_FORMAT
diff --git a/gdb/tm-i386v.h b/gdb/tm-i386v.h
new file mode 100644 (file)
index 0000000..59f8967
--- /dev/null
@@ -0,0 +1,307 @@
+/* Macro defintions for i386.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* define this if you don't have the extension to coff that allows
+ * file names to appear in the string table
+ * (aux.x_file.x_foff)
+ */
+#define COFF_NO_LONG_FILE_NAMES
+
+/* turn this on when rest of gdb is ready */
+/* #define IEEE_FLOAT */
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+/* #define NAMES_HAVE_UNDERSCORE */
+
+/* Specify debugger information format.  */
+
+/* #define READ_DBX_FORMAT */
+#define COFF_FORMAT
+
+/* number of traps that happen between exec'ing the shell 
+ * to run an inferior, and when we finally get to 
+ * the inferior code.  This is 2 on most implementations.
+ */
+#define START_INFERIOR_TRAPS_EXPECTED 4
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(frompc)   {(frompc) = i386_skip_prologue((frompc));}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+  (read_memory_integer (read_register (SP_REGNUM), 4))
+
+/* This is only supposed to work in execcore.c, where x == 0 and
+   this is called before any other fields are filled in.  */
+#define N_SET_MAGIC(aouthdr, x) \
+  bzero ((char *) &aouthdr, sizeof aouthdr)
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0x80000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xcc}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 1
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the 386.  */
+
+#define INVALID_FLOAT(p, len) (0)
+
+/* code to execute to print interesting information about the
+ * floating point processor (if any)
+ * No need to define if there is nothing to do.
+ */
+#define FLOAT_INFO { i386_float_info (); }
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 16
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+/* the order of the first 8 registers must match the compiler's 
+ * numbering scheme (which is the same as the 386 scheme)
+ * also, this table must match regmap in i386-pinsn.c.
+ */
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+                        "esp", "ebp", "esi", "edi", \
+                        "eip", "ps", "cs", "ss", \
+                        "ds", "es", "fs", "gs", \
+                        }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define FP_REGNUM 5            /* Contains address of executing stack frame */
+#define SP_REGNUM 4            /* Contains address of top of stack */
+
+#define PC_REGNUM 8
+#define PS_REGNUM 9
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+       (addr) = i386_register_u_addr ((blockend),(regno));
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+#define REGISTER_RAW_SIZE(N) (4)
+
+/* Number of bytes of storage in the program's representation
+   for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) {bcopy ((FROM), (TO), 4);}
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) {bcopy ((FROM), (TO), 4);}
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { (SP) -= sizeof (ADDR);             \
+    write_memory ((SP), &(ADDR), sizeof (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+#define FRAME_CHAIN(thisframe) \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi) (numargs) = i386_frame_num_args(fi)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  { i386_pop_frame (); }
+
+/* this is 
+ *   call 11223344 (32 bit relative)
+ *   int3
+ */
+
+#define CALL_DUMMY { 0x223344e8, 0xcc11 }
+
+#define CALL_DUMMY_LENGTH 8
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ \
+       int from, to, delta, loc; \
+       loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \
+       from = loc + 5; \
+       to = (int)(fun); \
+       delta = to - from; \
+       *(int *)((char *)(dummyname) + 1) = delta; \
+}
diff --git a/gdb/tm-i960.h b/gdb/tm-i960.h
new file mode 100644 (file)
index 0000000..5ddf8c2
--- /dev/null
@@ -0,0 +1,399 @@
+/* Parameters for target machine Intel 960, for GDB, the GNU debugger.
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Contributed by Intel Corporation.
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Definitions to target GDB to any i960.  */
+
+#ifndef I80960
+#define I80960
+#endif
+
+/* Hook for the SYMBOL_CLASS of a parameter when decoding DBX symbol
+   information.  In the i960, parameters can be stored as locals or as
+   args, depending on the type of the debug record.
+
+   From empirical observation, gcc960 uses N_LSYM to indicate
+   arguments passed in registers and then copied immediately
+   to the frame, and N_PSYM to indicate arguments passed in a
+   g14-relative argument block.  */
+
+#define        DBX_PARM_SYMBOL_CLASS(type) ((type == N_LSYM)? LOC_LOCAL_ARG: LOC_ARG)
+
+/* Byte order is configurable, but this machine runs little-endian.  */
+#define        TARGET_BYTE_ORDER       LITTLE_ENDIAN
+
+/* We have IEEE floating point, if we have any float at all.  */
+
+#define IEEE_FLOAT
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance ip across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(ip)      { ip = skip_prologue (ip); }
+extern CORE_ADDR skip_prologue ();
+
+/* Immediately after a function call, return the saved ip.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function
+   executes some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) (saved_pc_after_call (frame))
+extern CORE_ADDR saved_pc_after_call ();
+
+/* Stack grows upward */
+
+#define INNER_THAN >
+
+/* Nonzero if instruction at ip is a return instruction.  */
+
+#define ABOUT_TO_RETURN(ip) (read_memory_integer(ip,4) == 0x0a000000)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes.  */
+
+#define INVALID_FLOAT(p, len) (0)
+
+/* How long (ordinary) registers are */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+#define NUM_REGS 40
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES { \
+       /*  0 */ "pfp", "sp",  "rip", "r3",  "r4",  "r5",  "r6",  "r7", \
+       /*  8 */ "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",\
+       /* 16 */ "g0",  "g1",  "g2",  "g3",  "g4",  "g5",  "g6",  "g7", \
+       /* 24 */ "g8",  "g9",  "g10", "g11", "g12", "g13", "g14", "fp", \
+       /* 32 */ "pc",  "ac",  "ip",  "tc",  "fp0", "fp1", "fp2", "fp3",       \
+}
+
+/* Register numbers of various important registers (used to index
+   into arrays of register names and register values).  */
+
+#define R0_REGNUM   0  /* First local register         */
+#define SP_REGNUM   1  /* Contains address of top of stack */
+#define RIP_REGNUM  2  /* Return instruction pointer (local r2) */
+#define R15_REGNUM 15  /* Last local register          */
+#define G0_REGNUM  16  /* First global register        */
+#define G13_REGNUM 29  /* g13 - holds struct return address */
+#define G14_REGNUM 30  /* g14 - ptr to arg block / leafproc return address */
+#define FP_REGNUM  31  /* Contains address of executing stack frame */
+#define        PCW_REGNUM 32   /* process control word */
+#define        ACW_REGNUM 33   /* arithmetic control word */
+#define        IP_REGNUM  34   /* instruction pointer */
+#define        TCW_REGNUM 35   /* trace control word */
+#define FP0_REGNUM 36  /* First floating point register */
+
+/* Some registers have more than one name */
+
+#define PC_REGNUM  IP_REGNUM   /* GDB refers to ip as the Program Counter */
+#define PFP_REGNUM R0_REGNUM   /* Previous frame pointer       */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES ((36*4) + (4*10))
+
+/* Index within `registers' of the first byte of the space for register N.  */
+
+#define REGISTER_BYTE(N) ( (N) < FP0_REGNUM ? \
+                               (4*(N)) : ((10*(N)) - (6*FP0_REGNUM)) )
+
+/* The i960 has register windows, sort of.  */
+
+#define HAVE_REGISTER_WINDOWS
+
+/* Is this register part of the register window system?  A yes answer
+   implies that 1) The name of this register will not be the same in
+   other frames, and 2) This register is automatically "saved" upon
+   subroutine calls and thus there is no need to search more than one
+   stack frame for it.
+   
+   On the i960, in fact, the name of this register in another frame is
+   "mud" -- there is no overlap between the windows.  Each window is
+   simply saved into the stack (true for our purposes, after having been
+   flushed; normally they reside on-chip and are restored from on-chip
+   without ever going to memory).  */
+
+#define REGISTER_IN_WINDOW_P(regnum)   ((regnum) <= R15_REGNUM)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the i960, all regs are 4 bytes except for floating
+   point, which are 10.  NINDY only sends us 8 byte values for these,
+   which is a pain, but VxWorks handles this correctly, so we must.  */
+
+#define REGISTER_RAW_SIZE(N)           ( (N) < FP0_REGNUM ? 4 : 10 )
+
+/* Number of bytes of storage in the program's representation for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N)       ( (N) < FP0_REGNUM ? 4 : 8 )
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion from raw format to virtual
+   format.  */
+
+#define REGISTER_CONVERTIBLE(N) ((N) >= FP0_REGNUM)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)     \
+{ \
+  extern struct ext_format ext_format_i960[];          \
+  \
+  if ((REGNUM) >= FP0_REGNUM)   \
+    ieee_extended_to_double (ext_format_i960, (FROM), (TO));     \
+  else                                  \
+    bcopy ((FROM), (TO), 4);   \
+}
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
+{ \
+  extern struct ext_format ext_format_i960[];          \
+  \
+  if ((REGNUM) >= FP0_REGNUM)   \
+    double_to_ieee_extended (ext_format_i960, (FROM), (TO));     \
+  else                                  \
+    bcopy ((FROM), (TO), 4);   \
+}
+
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) ((N) < FP0_REGNUM ? \
+                                       builtin_type_int : builtin_type_double)
+\f
+/* Macros for understanding function return values... */
+
+/* Does the specified function use the "struct returning" convention
+   or the "value returning" convention?  The "value returning" convention
+   almost invariably returns the entire value in registers.  The
+   "struct returning" convention often returns the entire value in
+   memory, and passes a pointer (out of or into the function) saying
+   where the value (is or should go).
+
+   Since this sometimes depends on whether it was compiled with GCC,
+   this is also an argument.  This is used in call_function to build a
+   stack, and in value_being_returned to print return values.
+
+   On i960, a structure is returned in registers g0-g3, if it will fit.
+   If it's more than 16 bytes long, g13 pointed to it on entry.  */
+
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 16)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  This is only called if USE_STRUCT_CONVENTION for this
+   type is 0.
+
+   On the i960 we just take as many bytes as we need from G0 through G3.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+       bcopy(REGBUF+REGISTER_BYTE(G0_REGNUM), VALBUF, TYPE_LENGTH (TYPE))
+
+/* If USE_STRUCT_CONVENTION produces a 1, 
+   extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).
+
+   Address of where to put structure was passed in in global
+   register g13 on entry.  God knows what's in g13 now.  The
+   (..., 0) below is to make it appear to return a value, though
+   actually all it does is call error().  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+   (error("Don't know where large structure is returned on i960"), 0)
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format, for "value returning" functions.
+  
+   For 'return' command:  not (yet) implemented for i960.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+    error ("Returning values from functions is not implemented in i960 gdb")
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+    error ("Returning values from functions is not implemented in i960 gdb")
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* We cache information about saved registers in the frame structure,
+   to save us from having to re-scan function prologues every time
+   a register in a non-current frame is accessed.  */
+
+#define EXTRA_FRAME_INFO       \
+       struct frame_saved_regs *fsr;   \
+       CORE_ADDR arg_pointer;
+
+/* Zero the frame_saved_regs pointer when the frame is initialized,
+   so that FRAME_FIND_SAVED_REGS () will know to allocate and
+   initialize a frame_saved_regs struct the first time it is called.
+   Set the arg_pointer to -1, which is not valid; 0 and other values
+   indicate real, cached values.  */
+
+#define INIT_EXTRA_FRAME_INFO(fi) ((fi)->fsr = 0, (fi)->arg_pointer = -1)
+
+/* On the i960, we get the chain pointer by reading the PFP saved
+   on the stack and clearing the status bits.  */
+
+#define FRAME_CHAIN(thisframe) \
+  (read_memory_integer (FRAME_FP(thisframe), 4) & ~0xf)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+   and has no caller.  In that case, FRAME_CHAIN_COMBINE is not used.
+
+   On the i960, each various target system type must define FRAME_CHAIN_VALID,
+   since it differs between NINDY and VxWorks, the two currently supported
+   targets types.  We leave it undefined here.  */
+
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  { (FRAMELESS) = (leafproc_return ((FI)->pc) != 0); }
+
+/* Note that in the i960 architecture the return pointer is saved in the
+   *caller's* stack frame.
+  
+   Make sure to zero low-order bits because of bug in 960CA A-step part
+   (instruction addresses should always be word-aligned anyway).  */
+
+#define FRAME_SAVED_PC(frame) \
+                       ((read_memory_integer(FRAME_CHAIN(frame)+8,4)) & ~3)
+
+/* On the i960, FRAME_ARGS_ADDRESS should return the value of
+   g14 as passed into the frame, if known.  We need a function for this.
+   We cache this value in the frame info if we've already looked it up.  */
+
+#define FRAME_ARGS_ADDRESS(fi)         \
+  (((fi)->arg_pointer != -1)? (fi)->arg_pointer: frame_args_address (fi, 0))
+extern CORE_ADDR frame_args_address ();                /* i960-tdep.c */
+
+/* This is the same except it should return 0 when
+   it does not really know where the args are, rather than guessing.
+   This value is not cached since it is only used infrequently.  */
+
+#define        FRAME_ARGS_ADDRESS_CORRECT(fi)  (frame_args_address (fi, 1))
+
+#define FRAME_LOCALS_ADDRESS(fi)       (fi)->frame
+
+/* Set NUMARGS to the number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)    (numargs = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Produce the positions of the saved registers in a stack frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info_addr, sr) \
+       frame_find_saved_regs (frame_info_addr, &sr)
+extern void frame_find_saved_regs();           /* See i960-tdep.c */
+
+
+/* Print status when we get a random unexpected signal.  We have more
+   kinds of signals than Unix does... */
+
+#define        PRINT_RANDOM_SIGNAL(stop_signal) print_fault (stop_signal)
+\f
+/* Things needed for making calls to functions in the inferior process */
+
+/* Push an empty stack frame, to record the current ip, etc.
+  
+   Not (yet?) implemented for i960.  */
+
+#define PUSH_DUMMY_FRAME       \
+error("Function calls into the inferior process are not supported on the i960")
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME \
+       pop_frame ()
+
+
+/* This sequence of words is the instructions
+  
+       callx 0x00000000
+       fmark
+ */
+
+/* #define CALL_DUMMY { 0x86003000, 0x00000000, 0x66003e00 } */
+
+/* #define CALL_DUMMY_START_OFFSET 0 *//* Start execution at beginning of dummy */
+
+/* Indicate that we don't support calling inferior child functions.  */
+
+#undef CALL_DUMMY
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at 'dummyname'.
+  
+   Ignore arg count on i960.  */
+
+/* #define FIX_CALL_DUMMY(dummyname, fun, nargs) *(((int *)dummyname)+1) = fun */
+
+#undef FIX_CALL_DUMMY
+
+
+/* Interface definitions for kernel debugger KDB */
+/* (Not relevant to i960.) */
diff --git a/gdb/tm-isi.h b/gdb/tm-isi.h
new file mode 100644 (file)
index 0000000..7697a9f
--- /dev/null
@@ -0,0 +1,227 @@
+/* Definitions to target GDB on an ISI Optimum V (3.05) under 4.3bsd.
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This has not been tested on ISI's running BSD 4.2, but it will probably
+   work.  */
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/*#define STACK_END_ADDR 0x10000000*/
+#define STACK_END_ADDR 0xfffe000
+
+/* Data segment starts at etext rounded up to DATAROUND in {N,Z}MAGIC files */
+
+#define DATAROUND      0x20000
+#define N_DATADDR(hdr) (hdr.a_magic != OMAGIC ? \
+       (hdr.a_text + DATAROUND) & ~(DATAROUND-1) : hdr.a_text)
+
+/* Text segment starts at sizeof (struct exec) in {N,Z}MAGIC files */
+
+#define N_TXTADDR(hdr) (hdr.a_magic != OMAGIC ? sizeof (struct exec) : 0)
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.
+   On the ISI, the kernel resets the pc to the trap instr */
+
+#define DECR_PC_AFTER_BREAK 0
+
+\f
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(val, fi)  \
+{ register CORE_ADDR pc = FRAME_SAVED_PC (fi);                 \
+  register int insn = 0177777 & read_memory_integer (pc, 2);   \
+  val = 0;                                                     \
+  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */ \
+    val = read_memory_integer (pc + 2, 2);                     \
+  else if ((insn & 0170777) == 0050217 /* addql #N, sp */      \
+          || (insn & 0170777) == 0050117)  /* addqw */         \
+    { val = (insn >> 9) & 7; if (val == 0) val = 8; }          \
+  else if (insn == 0157774) /* addal #WW, sp */                        \
+    val = read_memory_integer (pc + 2, 4);                     \
+  val >>= 2; }
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{ register int regnum;                                                 \
+  register int regmask;                                                        \
+  register CORE_ADDR next_addr;                                                \
+  register CORE_ADDR pc;                                               \
+  register int insn;                                                   \
+  register int offset;                                                 \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
+      && (frame_info)->pc <= (frame_info)->frame)                              \
+    { next_addr = (frame_info)->frame;                                 \
+      pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
+  else                                                                 \
+    { pc = get_pc_function_start ((frame_info)->pc);                   \
+      /* Verify we have a link a6 instruction next,                    \
+        or a branch followed by a link a6 instruction;                 \
+        if not we lose.  If we win, find the address above the saved   \
+        regs using the amount of storage from the link instruction.  */\
+retry:                                                                 \
+      insn = read_memory_integer (pc, 2);                              \
+      if (insn == 044016)                                              \
+       next_addr = (frame_info)->frame - read_memory_integer (pc += 2, 4), pc+=4; \
+      else if (insn == 047126)                                         \
+       next_addr = (frame_info)->frame - read_memory_integer (pc += 2, 2), pc+=2; \
+      else if ((insn & 0177400) == 060000)     /* bra insn */          \
+       { offset = insn & 0377;                                         \
+          pc += 2;                             /* advance past bra */  \
+         if (offset == 0)                      /* bra #word */         \
+           offset = read_memory_integer (pc, 2), pc += 2;              \
+         else if (offset == 0377)              /* bra #long */         \
+           offset = read_memory_integer (pc, 4), pc += 4;              \
+         pc += offset;                                                 \
+         goto retry;                                                   \
+      } else goto lose;                                                        \
+      /* If have an addal #-n, sp next, adjust next_addr.  */          \
+      if ((0177777 & read_memory_integer (pc, 2)) == 0157774)          \
+       next_addr += read_memory_integer (pc += 2, 4), pc += 4;         \
+    }                                                                  \
+  /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */     \
+  insn = read_memory_integer (pc, 2), pc += 2;                         \
+  regmask = read_memory_integer (pc, 2);                               \
+  if ((insn & 0177760) == 022700)      /* movl rn, (sp) */             \
+    (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr;  \
+  else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */            \
+    (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \
+  else if (insn == 0044327)            /* moveml mask, (sp) */         \
+    { pc += 2;                                                         \
+      /* Regmask's low bit is for register 0, the first written */     \
+      next_addr -= 4;                                                  \
+      for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)           \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr += 4);          \
+  } else if (insn == 0044347)          /* moveml mask, -(sp) */        \
+    { pc += 2;                                                         \
+      /* Regmask's low bit is for register 15, the first pushed */     \
+      for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)          \
+       if (regmask & 1)                                                \
+          (frame_saved_regs).regs[regnum] = (next_addr -= 4); }                \
+  /* clrw -(sp); movw ccr,-(sp) may follow.  */                                \
+  if (read_memory_integer (pc, 2) == 041147                            \
+      && read_memory_integer (pc+2, 2) == 042347)                      \
+    (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4);             \
+  lose: ;                                                              \
+  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame;            \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;                \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                         \
+  register CORE_ADDR fp;                                               \
+  register int regnum;                                                 \
+  struct frame_saved_regs fsr;                                         \
+  struct frame_info *fi;                                               \
+  char raw_buffer[12];                                                 \
+  fi = get_frame_info (frame);                                         \
+  fp = fi->frame;                                                      \
+  get_frame_saved_regs (fi, &fsr);                                     \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    if (fsr.regs[regnum])                                              \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    if (fsr.regs[regnum])                                              \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                             \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
+  write_register (SP_REGNUM, fp + 8);                                  \
+  flush_cached_frames ();                                              \
+  set_current_frame ( create_new_frame (read_register (FP_REGNUM),     \
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     fmovem #<f0-f7>,-(sp)
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     bpt
+     nop
+Note this is 24 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
+\f
+#define HAVE_68881 1
+
+#include "tm-68k.h"
diff --git a/gdb/tm-m88k.h b/gdb/tm-m88k.h
new file mode 100644 (file)
index 0000000..1890d6c
--- /dev/null
@@ -0,0 +1,460 @@
+/* Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is currently for a 88000 running DGUX.  If other 88k ports are
+   done, OS-specific stuff should be moved (see tm-68k.h, for example).  */
+/* g++ support is not yet included.  */
+
+#include "tdesc.h"
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* This is not a CREATE_INFERIOR_HOOK because it also applies to
+   remote debugging.  */
+#define START_INFERIOR_HOOK () \
+  { \
+    extern int safe_to_init_tdesc_context; \
+    extern int tdesc_handle; \
+ \
+    safe_to_init_tdesc_context = 0; \
+    if (tdesc_handle) \
+      { \
+       dc_terminate (tdesc_handle); \
+       tdesc_handle = 0; \
+      } \
+  }
+
+#define EXTRA_FRAME_INFO dc_dcontext_t frame_context;
+#define INIT_EXTRA_FRAME_INFO(fci) \
+  {                                                                     \
+    if (fci->next_frame != NULL)                                        \
+      {                                                                 \
+        /* The call to get_prev_context */                              \
+        /* will update current_context for us. */                       \
+        int stack_error = 1;                                            \
+        jmp_buf stack_jmp;                                              \
+        if (!setjmp (stack_jmp))                                        \
+          {                                                             \
+            prev->frame_context                                         \
+              = get_prev_context (next_frame->frame_context);           \
+            stack_error = 0;                                            \
+          }                                                             \
+        else                                                            \
+          {                                                             \
+            stack_error = 0;                                            \
+            next_frame->prev = 0;                                       \
+            return 0;                                                   \
+          }                                                             \
+        if (!prev->frame_context)                                       \
+          {                                                             \
+            next_frame->prev = 0;                                       \
+            return 0;                                                   \
+          }                                                             \
+      }                                                                 \
+    else                                                                \
+      {                                                                 \
+        /* We are creating an arbitrary frame */                        \
+        /* (i.e. we are in create_new_frame).  */                       \
+        extern dc_dcontext_t current_context;                           \
+                                                                        \
+        fci->frame_context = current_context;                           \
+      }                                                                 \
+  }
+
+#define INIT_FRAME_PC(fromleaf, prev) \
+  {                                                                     \
+    prev->pc = dc_location (prev->frame_context);                       \
+    prev->frame = get_frame_base (prev->pc);                            \
+  }
+
+#define IEEE_FLOAT
+
+/* Text Description (TDESC) is used by m88k to maintain stack & reg info */
+
+#define TDESC
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Hook for read_relative_register_raw_bytes */
+
+#define READ_RELATIVE_REGISTER_RAW_BYTES
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(frompc)   0
+
+/* The m88k kernel aligns all instructions on 4-byte boundaries.  The
+   kernel also uses the least significant two bits for its own hocus
+   pocus.  When gdb receives an address from the kernel, it needs to
+   preserve those right-most two bits, but gdb also needs to be careful
+   to realize that those two bits are not really a part of the address
+   of an instruction.  Shrug.  */
+
+#define ADDR_BITS_REMOVE(addr) ((addr) & ~3)
+#define ADDR_BITS_SET(addr) (((addr) | 0x00000002) - 4)
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+  (read_register (SRP_REGNUM) & (~3))
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0xF0000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+/* instruction 0xF000D1FF is 'tb0 0,r0,511'
+   If Bit bit 0 of r0 is clear (always true),
+   initiate exception processing (trap).
+ */
+#define BREAKPOINT {0xF0, 0x00, 0xD1, 0xFF}
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0xF0000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+/* instruction 0xF000D1FF is 'tb0 0,r0,511'
+   If Bit bit 0 of r0 is clear (always true),
+   initiate exception processing (trap).
+ */
+#define BREAKPOINT {0xF0, 0x00, 0xD1, 0xFF}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+/* 'jmp r1' or 'jmp.n r1' is used to return from a subroutine. */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0xF800)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the 386.  */
+
+#define INVALID_FLOAT(p, len) IEEE_isNAN(p,len)
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 38
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES {\
+       "r0",\
+       "r1",\
+       "r2",\
+       "r3",\
+       "r4",\
+       "r5",\
+       "r6",\
+       "r7",\
+       "r8",\
+       "r9",\
+       "r10",\
+       "r11",\
+       "r12",\
+       "r13",\
+       "r14",\
+       "r15",\
+       "r16",\
+       "r17",\
+       "r18",\
+       "r19",\
+       "r20",\
+       "r21",\
+       "r22",\
+       "r23",\
+       "r24",\
+       "r25",\
+       "r26",\
+       "r27",\
+       "r28",\
+       "r29",\
+       "r30",\
+       "r31",\
+       "psr",\
+       "fpsr",\
+       "fpcr",\
+       "sxip",\
+       "snip",\
+       "sfip",\
+       "vbr",\
+       "dmt0",\
+       "dmd0",\
+       "dma0",\
+       "dmt1",\
+       "dmd1",\
+       "dma1",\
+       "dmt2",\
+       "dmd2",\
+       "dma2",\
+       "sr0",\
+       "sr1",\
+       "sr2",\
+       "sr3",\
+       "fpecr",\
+       "fphs1",\
+       "fpls1",\
+       "fphs2",\
+       "fpls2",\
+       "fppt",\
+       "fprh",\
+       "fprl",\
+       "fpit",\
+       "fpsr",\
+       "fpcr",\
+       };
+
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define SRP_REGNUM 1           /* Contains subroutine return pointer */
+#define RV_REGNUM 2            /* Contains simple return values */
+#define SRA_REGNUM 12          /* Contains address of struct return values */
+#define FP_REGNUM 30           /* Contains address of executing stack frame */
+#define SP_REGNUM 31           /* Contains address of top of stack */
+#define SXIP_REGNUM 35         /* Contains Shadow Execute Instruction Pointer */
+#define SNIP_REGNUM 36         /* Contains Shadow Next Instruction Pointer */
+#define PC_REGNUM SXIP_REGNUM  /* Program Counter */
+#define NPC_REGNUM SNIP_REGNUM /* Next Program Counter */
+#define PSR_REGNUM 32           /* Processor Status Register */
+#define FPSR_REGNUM 33         /* Floating Point Status Register */
+#define FPCR_REGNUM 34         /* Floating Point Control Register */
+#define SFIP_REGNUM 37         /* Contains Shadow Fetched Intruction pointer */
+#define NNPC_REGNUM SFIP_REGNUM /* Next Next Program Counter */
+
+/* PSR status bit definitions.  */
+
+#define PSR_MODE               0x80000000
+#define PSR_BYTE_ORDER         0x40000000
+#define PSR_SERIAL_MODE                0x20000000
+#define PSR_CARRY              0x10000000
+#define PSR_SFU_DISABLE                0x000003f0
+#define PSR_SFU1_DISABLE       0x00000008
+#define PSR_MXM                        0x00000004
+#define PSR_IND                        0x00000002
+#define PSR_SFRZ               0x00000001
+
+/* BCS requires that the SXIP_REGNUM (or PC_REGNUM) contain the address
+   of the next instr to be executed when a breakpoint occurs.  Because
+   the kernel gets the next instr (SNIP_REGNUM), the instr in SNIP needs
+   to be put back into SFIP, and the instr in SXIP should be shifted
+   to SNIP */
+
+/* Are you sitting down?  It turns out that the 88K BCS (binary compatibility
+  standard) folks originally felt that the debugger should be responsible
+  for backing up the IPs, not the kernel (as is usually done).  Well, they
+  have reversed their decision, and in future releases our kernel will be
+  handling the backing up of the IPs.  So, eventually, we won't need to
+  do the SHIFT_INST_REGS stuff.  But, for now, since there are 88K systems out
+  there that do need the debugger to do the IP shifting, and since there
+  will be systems where the kernel does the shifting, the code is a little
+  more complex than perhaps it needs to be (we still go inside SHIFT_INST_REGS,
+  and if the shifting hasn't occurred then gdb goes ahead and shifts).  */
+
+#define SHIFT_INST_REGS
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+
+#define REGISTER_BYTES (NUM_REGS * sizeof(REGISTER_TYPE))
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N)*sizeof(REGISTER_TYPE))
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+#define REGISTER_RAW_SIZE(N) (sizeof(REGISTER_TYPE))
+
+/* Number of bytes of storage in the program's representation
+   for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (sizeof(REGISTER_TYPE))
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE (sizeof(REGISTER_TYPE))
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.
+/* Are FPS1, FPS2, FPR "virtual" regisers? */
+
+#define MAX_REGISTER_VIRTUAL_SIZE (sizeof(REGISTER_TYPE))
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) {bcopy ((FROM), (TO), (sizeof(REGISTER_TYPE)));}
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) {bcopy ((FROM), (TO), (sizeof(REGISTER_TYPE)));}
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int)
+
+/* The 88k call/return conventions call for "small" values to be returned
+   into consecutive registers starting from r2.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (&(((void *)REGBUF)[REGISTER_BYTE(RV_REGNUM)]), (VALBUF), TYPE_LENGTH (TYPE))
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (2*sizeof(void*), (VALBUF), TYPE_LENGTH (TYPE))
+
+/* In COFF, if PCC says a parameter is a short or a char, do not
+   change it to int (it seems the convention is to change it). */
+
+#define BELIEVE_PCC_PROMOTION 1
+
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* These are just dummies for the 88k because INIT_FRAME_PC sets prev->frame
+   instead.  */
+
+#define FRAME_CHAIN(thisframe) (0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) (1)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (0)
+
+/* Define other aspects of the stack frame.  */
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame+4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)  ((numargs) = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+/* On the 88k, parameter registers get stored into the so called "homing"
+   area.  This *always* happens when you compiled with GCC and use -g.
+   Also, (with GCC and -g) the saving of the parameter register values
+   always happens right within the function prologue code, so these register
+   values can generally be relied upon to be already copied into their
+   respective homing slots by the time you will normally try to look at
+   them (we hope).
+
+   Note that homing area stack slots are always at *positive* offsets from
+   the frame pointer.  Thus, the homing area stack slots for the parameter
+   registers (passed values) for a given function are actually part of the
+   frame area of the caller.  This is unusual, but it should not present
+   any special problems for GDB.
+
+   Note also that on the 88k, we are only interested in finding the
+   registers that might have been saved in memory.  This is a subset of
+   the whole set of registers because the standard calling sequence allows
+   the called routine to clobber many registers.
+
+   We could manage to locate values for all of the so called "preserved"
+   registers (some of which may get saved within any particular frame) but
+   that would require decoding all of the tdesc information.  Tht would be
+   nice information for GDB to have, but it is not strictly manditory if we
+   can live without the ability to look at values within (or backup to)
+   previous frames.
+*/
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+        frame_find_saved_regs (frame_info, &frame_saved_regs)
+
+\f
+/* When popping a frame on the 88k (say when doing a return command), the
+   calling function only expects to have the "preserved" registers restored.
+   Thus, those are the only ones that we even try to restore here.   */
+
+extern void pop_frame ();
+
+#define POP_FRAME pop_frame ()
+
+/* BCS is a standard for binary compatibility.  This machine uses it.  */
+#define BCS
diff --git a/gdb/tm-merlin.h b/gdb/tm-merlin.h
new file mode 100644 (file)
index 0000000..91475c8
--- /dev/null
@@ -0,0 +1,364 @@
+/* Definitions to target GDB to a merlin under utek 2.1
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* I don't know if this will work for cross-debugging, even if you do get
+   a copy of the right include file.  */
+#include <machine/reg.h>
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)                              \
+{ register int op = read_memory_integer (pc, 1);       \
+  if (op == 0x82)                                      \
+    { op = read_memory_integer (pc+2,1);               \
+      if ((op & 0x80) == 0) pc += 3;                   \
+      else if ((op & 0xc0) == 0x80) pc += 4;           \
+      else pc += 6;                                    \
+    }}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+       read_memory_integer (read_register (SP_REGNUM), 4)
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0x800000)
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xf2}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12)
+
+/* Return 1 if P points to an invalid floating point value.  */
+
+#define INVALID_FLOAT(p, len) 0
+
+/* Define this to say that the "svc" insn is followed by
+   codes in memory saying which kind of system call it is.  */
+
+#define NS32K_SVC_IMMED_OPERANDS
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS               25
+
+#define NUM_GENERAL_REGS       8
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",        \
+                       "pc", "sp", "fp", "ps",                         \
+                       "fsr",                                          \
+                       "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+                       "l0", "l1", "l2", "l3", "l4",                   \
+                       }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define AP_REGNUM FP_REGNUM
+#define FP_REGNUM 10           /* Contains address of executing stack frame */
+#define SP_REGNUM 9            /* Contains address of top of stack */
+#define PC_REGNUM 8            /* Contains program counter */
+#define PS_REGNUM 11           /* Contains processor status */
+#define FPS_REGNUM 12          /* Floating point status register */
+#define FP0_REGNUM 13          /* Floating point register 0 */
+#define LP0_REGNUM 21          /* Double register 0 (same as FP0) */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double))
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \
+       LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the 32000, all regs are 4 bytes
+   except for the doubled floating registers. */
+
+#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the 32000, all regs are 4 bytes
+   except for the doubled floating registers. */
+
+#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+  ((N) >= FP0_REGNUM ?         \
+    ((N) >= LP0_REGNUM ?       \
+     builtin_type_double       \
+     : builtin_type_float)     \
+   : builtin_type_int) 
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function.
+
+   On this machine this is a no-op, as gcc doesn't run on it yet.
+   This calling convention is not used. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the Merlin, the frame's nominal address is the FP value,
+   and at that address is saved previous FP value as a 4-byte word.  */
+
+#define FRAME_CHAIN(thisframe)  \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+/* compute base of arguments */
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)                    \
+{ CORE_ADDR pc;                                                \
+  int insn;                                            \
+  int addr_mode;                                       \
+  int width;                                           \
+                                                       \
+  pc = FRAME_SAVED_PC (fi);                            \
+  insn = read_memory_integer (pc,2);                   \
+  addr_mode = (insn >> 11) & 0x1f;                     \
+  insn = insn & 0x7ff;                                 \
+  if ((insn & 0x7fc) == 0x57c                          \
+      && addr_mode == 0x14) /* immediate */            \
+    { if (insn == 0x57c) /* adjspb */                  \
+       width = 1;                                      \
+      else if (insn == 0x57d) /* adjspw */             \
+       width = 2;                                      \
+      else if (insn == 0x57f) /* adjspd */             \
+       width = 4;                                      \
+      numargs = read_memory_integer (pc+2,width);      \
+      if (width > 1)                                   \
+       flip_bytes (&numargs, width);                   \
+      numargs = - sign_extend (numargs, width*8) / 4; }        \
+  else numargs = -1;                                   \
+}
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ int regmask,regnum;                                          \
+  int localcount;                                              \
+  CORE_ADDR enter_addr;                                                \
+  CORE_ADDR next_addr;                                         \
+                                                               \
+  enter_addr = get_pc_function_start ((frame_info)->pc);       \
+  regmask = read_memory_integer (enter_addr+1, 1);             \
+  localcount = ns32k_localcount (enter_addr);                  \
+  next_addr = (frame_info)->frame + localcount;                        \
+  for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)                \
+    (frame_saved_regs).regs[regnum]                            \
+      = (regmask & 1) ? (next_addr -= 4) : 0;                  \
+  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 4;        \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;        \
+  (frame_saved_regs).regs[FP_REGNUM]                           \
+     = read_memory_integer ((frame_info)->frame, 4); }
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);   \
+  register int regnum;                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));      \
+  sp = push_word (sp, read_register (FP_REGNUM));      \
+  write_register (FP_REGNUM, sp);                      \
+  for (regnum = 0; regnum < 8; regnum++)               \
+    sp = push_word (sp, read_register (regnum));       \
+  write_register (SP_REGNUM, sp);                      \
+}
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                                \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = 0; regnum < 8; regnum++)                        \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
+                                      read_pc ()));             \
+}
+
+/* This sequence of words is the instructions
+     enter     0xff,0          82 ff 00
+     jsr       @0x00010203     7f ae c0 01 02 03
+     adjspd    0x69696969      7f a5 01 02 03 04
+     bpt                       f2
+   Note this is 16 bytes.  */
+
+#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 }
+
+#define CALL_DUMMY_START_OFFSET        3
+#define CALL_DUMMY_LENGTH      16
+#define CALL_DUMMY_ADDR                5
+#define CALL_DUMMY_NARGS       11
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)                   \
+{ int flipped = fun | 0xc0000000;                              \
+  flip_bytes (&flipped, 4);                                    \
+  *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \
+  flipped = - nargs * 4;                                       \
+  flip_bytes (&flipped, 4);                                    \
+  *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped;        \
+}
diff --git a/gdb/tm-mips.h b/gdb/tm-mips.h
new file mode 100644 (file)
index 0000000..6fd681d
--- /dev/null
@@ -0,0 +1,363 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+   Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+   and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (TARGET_BYTE_ORDER)
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* Floating point is IEEE compliant */
+#define IEEE_FLOAT
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+/*#define NAMES_HAVE_UNDERSCORE*/
+
+/* Debugger information will be in mips' format */
+
+#define READ_MIPS_FORMAT
+
+/* File format is coff, but with additions */
+
+#define COFF_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)      pc = mips_skip_prologue(pc)
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame)     read_register(RA_REGNUM)
+
+/* Are we currently handling a signal */
+
+#define IN_SIGTRAMP(pc, name)  in_sigtramp(pc, name)
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0x7ffff000)
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+#define BIG_ENDIAN 4321
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+#define BREAKPOINT {0, 0x5, 0, 0xd}
+#else
+#define BREAKPOINT {0xd, 0, 0x5, 0}
+#endif
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction. "j ra" on mips. */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 4) == 0x3e00008)
+
+/* Return 1 if P points to an invalid floating point value. */
+
+#define INVALID_FLOAT(p,l)     isa_NAN(p,l)
+
+/* Say how long (all) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 73
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES         \
+    {  "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3", \
+       "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7", \
+       "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7", \
+       "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra", \
+       "sr",   "lo",   "hi",   "bad",  "cause","pc",    \
+       "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7", \
+       "f8",   "f9",   "f10",   "f11",   "f12",   "f13",   "f14",   "f15", \
+       "f16",   "f17",   "f18",   "f19",   "f20",   "f21",   "f22",   "f23",\
+       "f24",   "f25",   "f26",   "f27",   "f28",   "f29",   "f30",   "f31",\
+       "fsr",   "fir", "fp" \
+    }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define SP_REGNUM 29           /* Contains address of top of stack */
+#define PC_REGNUM 37           /* Contains program counter */
+#define RA_REGNUM 31           /* Contains return address value */
+#define PS_REGNUM 32           /* Contains processor status */
+#define HI_REGNUM 34            /* Multiple/divide temp */
+#define LO_REGNUM 33            /* ... */
+#define FP0_REGNUM 38           /* Floating point register 0 (single float) */
+#define FCRCS_REGNUM 70         /* FP control/status */
+#define FCRIR_REGNUM 71         /* FP implementation/revision */
+#define FP_REGNUM 72           /* Pseudo register that contains true address of executing stack frame */
+
+/* Define DO_REGISTERS_INFO() to do machine-specific formatting
+   of register dumps. */
+
+#define DO_REGISTERS_INFO(_regnum) mips_do_registers_info(_regnum)
+
+#define REGISTER_U_ADDR(addr, blockend, regno)                 \
+   if (blockend == 0) {                                        \
+       if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\
+       else addr = 0; /* ..somewhere in the pcb */     \
+   } else if (regno < 32) addr = regno;                        \
+   else if (regno == PC_REGNUM) addr = 96;             \
+   else if (regno == 36) addr = 97;                    \
+   else if (regno == HI_REGNUM) addr = 98;             \
+   else if (regno == LO_REGNUM) addr = 99;             \
+   else if (regno == FCRCS_REGNUM) addr = 100;         \
+   else if (regno == FCRIR_REGNUM) addr = 101;         \
+   else if (regno >= FP0_REGNUM) addr = regno - (FP0_REGNUM-32);\
+   else addr = 0;
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On mips, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On mips, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  bcopy ((FROM), (TO), 4);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), 4);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) builtin_type_int
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(addr, sp) \
+  { sp = push_word(sp, addr);}
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  XXX floats */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF+REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF+16))
+
+/* Structures are returned by ref in extra arg0 */
+#define USE_STRUCT_CONVENTION(gcc_p, type)     1
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+#define FRAME_CHAIN(thisframe) (FRAME_ADDR)mips_frame_chain(thisframe)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+/* We handle this differently for mips, and maybe we should not */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS)  {(FRAMELESS) = 0;}
+
+/* Saved Pc.  */
+
+#define FRAME_SAVED_PC(FRAME)  (mips_frame_saved_pc(FRAME))
+
+#define FRAME_ARGS_ADDRESS(fi) (fi)->frame
+
+#define FRAME_LOCALS_ADDRESS(fi) (fi)->frame
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(num, fi)        (num = mips_frame_num_args(fi))
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) ( \
+  (frame_saved_regs) = *(frame_info)->saved_regs, \
+  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame)
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Stack has strict alignment. However, use PUSH_ARGUMENTS
+   to take care of it. */
+/*#define STACK_ALIGN(addr)    (((addr)+3)&~3)*/
+
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+    sp = mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME       mips_push_dummy_frame()
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME              mips_pop_frame()
+
+#define MK_OP(op,rs,rt,offset) (((op)<<26)|((rs)<<21)|((rt)<<16)|(offset))
+#define CALL_DUMMY_SIZE (16*4)
+#define Dest_Reg 2
+#define CALL_DUMMY {\
+ MK_OP(0,RA_REGNUM,0,8),       /* jr $ra # Fake ABOUT_TO_RETURN ...*/\
+ 0,                            /* nop    #  ... to stop raw backtrace*/\
+ 0x27bd0000,                   /* addu sp,?0 # Pseudo prologue */\
+/* Start here: */\
+ MK_OP(061,SP_REGNUM,12,0),    /* lwc1 $f12,0(sp) # Reload first 4 args*/\
+ MK_OP(061,SP_REGNUM,13,4),    /* lwc1 $f13,4(sp) */\
+ MK_OP(061,SP_REGNUM,14,8),    /* lwc1 $f14,8(sp) */\
+ MK_OP(061,SP_REGNUM,15,12),   /* lwc1 $f15,12(sp) */\
+ MK_OP(043,SP_REGNUM,4,0),     /* lw $r4,0(sp) # Re-load FP regs*/\
+ MK_OP(043,SP_REGNUM,5,4),     /* lw $r5,4(sp) */\
+ MK_OP(043,SP_REGNUM,6,8),     /* lw $r6,8(sp) */\
+ MK_OP(043,SP_REGNUM,7,12),    /* lw $r7,12(sp) */\
+ (017<<26)| (Dest_Reg << 16),  /* lui $r31,<target upper 16 bits>*/\
+ MK_OP(13,Dest_Reg,Dest_Reg,0),        /* ori $r31,$r31,<lower 16 bits>*/ \
+ (Dest_Reg<<21) | (31<<11) | 9,        /* jalr $r31 */\
+ MK_OP(043,SP_REGNUM,7,12),    /* lw $r7,12(sp) */\
+ 0x5000d,                      /* bpt */\
+}
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, start_sp, fun, nargs,        args, rettype, gcc_p)\
+  (((int*)dummyname)[11] |= (((unsigned long)(fun)) >> 16), \
+   ((int*)dummyname)[12] |= (unsigned short)(fun))
+
+/* Specific information about a procedure.
+   This overlays the MIPS's PDR records, 
+   mipsread.c (ab)uses this to save memory */
+
+typedef struct mips_extra_func_info {
+       unsigned long   adr;    /* memory address of start of procedure */
+       long    isym;           /* pointer to procedure symbol */
+       long    pad2;           /* iline: start of line number entries*/
+       long    regmask;        /* save register mask */
+       long    regoffset;      /* save register offset */
+       long    numargs;        /* number of args to procedure (was iopt) */
+       long    fregmask;       /* save floating point register mask */
+       long    fregoffset;     /* save floating point register offset */
+       long    framesize;      /* frameoffset: frame size */
+       short   framereg;       /* frame pointer register */
+       short   pcreg;          /* offset or reg of return pc */
+       long    lnLow;          /* lowest line in the procedure */
+       long    lnHigh;         /* highest line in the procedure */
+       long    pad3;           /* cbLineOffset: byte offset for this procedure from the fd base */
+} *mips_extra_func_info_t;
+
+#define EXTRA_FRAME_INFO \
+  char *proc_desc; /* actually, a mips_extra_func_info_t */\
+  int num_args;\
+  struct frame_saved_regs *saved_regs;
+
+#define INIT_EXTRA_FRAME_INFO(fci) init_extra_frame_info(fci)
diff --git a/gdb/tm-news.h b/gdb/tm-news.h
new file mode 100644 (file)
index 0000000..ff50dbf
--- /dev/null
@@ -0,0 +1,172 @@
+/* Parameters for execution on a Sony/NEWS, for GDB, the GNU debugger.
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* See following cpu type determination macro to get the machine type.
+  
+Here is an m-news.h file for gdb.  It supports the 68881 registers.
+                                           by hikichi@srava.sra.junet
+  
+* Support Sun assembly format instead of Motorola one.
+* Ptrace for handling floating register has a bug(before NEWS OS version 2.2),
+* After NEWS OS version 3.2, some of ptrace's bug is fixed.
+  But we cannot change the floating register(see adb(1) in OS 3.2) yet.  */
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Symbols on this machine are in DBX format. */
+#define READ_DBX_FORMAT
+
+/* Use to compute STACK_END_ADDR.  */
+#define TARGET_UPAGES 2
+#define TARGET_NBPG 4096
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0x80000000 - TARGET_UPAGES * TARGET_NBPG)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+/* when it return the floating value, use the FP0 in NEWS.  */
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  { if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+      { \
+       REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM, \
+                              &REGBUF[REGISTER_BYTE (FP0_REGNUM)], VALBUF); \
+      } \
+    else \
+      bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE)); }
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+/* when it return the floating value, use the FP0 in NEWS.  */
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  { if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
+      { \
+       char raw_buf[REGISTER_RAW_SIZE (FP0_REGNUM)]; \
+       REGISTER_CONVERT_TO_RAW (FP0_REGNUM, VALBUF, raw_buf); \
+       write_register_bytes (FP0_REGNUM, \
+                             raw_buf, REGISTER_RAW_SIZE (FP0_REGNUM)); \
+      } \
+    else \
+      write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)); }
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(val, fi)  \
+{ register CORE_ADDR pc = FRAME_SAVED_PC (fi);                 \
+  register int insn = 0177777 & read_memory_integer (pc, 2);   \
+  val = 0;                                                     \
+  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */ \
+    val = read_memory_integer (pc + 2, 2);                     \
+  else if ((insn & 0170777) == 0050217 /* addql #N, sp */      \
+          || (insn & 0170777) == 0050117)  /* addqw */         \
+    { val = (insn >> 9) & 7; if (val == 0) val = 8; }          \
+  else if (insn == 0157774) /* addal #WW, sp */                        \
+    val = read_memory_integer (pc + 2, 4);                     \
+  val >>= 2; }
+
+/* Things needed for making the inferior call functions.  */
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                         \
+  register CORE_ADDR fp;                                               \
+  register int regnum;                                                 \
+  struct frame_saved_regs fsr;                                         \
+  struct frame_info *fi;                                               \
+  char raw_buffer[12];                                                 \
+  fi = get_frame_info (frame);                                         \
+  fp = fi->frame;                                                      \
+  get_frame_saved_regs (fi, &fsr);                                     \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    if (fsr.regs[regnum])                                              \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    if (fsr.regs[regnum])                                              \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                             \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
+  write_register (SP_REGNUM, fp + 8);                                  \
+  flush_cached_frames ();                                              \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
+                                      read_pc ())); }
+
+/* This sequence of words is the instructions
+     fmove.m #<f0-f7>,-(sp)
+     movem.l 0xfffc,-(sp)     ;; no save a6(fp) and a7(sp)
+     clr.w -(sp)
+     move.w ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jbsr (#32323232)
+     add.l #69696969,sp
+     bpt
+     nop
+Note this is 24 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
+\f
+#define HAVE_68881
+
+#include "tm-68k.h"
diff --git a/gdb/tm-nindy960.h b/gdb/tm-nindy960.h
new file mode 100644 (file)
index 0000000..e7ed59b
--- /dev/null
@@ -0,0 +1,105 @@
+/* Parameters for Intel 960 running NINDY monitor, for GDB, the GNU debugger.
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Contributed by Intel Corporation and Cygnus Support.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*****************************************************************************
+ * Definitions to target GDB to an i960 debugged over a serial line.
+ ******************************************************************************/
+
+#include "tm-i960.h"
+
+/* Override the standard gdb prompt when compiled for this target.  */
+
+#define        DEFAULT_PROMPT  "(gdb960) "
+
+/* Additional command line options accepted by nindy gdb's, for handling
+   the remote-nindy.c interface.  These should really be target-specific
+   rather than architecture-specific.  */
+
+extern int nindy_old_protocol; /* nonzero if old NINDY serial protocol */
+extern int nindy_initial_brk;  /* Send a BREAK to reset board first */
+extern char *nindy_ttyname;    /* Name of serial port to talk to nindy */
+
+#define        ADDITIONAL_OPTIONS \
+       {"O", 0, &nindy_old_protocol, 1},       \
+       {"brk", 0, &nindy_initial_brk, 1},      \
+       {"r", 1, 0, 1004},  /* 1004 is magic cookie for ADDL_CASES */
+
+#define        ADDITIONAL_OPTION_CASES \
+       case 1004:      /* -r option:  remote nindy auto-start */       \
+         nindy_ttyname = optarg;       \
+         break;
+
+#define        ADDITIONAL_OPTION_HELP \
+       "\
+  -O                Use old protocol to talk to a Nindy target\n\
+  -brk              Send a break to a Nindy target to reset it.\n\
+  -r SERIAL         Open remote Nindy session to SERIAL port.\n\
+"
+
+/* If specified on the command line, open tty for talking to nindy,
+   and download the executable file if one was specified.  */
+
+#define        ADDITIONAL_OPTION_HANDLER       \
+       if (!setjmp (to_top_level) && nindy_ttyname) {          \
+         nindy_open (nindy_ttyname, !batch);                   \
+         if ( !setjmp(to_top_level) && execarg ) {             \
+               target_load (execarg, !batch);                  \
+         }                                                     \
+       }
+
+/* If configured for i960 target, we take control before main loop
+   and demand that we configure for a nindy target.  */
+
+#define        BEFORE_MAIN_LOOP_HOOK   \
+  nindy_before_main_loop();
+
+/* Address of end of stack space.
+ *     This probably doesn't matter for nindy, because it's only used
+ *     in manipulation of core files, which we don't support.
+ */
+
+#define STACK_END_ADDR (0xfe000000)
+
+/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
+   and has no caller.  In that case, FRAME_CHAIN_COMBINE is not used.
+
+   On the i960, each various target system type defines FRAME_CHAIN_VALID,
+   since it differs between NINDY and VxWorks, the two currently supported
+   targets types.  */
+
+#define        FRAME_CHAIN_VALID(chain, thisframe) \
+       nindy_frame_chain_valid (chain, thisframe)
+
+extern int nindy_frame_chain_valid();          /* See nindy-tdep.c */
+
+/* Sequence of bytes for breakpoint instruction */
+
+#define BREAKPOINT {0x00, 0x3e, 0x00, 0x66}
+
+/* Amount ip must be decremented by after a breakpoint.
+ * This is often the number of bytes in BREAKPOINT but not always.
+ */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Not needed, because we don't support core files:
+ *     #define KERNEL_U_ADDR
+ *     #define REGISTER_U_ADDR(addr, blockend, regno)
+ */
diff --git a/gdb/tm-np1.h b/gdb/tm-np1.h
new file mode 100644 (file)
index 0000000..0bb1dcc
--- /dev/null
@@ -0,0 +1,515 @@
+/* Parameters for targeting on a Gould NP1, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define GOULD_NPL
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* N_ENTRY appears in libraries on Gould machines.
+   Don't know what 0xa4 is; it's mentioned in stab.h
+   but only in the sdb symbol list.  */
+#define IGNORE_SYMBOL(type) (type == N_ENTRY || type == 0xa4)
+
+/* We don't want the extra gnu symbols on the machine;
+   they will interfere with the shared segment symbols.  */
+#define NO_GNU_STABS
+
+/* Macro for text-offset and data info (in NPL a.out format).  */
+#define        TEXTINFO                                                \
+        text_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr);   \
+        exec_data_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr)\
+                + exec_aouthdr.a_text
+
+/* Macro for number of symbol table entries */
+#define NUMBER_OF_SYMBOLS                                      \
+       (coffhdr.f_nsyms)
+
+/* Macro for file-offset of symbol table (in NPL a.out format).  */
+#define SYMBOL_TABLE_OFFSET                                    \
+       N_SYMOFF (coffhdr)
+
+/* Macro for file-offset of string table (in NPL a.out format).  */
+#define STRING_TABLE_OFFSET                                    \
+       (N_STROFF (coffhdr))
+
+/* Macro to store the length of the string table data in INTO.  */
+#define READ_STRING_TABLE_SIZE(INTO)                           \
+       { INTO = hdr.a_stsize; }
+
+/* Macro to declare variables to hold the file's header data.  */
+#define DECLARE_FILE_HEADERS  struct exec hdr;                 \
+                             FILHDR coffhdr
+
+/* Macro to read the header data from descriptor DESC and validate it.
+   NAME is the file name, for error messages.  */
+#define READ_FILE_HEADERS(DESC, NAME)                          \
+{ val = myread (DESC, &coffhdr, sizeof coffhdr);               \
+  if (val < 0)                                                 \
+    perror_with_name (NAME);                                   \
+  val = myread (DESC, &hdr, sizeof hdr);                       \
+  if (val < 0)                                                 \
+    perror_with_name (NAME);                                   \
+  if (coffhdr.f_magic != GNP1MAGIC)                            \
+    error ("File \"%s\" not in coff executable format.", NAME);        \
+  if (N_BADMAG (hdr))                                          \
+    error ("File \"%s\" not in executable format.", NAME); }
+
+/* Define COFF and other symbolic names needed on NP1 */
+#define        NS32GMAGIC      GNP1MAGIC
+#define        NS32SMAGIC      GPNMAGIC
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+#define READ_DBX_FORMAT
+
+/* Address of blocks in N_LBRAC and N_RBRAC symbols are absolute addresses,
+   not relative to start of source address.  */
+#define BLOCK_ADDRESS_ABSOLUTE
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+#define FUNCTION_START_OFFSET  8
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  One NPL we can have one two startup
+   sequences depending on the size of the local stack:
+
+   Either:
+      "suabr b2, #"
+   of
+      "lil r4, #", "suabr b2, #(r4)"
+
+   "lwbr b6, #", "stw r1, 8(b2)"
+   Optional "stwbr b3, c(b2)"
+   Optional "trr r2,r7"      (Gould first argument register passing)
+     or
+   Optional "stw r2,8(b3)"   (Gould first argument register passing)
+ */
+#define SKIP_PROLOGUE(pc) {                                            \
+       register int op = read_memory_integer ((pc), 4);                \
+       if ((op & 0xffff0000) == 0xFA0B0000) {                          \
+           pc += 4;                                                    \
+           op = read_memory_integer ((pc), 4);                         \
+           if ((op & 0xffff0000) == 0x59400000) {                      \
+               pc += 4;                                                \
+               op = read_memory_integer ((pc), 4);                     \
+               if ((op & 0xffff0000) == 0x5F000000) {                  \
+                   pc += 4;                                            \
+                   op = read_memory_integer ((pc), 4);                 \
+                   if (op == 0xD4820008) {                             \
+                       pc += 4;                                        \
+                       op = read_memory_integer ((pc), 4);             \
+                       if (op == 0x5582000C) {                         \
+                           pc += 4;                                    \
+                           op = read_memory_integer ((pc), 2);         \
+                           if (op == 0x2fa0) {                         \
+                               pc += 2;                                \
+                           } else {                                    \
+                               op = read_memory_integer ((pc), 4);     \
+                               if (op == 0xd5030008) {                 \
+                                   pc += 4;                            \
+                               }                                       \
+                           }                                           \
+                       } else {                                        \
+                           op = read_memory_integer ((pc), 2);         \
+                           if (op == 0x2fa0) {                         \
+                               pc += 2;                                \
+                           }                                           \
+                       }                                               \
+                   }                                                   \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+       if ((op & 0xffff0000) == 0x59000000) {                          \
+           pc += 4;                                                    \
+           op = read_memory_integer ((pc), 4);                         \
+           if ((op & 0xffff0000) == 0x5F000000) {                      \
+               pc += 4;                                                \
+               op = read_memory_integer ((pc), 4);                     \
+               if (op == 0xD4820008) {                                 \
+                   pc += 4;                                            \
+                   op = read_memory_integer ((pc), 4);                 \
+                   if (op == 0x5582000C) {                             \
+                       pc += 4;                                        \
+                       op = read_memory_integer ((pc), 2);             \
+                       if (op == 0x2fa0) {                             \
+                           pc += 2;                                    \
+                       } else {                                        \
+                           op = read_memory_integer ((pc), 4);         \
+                           if (op == 0xd5030008) {                     \
+                               pc += 4;                                \
+                           }                                           \
+                       }                                               \
+                   } else {                                            \
+                       op = read_memory_integer ((pc), 2);             \
+                       if (op == 0x2fa0) {                             \
+                           pc += 2;                                    \
+                       }                                               \
+                   }                                                   \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  True on NPL! Return address is in R1.
+   The true return address is REALLY 4 past that location! */
+#define SAVED_PC_AFTER_CALL(frame) \
+       (read_register(R1_REGNUM) + 4)
+
+/* Address of end of stack space.  */
+#define STACK_END_ADDR                 0x7fffc000
+
+/* Stack grows downward.  */
+#define INNER_THAN             <
+
+/* Sequence of bytes for breakpoint instruction.
+   This is padded out to the size of a machine word.  When it was just
+   {0x28, 0x09} it gave problems if hit breakpoint on returning from a
+   function call.  */
+#define BREAKPOINT             {0x28, 0x09, 0x0, 0x0}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+#define DECR_PC_AFTER_BREAK    2
+
+/* Nonzero if instruction at PC is a return instruction. "bu 4(r1)" */
+#define ABOUT_TO_RETURN(pc)    (read_memory_integer (pc, 4) == 0x40100004)
+
+/* Return 1 if P points to an invalid floating point value.  */
+#define INVALID_FLOAT(p, len)  ((*(short *)p & 0xff80) == 0x8000)
+
+/* Say how long (ordinary) registers are.  */
+#define REGISTER_TYPE          long
+
+/* Size of bytes of vector register (NP1 only), 32 elements * sizeof(int) */
+#define VR_SIZE                        128
+
+/* Number of machine registers */
+#define NUM_REGS               27
+#define NUM_GEN_REGS           16
+#define NUM_CPU_REGS           4
+#define NUM_VECTOR_REGS                7
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+#define REGISTER_NAMES { \
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+  "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
+  "sp", "ps", "pc", "ve", \
+  "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
+}
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+#define R1_REGNUM      1       /* Gr1 => return address of caller */
+#define R2_REGNUM      2       /* Gr2 => return value from function */
+#define R4_REGNUM      4       /* Gr4 => register save area */
+#define R5_REGNUM      5       /* Gr5 => register save area */
+#define R6_REGNUM      6       /* Gr6 => register save area */
+#define R7_REGNUM      7       /* Gr7 => register save area */
+#define B1_REGNUM      9       /* Br1 => start of this code routine */
+#define SP_REGNUM      10      /* Br2 == (sp) */
+#define AP_REGNUM      11      /* Br3 == (ap) */
+#define FP_REGNUM      16      /* A copy of Br2 saved in trap */
+#define PS_REGNUM      17      /* Contains processor status */
+#define PC_REGNUM      18      /* Contains program counter */
+#define VE_REGNUM      19      /* Vector end (user setup) register */
+#define V1_REGNUM      20      /* First vector register */
+#define V7_REGNUM      26      /* First vector register */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES \
+       (NUM_GEN_REGS*4 + NUM_VECTOR_REGS*VR_SIZE + NUM_CPU_REGS*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+#define REGISTER_BYTE(N)  \
+       (((N) < V1_REGNUM) ? ((N) * 4) : (((N) - V1_REGNUM) * VR_SIZE) + 80)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the NP1, all normal regs are 4 bytes, but
+   the vector registers are VR_SIZE*4 bytes long. */
+#define REGISTER_RAW_SIZE(N) \
+       (((N) < V1_REGNUM) ? 4 : VR_SIZE)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the NP1, all regs are 4 bytes. */
+#define REGISTER_VIRTUAL_SIZE(N) \
+       (((N) < V1_REGNUM) ? 4 : VR_SIZE)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+#define MAX_REGISTER_RAW_SIZE          VR_SIZE
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+#define MAX_REGISTER_VIRTUAL_SIZE      VR_SIZE
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+#define REGISTER_CONVERTIBLE(N)                (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+       bcopy ((FROM), (TO), REGISTER_RAW_SIZE(REGNUM));
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+       bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+#define REGISTER_VIRTUAL_TYPE(N)       \
+  ((N) > VE_REGNUM ? builtin_type_np1_vector : builtin_type_int)
+extern struct type *builtin_type_np1_vector;
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function.
+
+   On this machine this is a no-op, because gcc isn't used on it
+   yet.  So this calling convention is not used. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) push_word(SP + 8, ADDR)
+
+/* Extract from an arrary REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+       bcopy (((int *)(REGBUF)) + 2, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+       write_register_bytes (REGISTER_BYTE (R2_REGNUM), VALBUF,      \
+                             TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*((int *)(REGBUF) + 2))
+
+/* Both gcc and cc return small structs in registers (i.e. in GDB
+   terminology, small structs don't use the struct return convention).  */
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH(type) > 8)
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the NPL, the frame's norminal address is Br2 and the 
+   previous routines frame is up the stack X bytes, where X is the
+   value stored in the code function header xA(Br1). */
+#define FRAME_CHAIN(thisframe)         (findframe(thisframe))
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+        (chain != 0 && chain != (thisframe)->frame)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) \
+       (chain)
+
+/* Define other aspects of the stack frame on NPL.  */
+#define FRAME_SAVED_PC(FRAME) \
+       (read_memory_integer ((FRAME)->frame + 8, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) \
+       ((fi)->next_frame ? \
+        read_memory_integer ((fi)->frame + 12, 4) : \
+        read_register (AP_REGNUM))
+
+#define FRAME_LOCALS_ADDRESS(fi)       ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+   Can set VAL to -1, meaning no way to tell.  */
+
+/* We can check the stab info to see how
+   many arg we have.  No info in stack will tell us */
+#define FRAME_NUM_ARGS(val,fi)         (val = findarg(fi))
+
+/* Return number of bytes at start of arglist that are not really args.  */
+#define FRAME_ARGS_SKIP                        8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{                                                                       \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  (frame_saved_regs).regs[SP_REGNUM] = framechain (frame_info);         \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[R4_REGNUM] = (frame_info)->frame + 0x30;     \
+  (frame_saved_regs).regs[R5_REGNUM] = (frame_info)->frame + 0x34;     \
+  (frame_saved_regs).regs[R6_REGNUM] = (frame_info)->frame + 0x38;     \
+  (frame_saved_regs).regs[R7_REGNUM] = (frame_info)->frame + 0x3C;     \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+#define CANNOT_EXECUTE_STACK
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM); \
+  register int regnum;                               \
+  for (regnum = 0; regnum < FP_REGNUM; regnum++)     \
+    sp = push_word (sp, read_register (regnum));     \
+  sp = push_word (sp, read_register (PS_REGNUM));    \
+  sp = push_word (sp, read_register (PC_REGNUM));    \
+  write_register (SP_REGNUM, sp);}
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ CORE_ADDR sp = read_register(SP_REGNUM);             \
+  REGISTER_TYPE reg;                                   \
+  int regnum;                                          \
+  for(regnum = 0;regnum < FP_REGNUM;regnum++){         \
+    sp-=sizeof(REGISTER_TYPE);                         \
+    read_memory(sp,&reg,sizeof(REGISTER_TYPE));        \
+    write_register(regnum,reg);}                       \
+  sp-=sizeof(REGISTER_TYPE);                           \
+  read_memory(sp,&reg,sizeof(REGISTER_TYPE));          \
+  write_register(PS_REGNUM,reg);                       \
+  sp-=sizeof(REGISTER_TYPE);                           \
+  read_memory(sp,&reg,sizeof(REGISTER_TYPE));          \
+  write_register(PC_REGNUM,reg);}
+
+/* MJD - Size of dummy frame pushed onto stack by PUSH_DUMMY_FRAME */
+
+#define DUMMY_FRAME_SIZE (0x48)
+
+/* MJD - The sequence of words in the instructions is
+   halt
+   halt
+   halt
+   halt
+   subr    b2,stack size,0             grab stack space for dummy call
+   labr    b3,x0(b2),0                 set AP_REGNUM to point at arguments
+   lw      r2,x8(b3),0                 load r2 with first argument    
+   lwbr    b1,arguments size(b2),0     load address of function to be called
+   brlnk   r1,x8(b1),0                 call function
+   halt
+   halt
+   labr    b2,stack size(b2),0         give back stack
+   break                               break
+   */
+
+#define CALL_DUMMY {0x00000000,  \
+                   0x00000000,  \
+                   0x59000000,  \
+                   0x598a0000,  \
+                   0xb5030008,  \
+                   0x5c820000,  \
+                   0x44810008,  \
+                   0x00000000,  \
+                   0x590a0000,  \
+                   0x28090000 }
+
+#define CALL_DUMMY_LENGTH 40
+
+#define CALL_DUMMY_START_OFFSET 8
+
+#define CALL_DUMMY_STACK_ADJUST 8
+
+/* MJD - Fixup CALL_DUMMY for the specific function call.
+   OK heres the problems
+   1) On a trap there are two copies of the stack pointer, one in SP_REGNUM
+      which is read/write and one in FP_REGNUM which is only read. It seems
+      that when restarting the GOULD NP1 uses FP_REGNUM's value.
+   2) Loading function address into b1 looks a bit difficult if bigger than
+      0x0000fffc, infact from what I can tell the compiler sets up table of
+      function address in base3 through which function calls are referenced.
+
+   OK my solutions
+     Calculate the size of the dummy stack frame and do adjustments of
+     SP_REGNUM in the dummy call.
+     Push function address onto the stack and load it in the dummy call
+ */
+
+#define FIX_CALL_DUMMY(dummyname, sp, fun, nargs, args, type, gcc_p) \
+  {   int i;\
+      int arg_len = 0, total_len;\
+      old_sp = push_word(old_sp,fun);\
+      for(i = nargs - 1;i >= 0;i--)\
+       arg_len += TYPE_LENGTH (VALUE_TYPE (value_arg_coerce (args[i])));\
+      if(struct_return)\
+       arg_len += TYPE_LENGTH(value_type);\
+      total_len = DUMMY_FRAME_SIZE+CALL_DUMMY_STACK_ADJUST+4+arg_len;\
+      dummyname[0] += total_len;\
+      dummyname[2] += total_len;\
+      dummyname[5] += arg_len+CALL_DUMMY_STACK_ADJUST;\
+      dummyname[8] += total_len;}
+
+/* MJD - So the stack should end up looking like this
+
+                   | Normal stack frame  |
+                   | from normal program |
+                   | flow                |
+                   +---------------------+ <- Final sp - 0x08 - argument size
+                   |                     |    - 0x4 - dummy_frame_size
+                   | Pushed dummy frame  |
+                   |  b0-b7, r0-r7       |
+                   |  pc and ps          |
+                   |                     |
+                   +---------------------+
+                   | Function address    |
+                   +---------------------+ <- Final sp - 0x8 - arguments size
+                   |                     |
+                   |                     |
+                   |                     |
+                   |  Arguments to       |
+                   |       Function      |
+                   |                     |
+                   |                     |
+                   |                     |
+                   +---------------------+ <- Final sp - 0x8
+                   | Dummy_stack_adjust  |
+                   +---------------------+ <- Final sp
+                   |                     |
+                   | where call will     |
+                   |   build frame       |
+*/
diff --git a/gdb/tm-pn.h b/gdb/tm-pn.h
new file mode 100644 (file)
index 0000000..82bf919
--- /dev/null
@@ -0,0 +1,444 @@
+/* Parameters for targe of a Gould Powernode, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define GOULD_PN
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* This code appears in libraries on Gould machines.  Ignore it. */
+#define IGNORE_SYMBOL(type) (type == N_ENTRY)
+
+/* We don't want the extra gnu symbols on the machine;
+   they will interfere with the shared segment symbols.  */
+#define NO_GNU_STABS
+
+/* Macro for text-offset and data info (in PN a.out format).  */
+#define        TEXTINFO                                                \
+       text_offset = N_TXTOFF (exec_coffhdr);                  \
+       exec_data_offset = N_TXTOFF (exec_coffhdr)              \
+               + exec_aouthdr.a_text
+
+/* Macro for number of symbol table entries */
+#define END_OF_TEXT_DEFAULT                                    \
+       (0xffffff)
+
+/* Macro for number of symbol table entries */
+#define NUMBER_OF_SYMBOLS                                      \
+       (coffhdr.f_nsyms)
+
+/* Macro for file-offset of symbol table (in usual a.out format).  */
+#define SYMBOL_TABLE_OFFSET                                    \
+       N_SYMOFF (coffhdr)
+
+/* Macro for file-offset of string table (in usual a.out format).  */
+#define STRING_TABLE_OFFSET                                    \
+       (N_STROFF (coffhdr) + sizeof(int))
+
+/* Macro to store the length of the string table data in INTO.  */
+#define READ_STRING_TABLE_SIZE(INTO)                           \
+       { INTO = hdr.a_stsize; }
+
+/* Macro to declare variables to hold the file's header data.  */
+#define DECLARE_FILE_HEADERS  struct old_exec hdr;             \
+                             FILHDR coffhdr
+
+/* Macro to read the header data from descriptor DESC and validate it.
+   NAME is the file name, for error messages.  */
+#define READ_FILE_HEADERS(DESC, NAME)                          \
+{ val = myread (DESC, &coffhdr, sizeof coffhdr);               \
+  if (val < 0)                                                 \
+    perror_with_name (NAME);                                   \
+  val = myread (DESC, &hdr, sizeof hdr);                       \
+  if (val < 0)                                                 \
+    perror_with_name (NAME);                                   \
+  if (coffhdr.f_magic != GNP1MAGIC)                            \
+    error ("File \"%s\" not in coff executable format.", NAME);        \
+  if (N_BADMAG (hdr))                                          \
+    error ("File \"%s\" not in executable format.", NAME); }
+
+/* Define COFF and other symbolic names needed on NP1 */
+#define        NS32GMAGIC      GDPMAGIC
+#define        NS32SMAGIC      PN_MAGIC
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+#define FUNCTION_START_OFFSET  4
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  One PN we can have one or two startup
+   sequences depending on the size of the local stack:
+
+   Either:
+      "suabr b2, #"
+   of
+      "lil r4, #", "suabr b2, #(r4)"
+
+   "lwbr b6, #", "stw r1, 8(b2)"
+   Optional "stwbr b3, c(b2)"
+   Optional "trr r2,r7"      (Gould first argument register passing)
+     or
+   Optional "stw r2,8(b3)"   (Gould first argument register passing)
+ */
+#define SKIP_PROLOGUE(pc) {                                            \
+       register int op = read_memory_integer ((pc), 4);                \
+       if ((op & 0xffff0000) == 0x580B0000) {                          \
+           pc += 4;                                                    \
+           op = read_memory_integer ((pc), 4);                         \
+           if ((op & 0xffff0000) == 0x59400000) {                      \
+               pc += 4;                                                \
+               op = read_memory_integer ((pc), 4);                     \
+               if ((op & 0xffff0000) == 0x5F000000) {                  \
+                   pc += 4;                                            \
+                   op = read_memory_integer ((pc), 4);                 \
+                   if (op == 0xD4820008) {                             \
+                       pc += 4;                                        \
+                       op = read_memory_integer ((pc), 4);             \
+                       if (op == 0x5582000C) {                         \
+                           pc += 4;                                    \
+                           op = read_memory_integer ((pc), 2);         \
+                           if (op == 0x2fa0) {                         \
+                               pc += 2;                                \
+                           } else {                                    \
+                               op = read_memory_integer ((pc), 4);     \
+                               if (op == 0xd5030008) {                 \
+                                   pc += 4;                            \
+                               }                                       \
+                           }                                           \
+                       } else {                                        \
+                           op = read_memory_integer ((pc), 2);         \
+                           if (op == 0x2fa0) {                         \
+                               pc += 2;                                \
+                           }                                           \
+                       }                                               \
+                   }                                                   \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+       if ((op & 0xffff0000) == 0x59000000) {                          \
+           pc += 4;                                                    \
+           op = read_memory_integer ((pc), 4);                         \
+           if ((op & 0xffff0000) == 0x5F000000) {                      \
+               pc += 4;                                                \
+               op = read_memory_integer ((pc), 4);                     \
+               if (op == 0xD4820008) {                                 \
+                   pc += 4;                                            \
+                   op = read_memory_integer ((pc), 4);                 \
+                   if (op == 0x5582000C) {                             \
+                       pc += 4;                                        \
+                       op = read_memory_integer ((pc), 2);             \
+                       if (op == 0x2fa0) {                             \
+                           pc += 2;                                    \
+                       } else {                                        \
+                           op = read_memory_integer ((pc), 4);         \
+                           if (op == 0xd5030008) {                     \
+                               pc += 4;                                \
+                           }                                           \
+                       }                                               \
+                   } else {                                            \
+                       op = read_memory_integer ((pc), 2);             \
+                       if (op == 0x2fa0) {                             \
+                           pc += 2;                                    \
+                       }                                               \
+                   }                                                   \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  True on PN!  Return address is in R1.
+   Note: true return location is 4 bytes past R1! */
+#define SAVED_PC_AFTER_CALL(frame) \
+       (read_register(R1_REGNUM) + 4)
+
+/* Address of end of stack space.  */
+#define STACK_END_ADDR                 0x480000
+
+/* Stack grows downward.  */
+#define INNER_THAN             <
+
+/* Sequence of bytes for breakpoint instruction.  */
+#define BREAKPOINT             {0x28, 0x09}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+#define DECR_PC_AFTER_BREAK    2
+
+/* Nonzero if instruction at PC is a return instruction. "bu 4(r1)" */
+#define ABOUT_TO_RETURN(pc)    (read_memory_integer (pc, 4) == 0xEC100004)
+
+/* Return 1 if P points to an invalid floating point value.  */
+#define INVALID_FLOAT(p, len)  ((*(short *)p & 0xff80) == 0x8000)
+
+/* Say how long (ordinary) registers are.  */
+#define REGISTER_TYPE          long
+
+/* Number of machine registers */
+#define NUM_REGS               19
+#define NUM_GEN_REGS           16
+#define NUM_CPU_REGS           3
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+#define REGISTER_NAMES { \
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+  "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
+  "sp", "ps", "pc", \
+}
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+#define R1_REGNUM      1       /* Gr1 => return address of caller */
+#define R4_REGNUM      4       /* Gr4 => register save area */
+#define R5_REGNUM      5       /* Gr5 => register save area */
+#define R6_REGNUM      6       /* Gr6 => register save area */
+#define R7_REGNUM      7       /* Gr7 => register save area */
+#define B1_REGNUM      9       /* Br1 => start of this code routine */
+#define FP_REGNUM      10      /* Br2 == (sp) */
+#define AP_REGNUM      11      /* Br3 == (ap) */
+#define SP_REGNUM      16      /* A copy of Br2 saved in trap */
+#define PS_REGNUM      17      /* Contains processor status */
+#define PC_REGNUM      18      /* Contains program counter */
+
+/* This is a piece of magic that is given a register number REGNO
+   and as BLOCKEND the address in the system of the end of the user structure
+   and stores in ADDR the address in the kernel or core dump
+   of that register. */
+#define REGISTER_U_ADDR(addr, blockend, regno) {                       \
+       addr = blockend + regno * 4;                                    \
+       if (regno == PC_REGNUM) addr = blockend - 8 * 4;                \
+       if (regno == PS_REGNUM) addr = blockend - 7 * 4;                \
+       if (regno == SP_REGNUM) addr = blockend - 6 * 4;                \
+}
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES                 (NUM_GEN_REGS*4 + NUM_CPU_REGS*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+#define REGISTER_BYTE(N)               ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the PN, all normal regs are 4 bytes. */
+#define REGISTER_RAW_SIZE(N)           (4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the PN, all regs are 4 bytes. */
+#define REGISTER_VIRTUAL_SIZE(N)       (4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+#define MAX_REGISTER_RAW_SIZE          (4)
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+#define MAX_REGISTER_VIRTUAL_SIZE      (4)
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+#define REGISTER_CONVERTIBLE(N)                (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+       bcopy ((FROM), (TO), REGISTER_RAW_SIZE(REGNUM));
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+       bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+#define REGISTER_VIRTUAL_TYPE(N)       (builtin_type_int)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function.
+
+   On this machine this is a no-op, because gcc isn't used on it
+   yet.  So this calling convention is not used. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP)
+
+/* Extract from an arrary REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF. */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+       bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+       write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the NPL, the frame's norminal address is Br2 and the 
+   previous routines frame is up the stack X bytes, where X is the
+   value stored in the code function header xA(Br1). */
+#define FRAME_CHAIN(thisframe)         (findframe(thisframe))
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+        (chain != 0 && chain != (thisframe)->frame)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) \
+       (chain)
+
+/* Define other aspects of the stack frame on NPL.  */
+#define FRAME_SAVED_PC(frame) \
+       (read_memory_integer ((frame)->frame + 8, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) \
+       ((fi)->next_frame ? \
+        read_memory_integer ((fi)->frame + 12, 4) : \
+        read_register (AP_REGNUM))
+
+#define FRAME_LOCALS_ADDRESS(fi)       ((fi)->frame + 80)
+
+/* Set VAL to the number of args passed to frame described by FI.
+   Can set VAL to -1, meaning no way to tell.  */
+
+/* We can check the stab info to see how
+   many arg we have.  No info in stack will tell us */
+#define FRAME_NUM_ARGS(val,fi)         (val = findarg(fi))
+
+/* Return number of bytes at start of arglist that are not really args.  */
+#define FRAME_ARGS_SKIP                        8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)            \
+{                                                                       \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);                  \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 8;                \
+  (frame_saved_regs).regs[R4_REGNUM] = (frame_info)->frame + 0x30;     \
+  (frame_saved_regs).regs[R5_REGNUM] = (frame_info)->frame + 0x34;     \
+  (frame_saved_regs).regs[R6_REGNUM] = (frame_info)->frame + 0x38;     \
+  (frame_saved_regs).regs[R7_REGNUM] = (frame_info)->frame + 0x3C;     \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                        \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                      \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions:
+     halt
+     halt
+     halt
+     halt
+     suabr     b2, #<stacksize>
+     lwbr      b6, #con
+     stw       r1, 8(b2)       - save caller address, do we care?
+     lw                r2, 60(b2)      - arg1
+     labr      b3, 50(b2)
+     std       r4, 30(b2)      - save r4-r7
+     std       r6, 38(b2)
+     lwbr      b1, #<func>     - load function call address
+     brlnk     r1, 8(b1)       - call function
+     halt
+     halt
+     ld                r4, 30(b2)      - restore r4-r7
+     ld                r6, 38(b2)
+
+   Setup our stack frame, load argumemts, call and then restore registers.
+*/
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
diff --git a/gdb/tm-pyr.h b/gdb/tm-pyr.h
new file mode 100644 (file)
index 0000000..e37f8f5
--- /dev/null
@@ -0,0 +1,530 @@
+/* Definitions to make GDB run on a Pyramidax under OSx 4.0 (4.2bsd).
+   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Traditional Unix virtual address spaces have thre regions: text,
+   data and stack.  The text, initialised data, and uninitialised data
+   are represented in separate segments of the a.out file.
+   When a process dumps core, the data and stack regions are written
+   to a core file.  This gives a debugger enough information to
+   reconstruct (and debug) the virtual address space at the time of
+   the coredump.
+   Pyramids have an distinct fourth region of the virtual address
+   space, in which the contents of the windowed registers are stacked
+   in fixed-size frames.  Pyramid refer to this region as the control
+   stack.  Each call (or trap) automatically allocates a new register
+   frame; each return deallocates the current frame and restores the
+   windowed registers to their values before the call.
+
+   When dumping core, the control stack is written to a core files as
+   a third segment. The core-handling functions need to know to deal
+   with it. */ 
+/* Tell core.c there is an extra segment.  */
+#define REG_STACK_SEGMENT
+
+/* Floating point is IEEE compatible on most Pyramid hardware
+   (Older processors do not have IEEE NaNs).  */
+#define IEEE_FLOAT
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+/* FIXME -- do we want to skip insns to allocate the local frame?
+   If so, what do they look like?
+   This is becoming harder, since tege@sics.SE wants to change
+   gcc to not output a prologue when no frame is needed.   */
+#define SKIP_PROLOGUE(pc)  do {} while (0)
+
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) FRAME_SAVED_PC(frame)
+
+/* Address of end of stack space.  */
+/* This seems to be right for the 90x comp.vuw.ac.nz.
+   The correct value at any site may be a function of the configured
+   maximum control stack depth.  If so, I don't know where the
+   control-stack depth is configured, so I can't #include it here. */ 
+#define STACK_END_ADDR (0xc00cc000)
+
+/* Register window stack (Control stack) stack definitions
+    - Address of beginning of control stack.
+    - size of control stack frame
+   (Note that since crts0 is usually the first function called,
+    main()'s control stack is one frame (0x80 bytes) beyond this value.  */
+
+#define CONTROL_STACK_ADDR (0xc00cd000)
+
+/* Bytes in a register window -- 16 parameter regs, 16 local regs
+   for each call, is 32 regs * 4 bytes */
+
+#define CONTROL_STACK_FRAME_SIZE (32*4)
+
+/* FIXME.  On a pyr, Data Stack grows downward; control stack goes upwards. 
+   Which direction should we use for INNER_THAN, PC_INNER_THAN ?? */
+
+#define INNER_THAN <
+#define PC_INNER_THAN >
+
+/* Stack has strict alignment.  */
+
+#define STACK_ALIGN(ADDR) (((ADDR)+3)&-4)
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xf0, 00, 00, 00}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction. 
+   On a pyr, this is either "ret" or "retd".
+   It would be friendly to check that any "retd" always had an
+   argument of 0, since anything else is invalid. */
+
+#define ABOUT_TO_RETURN(pc) \
+(((read_memory_integer (pc, 2) & 0x3ff0) == 0x3090) || \
+ ((read_memory_integer (pc, 2) & 0x0ff0) == 0x00a0))
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the Vax.  */
+/* FIXME -- this is ok for a vax, bad for big-endian ieee format.
+   I would use the definition for a Sun; but it is no better! */
+
+#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+/* pyramids have 64, plus one for the PSW; plus perhaps one more for the
+   kernel stack pointer (ksp) and control-stack pointer (CSP) */
+
+#define NUM_REGS 67
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES \
+{"gr0", "gr1", "gr2", "gr3", "gr4", "gr5", "gr6", "gr7", \
+ "gr8", "gr9", "gr10", "gr11", "logpsw", "cfp", "sp", "pc", \
+ "pr0", "pr1", "pr2", "pr3", "pr4", "pr5", "pr6", "pr7", \
+ "pr8", "pr9", "pr10", "pr11", "pr12", "pr13", "pr14", "pr15", \
+ "lr0", "lr1", "lr2", "lr3", "lr4", "lr5", "lr6", "lr7", \
+ "lr8", "lr9", "lr10", "lr11", "lr12", "lr13", "lr14", "lr15", \
+ "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \
+ "tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15", \
+  "psw", "ksp", "csp"}
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+/* pseudo-registers: */
+#define PS_REGNUM 64           /* Contains processor status */
+#define PSW_REGNUM 64          /* Contains current psw, whatever it is.*/
+#define CSP_REGNUM 65          /* address of this control stack frame*/
+#define KSP_REGNUM 66          /* Contains process's Kernel Stack Pointer */
+
+#define CFP_REGNUM 13          /* Current data-stack frame ptr */
+#define TR0_REGNUM 48          /* After function call, contains
+                                  function result */
+
+/* Registers interesting to the machine-independent part of gdb*/
+
+#define FP_REGNUM CSP_REGNUM   /* Contains address of executing (control)
+                                  stack frame */
+#define SP_REGNUM 14           /* Contains address of top of stack -??*/
+#define PC_REGNUM 15           /* Contains program counter */
+
+/* Define DO_REGISTERS_INFO() to do machine-specific formatting
+   of register dumps. */
+
+#define DO_REGISTERS_INFO(_regnum) pyr_do_registers_info(_regnum)
+
+/* need this so we can find the global registers: they never get saved. */
+extern unsigned int global_reg_offset;
+extern unsigned int last_frame_offset;
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS*4)
+
+/* the Pyramid has register windows.  */
+
+#define HAVE_REGISTER_WINDOWS
+
+/* Is this register part of the register window system?  A yes answer
+   implies that 1) The name of this register will not be the same in
+   other frames, and 2) This register is automatically "saved" (out
+   registers shifting into ins counts) upon subroutine calls and thus
+   there is no need to search more than one stack frame for it. */
+
+#define REGISTER_IN_WINDOW_P(regnum)   \
+  ((regnum) >= 16 && (regnum) < 64)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the Pyramid, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the Pyramid, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  bcopy ((FROM), (TO), 4);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), 4);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) builtin_type_int
+
+/* FIXME: It seems impossible for both EXTRACT_RETURN_VALUE and
+   STORE_RETURN_VALUE to be correct. */
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+/****FIXME****/
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { write_register (TR0_REGNUM, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+/* Note that on a register-windowing machine (eg, Pyr, SPARC), this is
+   where the value is found after the function call -- ie, it should
+   correspond to GNU CC's FUNCTION_VALUE rather than FUNCTION_OUTGOING_VALUE.*/
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (((int *)(REGBUF))+TR0_REGNUM, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+/* on pyrs, values are returned in */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (REGISTER_BYTE(TR0_REGNUM), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+/* FIXME */
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+  ( ((int *)(REGBUF)) [TR0_REGNUM])
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+#define EXTRA_FRAME_INFO \
+       FRAME_ADDR bottom;      \
+       CORE_ADDR frame_cfp;    \
+       CORE_ADDR frame_window_addr;
+
+#define INIT_EXTRA_FRAME_INFO(fci)  \
+do {                                                           \
+  (fci)->frame_window_addr = (fci)->frame;                     \
+  (fci)->bottom =                                              \
+         ((fci)->next ?                                        \
+          ((fci)->frame == (fci)->next_frame ?                 \
+           (fci)->next->bottom : (fci)->next->frame) :         \
+          read_register (SP_REGNUM));                          \
+  (fci)->frame_cfp =                                           \
+         read_register (CFP_REGNUM);                           \
+  /***fprintf (stderr,                                         \
+          "[[creating new frame for %0x,pc=%0x,csp=%0x]]\n",   \
+          (fci)->frame, (fci)->pc,(fci)->frame_cfp);*/         \
+} while (0);
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the pyr, the frame's nominal address is the address
+   of parameter register 0.  The previous frame is found 32 words up.   */
+
+#define FRAME_CHAIN(thisframe) \
+  ( (thisframe) -> frame - CONTROL_STACK_FRAME_SIZE)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+ /*((thisframe) >= CONTROL_STACK_ADDR))*/
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.
+
+   I do not understand what this means on a Pyramid, where functions
+   *always* have a control-stack frame, but may or may not have a
+   frame on the data stack.  Since GBD uses the value of the
+   control stack pointer as its "address" of a frame, FRAMELESS
+   is always 1, so does not need to be defined.  */
+
+
+/* Where is the PC for a specific frame */
+
+#define FRAME_SAVED_PC(fi) \
+  ((CORE_ADDR) (read_memory_integer ( (fi) -> frame + 60, 4)))
+
+/* There may be bugs in FRAME_ARGS_ADDRESS and FRAME_LOCALS_ADDRESS;
+   or there may be bugs in accessing the registers that break
+   their definitions.
+   Having the macros expand into functions makes them easier to debug.
+   When the bug is finally located, the inline macro defintions can
+   be un-#if 0ed, and frame_args_addr and frame_locals_address can
+   be deleted from pyr-dep.c */ 
+
+/* If the argument is on the stack, it will be here.  */
+#define FRAME_ARGS_ADDRESS(fi) \
+  frame_args_addr(fi)
+
+#define FRAME_LOCALS_ADDRESS(fi) \
+  frame_locals_address(fi)
+
+/* The following definitions doesn't seem to work.
+   I don't understand why. */
+#if 0
+#define FRAME_ARGS_ADDRESS(fi) \
+   /*(FRAME_FP(fi) + (13*4))*/ (read_register (CFP_REGNUM))
+
+#define FRAME_LOCALS_ADDRESS(fi) \
+  ((fi)->frame +(16*4))
+
+#endif /* 0 */
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(val, fi)  (val = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.
+
+   Note that on register window machines, we are currently making the
+   assumption that window registers are being saved somewhere in the
+   frame in which they are being used.  If they are stored in an
+   inferior frame, find_saved_register will break.
+
+   On pyrs, frames of window registers are stored contiguously on a
+   separate stack.  All window registers are always stored.
+   The pc and psw (gr15 and gr14)  are also always saved: the call
+   insn saves them in pr15 and pr14 of the new frame (tr15,tr14 of the
+   old frame).  
+   The data-stack frame pointer (CFP) is only saved in functions which
+   allocate a (data)stack frame (with "adsf").  We detect them by
+   looking at the first insn of the procedure. 
+
+   Other non-window registers (gr0-gr11) are never saved.  Pyramid's C
+   compiler and gcc currently ignore them, so it's not an issue.   */ 
+
+#define FRAME_FIND_SAVED_REGS(fi_p, frame_saved_regs) \
+{  register int regnum;                                                        \
+  register CORE_ADDR pc;                                               \
+  register CORE_ADDR fn_start_pc;                                      \
+  register int first_insn;                                             \
+  register CORE_ADDR prev_cf_addr;                                     \
+  register int window_ptr;                                             \
+  FRAME fid = FRAME_INFO_ID (fi_p);                                    \
+  if (!fid) fatal ("Bad frame info struct in FRAME_FIND_SAVED_REGS");  \
+  bzero (&(frame_saved_regs), sizeof (frame_saved_regs));              \
+                                                                       \
+  window_ptr = prev_cf_addr = FRAME_FP(fi_p);                          \
+                                                                       \
+  for (regnum = 16 ; regnum < 64; regnum++,window_ptr+=4)              \
+  {                                                                    \
+    (frame_saved_regs).regs[regnum] = window_ptr;                      \
+  }                                                                    \
+                                                                       \
+  /* In each window, psw, and pc are "saved" in tr14,tr15. */          \
+  /*** psw is sometimes saved in gr12 (so sez <sys/pcb.h>) */          \
+  (frame_saved_regs).regs[PS_REGNUM] = FRAME_FP(fi_p) + (14*4);        \
+                                                                       \
+/*(frame_saved_regs).regs[PC_REGNUM] = (frame_saved_regs).regs[31];*/  \
+  (frame_saved_regs).regs[PC_REGNUM] = FRAME_FP(fi_p) + ((15+32)*4);   \
+                                                                       \
+  /* Functions that allocate a frame save sp *where*? */               \
+/*first_insn = read_memory_integer (get_pc_function_start ((fi_p)->pc),4); */ \
+                                                                       \
+  fn_start_pc = (get_pc_function_start ((fi_p)->pc));                  \
+  first_insn = read_memory_integer(fn_start_pc, 4);                    \
+                                                                       \
+  if (0x08 == ((first_insn >> 20) &0x0ff)) {                           \
+    /* NB: because WINDOW_REGISTER_P(cfp) is false, a saved cfp                \
+       in this frame is only visible in this frame's callers.          \
+       That means the cfp we mark saved is my caller's cfp, ie pr13.   \
+       I don't understand why we don't have to do that for pc, too.  */        \
+                                                                       \
+    (frame_saved_regs).regs[CFP_REGNUM] = FRAME_FP(fi_p)+(13*4);       \
+                                                                       \
+    (frame_saved_regs).regs[SP_REGNUM] =                               \
+         read_memory_integer (FRAME_FP(fi_p)+((13+32)*4),4);           \
+  }                                                                    \
+                                                                       \
+/*                                                                     \
+ *(frame_saved_regs).regs[CFP_REGNUM] = (frame_saved_regs).regs[61];   \
+ * (frame_saved_regs).regs[SP_REGNUM] =                                        \
+ *       read_memory_integer (FRAME_FP(fi_p)+((13+32)*4),4);           \
+ */                                                                    \
+                                                                       \
+  (frame_saved_regs).regs[CSP_REGNUM] = prev_cf_addr;                  \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+#if 0
+/* These are all lies.  These macro definitions are appropriate for a
+    SPARC. On a pyramid, pushing a dummy frame will
+   surely involve writing the control stack pointer,
+   then saving the pc.  This requires a privileged instruction.
+   Maybe one day Pyramid can be persuaded to add a syscall to do this.
+   Until then, we are out of luck. */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+  register int regnum;                             \
+  sp = push_word (sp, 0); /* arglist */                    \
+  for (regnum = 11; regnum >= 0; regnum--)         \
+    sp = push_word (sp, read_register (regnum));    \
+  sp = push_word (sp, read_register (PC_REGNUM));   \
+  sp = push_word (sp, read_register (FP_REGNUM));   \
+/*  sp = push_word (sp, read_register (AP_REGNUM));*/   \
+  sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef)   \
+                     + 0x2fff0000);                \
+  sp = push_word (sp, 0);                          \
+  write_register (SP_REGNUM, sp);                  \
+  write_register (FP_REGNUM, sp);                  \
+/*  write_register (AP_REGNUM, sp + 17 * sizeof (int));*/ }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register CORE_ADDR fp = read_register (FP_REGNUM);            \
+  register int regnum;                                          \
+  register int regmask = read_memory_integer (fp + 4, 4);       \
+  write_register (PS_REGNUM,                                    \
+                 (regmask & 0xffff)                             \
+                 | (read_register (PS_REGNUM) & 0xffff0000));   \
+  write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));  \
+  write_register (FP_REGNUM, read_memory_integer (fp + 12, 4));  \
+/*  write_register (AP_REGNUM, read_memory_integer (fp + 8, 4));*/   \
+  fp += 16;                                                     \
+  for (regnum = 0; regnum < 12; regnum++)                       \
+    if (regmask & (0x10000 << regnum))                          \
+      write_register (regnum, read_memory_integer (fp += 4, 4)); \
+  fp = fp + 4 + ((regmask >> 30) & 3);                          \
+  if (regmask & 0x20000000)                                     \
+    { regnum = read_memory_integer (fp, 4);                     \
+      fp += (regnum + 1) * 4; }                                         \
+  write_register (SP_REGNUM, fp);                               \
+  set_current_frame (read_register (FP_REGNUM)); }
+
+/* This sequence of words is the instructions
+     calls #69, @#32323232
+     bpt
+   Note this is 8 bytes.  */
+
+#define CALL_DUMMY {0x329f69fb, 0x03323232}
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ *((char *) dummyname + 1) = nargs;           \
+  *(int *)((char *) dummyname + 3) = fun; }
+#endif /* 0 */
+
+#define POP_FRAME \
+  { error ("The return command is not supported on this machine."); }
diff --git a/gdb/tm-sparc.h b/gdb/tm-sparc.h
new file mode 100644 (file)
index 0000000..b3316da
--- /dev/null
@@ -0,0 +1,586 @@
+/* Parameters for target machine of Sun 4, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@mcc.com)
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Floating point is IEEE compatible.  */
+#define IEEE_FLOAT
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* When passing a structure to a function, Sun cc passes the address
+   in a register, not the structure itself.  It (under SunOS4) creates
+   two symbols, so we get a LOC_ARG saying the address is on the stack
+   (a lie, and a serious one since we don't know which register to
+   use), and a LOC_REGISTER saying that the struct is in a register
+   (sort of a lie, but fixable with REG_STRUCT_HAS_ADDR).
+
+   This still doesn't work if the argument is not one passed in a
+   register (i.e. it's the 7th or later argument).  */
+#define REG_STRUCT_HAS_ADDR(gcc_p) (!(gcc_p))
+#define STRUCT_ARG_SYM_GARBAGE(gcc_p) (!(gcc_p))
+
+/* If Pcc says that a parameter is a short, it's a short.  This is
+   because the parameter does get passed in in a register as an int,
+   but pcc puts it onto the stack frame as a short (not nailing
+   whatever else might be there.  I'm not sure that I consider this
+   swift.  Sigh.)
+
+   No, don't do this.  The problem here is that pcc says that the
+   argument is in the upper half of the word reserved on the stack,
+   but puts it in the lower half.  */
+/* #define BELIEVE_PCC_PROMOTION 1 */
+/* OK, I've added code to dbxread.c to deal with this case.  */
+#define BELIEVE_PCC_PROMOTION_TYPE
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc) \
+  { pc = skip_prologue (pc); }
+extern CORE_ADDR skip_prologue ();
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+/* On the Sun 4 under SunOS, the compile will leave a fake insn which
+   encodes the structure size being returned.  If we detect such
+   a fake insn, step past it.  */
+
+#define PC_ADJUST(pc) ((read_memory_integer (pc + 8, 4) & 0xfffffe00) == 0 ? \
+                      pc+12 : pc+8)
+
+#define SAVED_PC_AFTER_CALL(frame) PC_ADJUST (read_register (RP_REGNUM))
+
+/* Address of the end of stack space.  We get this from the system
+   include files. */
+#include <sys/types.h>
+#include <machine/vmparam.h>
+#define STACK_END_ADDR USRSTACK
+
+#define INNER_THAN <
+
+/* Stack has strict alignment.  */
+
+#define STACK_ALIGN(ADDR) (((ADDR)+7)&-8)
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0x91, 0xd0, 0x20, 0x01}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+/* For SPARC, this is either a "jmpl %o7+8,%g0" or "jmpl %i7+8,%g0".
+
+   Note: this does not work for functions returning structures under SunOS.  */
+#define ABOUT_TO_RETURN(pc) \
+  ((read_memory_integer (pc, 4)|0x00040000) == 0x81c7e008)
+
+/* Return 1 if P points to an invalid floating point value.  */
+
+#define INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 72
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES  \
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",      \
+  "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",      \
+  "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",      \
+  "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",      \
+                                                               \
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",      \
+  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",        \
+  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",      \
+  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",      \
+                                                                \
+  "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define        G0_REGNUM 0             /* %g0 */
+#define        G1_REGNUM 1             /* %g1 */
+#define O0_REGNUM 8            /* %o0 */
+#define        SP_REGNUM 14            /* Contains address of top of stack, \
+                                  which is also the bottom of the frame.  */
+#define        RP_REGNUM 15            /* Contains return address value, *before* \
+                                  any windows get switched.  */
+#define        O7_REGNUM 15            /* Last local reg not saved on stack frame */
+#define        L0_REGNUM 16            /* First local reg that's saved on stack frame
+                                  rather than in machine registers */
+#define        I0_REGNUM 24            /* %i0 */
+#define        FP_REGNUM 30            /* Contains address of executing stack frame */
+#define        I7_REGNUM 31            /* Last local reg saved on stack frame */
+#define        FP0_REGNUM 32           /* Floating point register 0 */
+#define        Y_REGNUM 64             /* Temp register for multiplication, etc.  */
+#define        PS_REGNUM 65            /* Contains processor status */
+#define        WIM_REGNUM 66           /* Window Invalid Mask (not really supported) */
+#define        TBR_REGNUM 67           /* Trap Base Register (not really supported) */
+#define        PC_REGNUM 68            /* Contains program counter */
+#define        NPC_REGNUM 69           /* Contains next PC */
+#define        FPS_REGNUM 70           /* Floating point status register */
+#define        CPS_REGNUM 71           /* Coprocessor status register */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (32*4+32*4+8*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+/* ?? */
+#define REGISTER_BYTE(N)  ((N)*4)
+
+/* The SPARC processor has register windows.  */
+
+#define HAVE_REGISTER_WINDOWS
+
+/* Is this register part of the register window system?  A yes answer
+   implies that 1) The name of this register will not be the same in
+   other frames, and 2) This register is automatically "saved" (out
+   registers shifting into ins counts) upon subroutine calls and thus
+   there is no need to search more than one stack frame for it. */
+
+#define REGISTER_IN_WINDOW_P(regnum)   \
+  ((regnum) >= 8 && (regnum) < 32)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+/* On the SPARC, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) (4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  */
+
+/* On the SPARC, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) (4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
+{ bcopy ((FROM), (TO), 4); }
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+{ bcopy ((FROM), (TO), 4); }
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ ((N) < 32 ? builtin_type_int : (N) < 64 ? builtin_type_float : \
+  builtin_type_int)
+
+/* Writing to %g0 is a noop (not an error or exception or anything like
+   that, however).  */
+
+#define CANNOT_STORE_REGISTER(regno) ((regno) == G0_REGNUM)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { target_write_memory ((SP)+(16*4), (char *)&(ADDR), 4); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF)             \
+  {                                                                       \
+    if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)                                \
+      {                                                                           \
+       bcopy (((int *)(REGBUF))+FP0_REGNUM,                               \
+              (VALBUF), TYPE_LENGTH(TYPE));                               \
+      }                                                                           \
+    else                                                                  \
+      bcopy (((int *)(REGBUF))+8, (VALBUF), TYPE_LENGTH (TYPE));           \
+  }
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+/* On sparc, values are returned in register %o0.  */
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  {                                                                                 \
+    if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)                                  \
+      /* Floating-point values are returned in the register pair */          \
+      /* formed by %f0 and %f1 (doubles are, anyway).  */                    \
+      write_register_bytes (REGISTER_BYTE (FP0_REGNUM), (VALBUF),           \
+                           TYPE_LENGTH (TYPE));                             \
+    else                                                                    \
+      /* Other values are returned in register %o0.  */                      \
+      write_register_bytes (REGISTER_BYTE (O0_REGNUM), (VALBUF),            \
+                           TYPE_LENGTH (TYPE));  \
+  }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+  (read_memory_integer (((int *)(REGBUF))[SP_REGNUM]+(16*4), 4))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* I don't know whether this will work for cross-debugging, even if you
+   do get the right reg.h.  */
+#include <machine/reg.h>
+
+#define GET_RWINDOW_REG(FRAME, REG) \
+  (read_memory_integer ((CORE_ADDR)&((struct rwindow *)FRAME)->REG, 4))
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the Sun 4, the frame-chain's nominal address
+   is held in the frame pointer register.
+
+   On the Sun4, the frame (in %fp) is %sp for the previous frame.
+   From the previous frame's %sp, we can find the previous frame's
+   %fp: it is in the save area just above the previous frame's %sp.
+
+   If we are setting up an arbitrary frame, we'll need to know where
+   it ends.  Hence the following.  This part of the frame cache
+   structure should be checked before it is assumed that this frame's
+   bottom is in the stack pointer.
+
+   If there isn't a frame below this one, the bottom of this frame is
+   in the stack pointer.
+
+   If there is a frame below this one, and the frame pointers are
+   identical, it's a leaf frame and the bottoms are the same also.
+
+   Otherwise the bottom of this frame is the top of the next frame.  */
+
+#define EXTRA_FRAME_INFO       FRAME_ADDR bottom;
+#define INIT_EXTRA_FRAME_INFO(fci)  \
+  (fci)->bottom =                                      \
+   ((fci)->next ?                                      \
+    ((fci)->frame == (fci)->next_frame ?               \
+     (fci)->next->bottom : (fci)->next->frame) :       \
+    read_register (SP_REGNUM));
+
+#define FRAME_CHAIN(thisframe) \
+   GET_RWINDOW_REG ((thisframe)->frame, rw_in[6])
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+/* Where is the PC for a specific frame */
+
+#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME)
+CORE_ADDR frame_saved_pc ();
+
+/* If the argument is on the stack, it will be here.  */
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_STRUCT_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Set VAL to the number of args passed to frame described by FI.
+   Can set VAL to -1, meaning no way to tell.  */
+
+/* We can't tell how many args there are
+   now that the C compiler delays popping them.  */
+#define FRAME_NUM_ARGS(val,fi) (val = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 68
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   The actual code is in sparc-tdep.c so we can debug it sanely.  */
+
+#define FRAME_FIND_SAVED_REGS(fi, frame_saved_regs)                \
+       sparc_frame_find_saved_regs ((fi), &(frame_saved_regs))
+extern void sparc_frame_find_saved_regs ();
+\f
+/* Things needed for making the inferior call functions.  */
+/*
+ * First of all, let me give my opinion of what the DUMMY_FRAME
+ * actually looks like.
+ *
+ *               |                                 |
+ *               |                                 |
+ *               + - - - - - - - - - - - - - - - - +<-- fp (level 0)
+ *               |                                 |
+ *               |                                 |
+ *               |                                 |
+ *               |                                 |
+ *               |  Frame of innermost program     |
+ *               |           function              |
+ *               |                                 |
+ *               |                                 |
+ *               |                                 |
+ *               |                                 |
+ *               |                                 |
+ *               |---------------------------------|<-- sp (level 0), fp (c)
+ *               |                                 |
+ *     DUMMY     |             fp0-31              |
+ *               |                                 |
+ *               |             ------              |<-- fp - 0x80
+ *     FRAME     |              g0-7               |<-- fp - 0xa0
+ *               |              i0-7               |<-- fp - 0xc0
+ *               |             other               |<-- fp - 0xe0
+ *               |               ?                 |
+ *               |               ?                 |
+ *               |---------------------------------|<-- sp' = fp - 0x140
+ *               |                                 |
+ * xcution start |                                 |
+ * sp' + 0x94 -->|        CALL_DUMMY (x code)      |
+ *               |                                 |
+ *               |                                 |
+ *               |---------------------------------|<-- sp'' = fp - 0x200
+ *               |  align sp to 8 byte boundary    |
+ *               |     ==> args to fn <==          |
+ *  Room for     |                                 |
+ * i & l's + agg | CALL_DUMMY_STACK_ADJUST = 0x0x44|
+ *               |---------------------------------|<-- final sp (variable)
+ *               |                                 |
+ *               |   Where function called will    |
+ *               |           build frame.          |
+ *               |                                 |
+ *               |                                 |
+ *
+ *   I understand everything in this picture except what the space
+ * between fp - 0xe0 and fp - 0x140 is used for.  Oh, and I don't
+ * understand why there's a large chunk of CALL_DUMMY that never gets
+ * executed (its function is superceeded by PUSH_DUMMY_FRAME; they
+ * are designed to do the same thing).
+ *
+ *   PUSH_DUMMY_FRAME saves the registers above sp' and pushes the
+ * register file stack down one.
+ *
+ *   call_function then writes CALL_DUMMY, pushes the args onto the
+ * stack, and adjusts the stack pointer.
+ *
+ *   run_stack_dummy then starts execution (in the middle of
+ * CALL_DUMMY, as directed by call_function).
+ */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME       sparc_push_dummy_frame ()
+#define POP_FRAME      sparc_pop_frame ()
+
+void sparc_push_dummy_frame (), sparc_pop_frame ();
+/* This sequence of words is the instructions
+
+   save %sp,-0x140,%sp
+   std %f30,[%fp-0x08]
+   std %f28,[%fp-0x10]
+   std %f26,[%fp-0x18]
+   std %f24,[%fp-0x20]
+   std %f22,[%fp-0x28]
+   std %f20,[%fp-0x30]
+   std %f18,[%fp-0x38]
+   std %f16,[%fp-0x40]
+   std %f14,[%fp-0x48]
+   std %f12,[%fp-0x50]
+   std %f10,[%fp-0x58]
+   std %f8,[%fp-0x60]
+   std %f6,[%fp-0x68]
+   std %f4,[%fp-0x70]
+   std %f2,[%fp-0x78]
+   std %f0,[%fp-0x80]
+   std %g6,[%fp-0x88]
+   std %g4,[%fp-0x90]
+   std %g2,[%fp-0x98]
+   std %g0,[%fp-0xa0]
+   std %i6,[%fp-0xa8]
+   std %i4,[%fp-0xb0]
+   std %i2,[%fp-0xb8]
+   std %i0,[%fp-0xc0]
+   nop ! stcsr [%fp-0xc4]
+   nop ! stfsr [%fp-0xc8]
+   nop ! wr    %npc,[%fp-0xcc]
+   nop ! wr    %pc,[%fp-0xd0]
+   rd  %tbr,%o0
+   st  %o0,[%fp-0xd4]
+   rd  %wim,%o1
+   st  %o0,[%fp-0xd8]
+   rd  %psr,%o0
+   st  %o0,[%fp-0xdc]
+   rd  %y,%o0
+   st  %o0,[%fp-0xe0]
+
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of
+       the following ld instruction.  *../
+
+   ld  [%sp+0x58],%o5
+   ld  [%sp+0x54],%o4
+   ld  [%sp+0x50],%o3
+   ld  [%sp+0x4c],%o2
+   ld  [%sp+0x48],%o1
+   call 0x00000000
+   ld  [%sp+0x44],%o0
+   nop
+   ta 1
+   nop
+
+   note that this is 192 bytes, which is a multiple of 8 (not only 4) bytes.
+   note that the `call' insn is a relative, not an absolute call.
+   note that the `nop' at the end is needed to keep the trap from
+        clobbering things (if NPC pointed to garbage instead).
+
+We actually start executing at the `sethi', since the pushing of the
+registers (as arguments) is done by PUSH_DUMMY_FRAME.  If this were
+real code, the arguments for the function called by the CALL would be
+pushed between the list of ST insns and the CALL, and we could allow
+it to execute through.  But the arguments have to be pushed by GDB
+after the PUSH_DUMMY_FRAME is done, and we cannot allow these ST
+insns to be performed again, lest the registers saved be taken for
+arguments.  */
+
+#define CALL_DUMMY { 0x9de3bee0, 0xfd3fbff8, 0xf93fbff0, 0xf53fbfe8,   \
+                    0xf13fbfe0, 0xed3fbfd8, 0xe93fbfd0, 0xe53fbfc8,    \
+                    0xe13fbfc0, 0xdd3fbfb8, 0xd93fbfb0, 0xd53fbfa8,    \
+                    0xd13fbfa0, 0xcd3fbf98, 0xc93fbf90, 0xc53fbf88,    \
+                    0xc13fbf80, 0xcc3fbf78, 0xc83fbf70, 0xc43fbf68,    \
+                    0xc03fbf60, 0xfc3fbf58, 0xf83fbf50, 0xf43fbf48,    \
+                    0xf03fbf40, 0x01000000, 0x01000000, 0x01000000,    \
+                    0x01000000, 0x91580000, 0xd027bf50, 0x93500000,    \
+                    0xd027bf4c, 0x91480000, 0xd027bf48, 0x91400000,    \
+                    0xd027bf44, 0xda03a058, 0xd803a054, 0xd603a050,    \
+                    0xd403a04c, 0xd203a048, 0x40000000, 0xd003a044,    \
+                    0x01000000, 0x91d02001, 0x01000000, 0x01000000}
+
+#define CALL_DUMMY_LENGTH 192
+
+#define CALL_DUMMY_START_OFFSET 148
+
+#define CALL_DUMMY_STACK_ADJUST 68
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.
+
+   For structs and unions, if the function was compiled with Sun cc,
+   it expects 'unimp' after the call.  But gcc doesn't use that
+   (twisted) convention.  So leave a nop there for gcc (FIX_CALL_DUMMY
+   can assume it is operating on a pristine CALL_DUMMY, not one that
+   has already been customized for a different function).  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{                                                                      \
+  *(int *)((char *) dummyname+168) = (0x40000000|((fun-(pc+168))>>2)); \
+  if (!gcc_p                                                            \
+      && (TYPE_CODE (type) == TYPE_CODE_STRUCT                         \
+         || TYPE_CODE (type) == TYPE_CODE_UNION))                      \
+    *(int *)((char *) dummyname+176) = (TYPE_LENGTH (type) & 0x1fff);  \
+}
+
+\f
+/* Sparc has no reliable single step ptrace call */
+
+#define NO_SINGLE_STEP 1
+extern void single_step ();
+
+/* We need two arguments (in general) to the "info frame" command.
+   Note that the definition of this macro implies that there exists a
+   function "setup_arbitrary_frame" in mach-dep.c */
+
+#define FRAME_SPECIFICATION_DYADIC
+
+/* To print every pair of float registers as a double, we use this hook.  */
+
+#define        PRINT_REGISTER_HOOK(regno)      \
+  if (((regno) >= FP0_REGNUM)          \
+   && ((regno) <  FP0_REGNUM + 32)     \
+   && (0 == (regno & 1))) {            \
+    char doublereg[8];         /* two float regs */    \
+    if (!read_relative_register_raw_bytes (i  , doublereg  )   \
+     && !read_relative_register_raw_bytes (i+1, doublereg+4)) {        \
+      printf("\t");                    \
+      print_floating (doublereg, builtin_type_double, stdout); \
+    }                                  \
+  }
+
diff --git a/gdb/tm-sun2.h b/gdb/tm-sun2.h
new file mode 100644 (file)
index 0000000..6d29462
--- /dev/null
@@ -0,0 +1,107 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "m-68k.h"
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Address of the end of stack space.  We get this from the system
+   include files. */
+#include <sys/types.h>
+#include <machine/vmparam.h>
+#define STACK_END_ADDR USRSTACK
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+  register int regnum;                             \
+  sp = push_word (sp, read_register (PC_REGNUM));   \
+  sp = push_word (sp, read_register (FP_REGNUM));   \
+  write_register (FP_REGNUM, sp);                  \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)  \
+    sp = push_word (sp, read_register (regnum));    \
+  sp = push_word (sp, read_register (PS_REGNUM));   \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                                \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                      \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     bpt
+     nop
+Note this is 24 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 24
+
+#define CALL_DUMMY_START_OFFSET 8
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 16) = nargs * 4;  \
+  *(int *)((char *) dummyname + 10) = fun; }
diff --git a/gdb/tm-sun2os4.h b/gdb/tm-sun2os4.h
new file mode 100644 (file)
index 0000000..bb1a061
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 1990, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "tm-sun2.h"
+#include "tm-sunos.h"
diff --git a/gdb/tm-sun3.h b/gdb/tm-sun3.h
new file mode 100644 (file)
index 0000000..4519d6a
--- /dev/null
@@ -0,0 +1,120 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HAVE_68881
+
+#include "tm-68k.h"
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Address of the end of stack space.  We get this from the system
+   include files. */
+#include <sys/types.h>
+#include <machine/vmparam.h>
+#define STACK_END_ADDR USRSTACK
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
+  register int regnum;                                                 \
+  char raw_buffer[12];                                                 \
+  sp = push_word (sp, read_register (PC_REGNUM));                      \
+  sp = push_word (sp, read_register (FP_REGNUM));                      \
+  write_register (FP_REGNUM, sp);                                      \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
+      sp = push_bytes (sp, raw_buffer, 12); }                          \
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    sp = push_word (sp, read_register (regnum));                       \
+  sp = push_word (sp, read_register (PS_REGNUM));                      \
+  write_register (SP_REGNUM, sp);  }
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                         \
+  register CORE_ADDR fp;                                               \
+  register int regnum;                                                 \
+  struct frame_saved_regs fsr;                                         \
+  struct frame_info *fi;                                               \
+  char raw_buffer[12];                                                 \
+  fi = get_frame_info (frame);                                         \
+  fp = fi->frame;                                                      \
+  get_frame_saved_regs (fi, &fsr);                                     \
+  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
+    if (fsr.regs[regnum])                                              \
+      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
+        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
+  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
+    if (fsr.regs[regnum])                                              \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  if (fsr.regs[PS_REGNUM])                                             \
+    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
+  write_register (SP_REGNUM, fp + 8);                                  \
+  flush_cached_frames ();                                              \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     fmovem 0xff,-(sp)
+     moveml 0xfffc,-(sp)
+     clrw -(sp)
+     movew ccr,-(sp)
+     /..* The arguments are pushed at this point by GDB;
+       no code is needed in the dummy for this.
+       The CALL_DUMMY_START_OFFSET gives the position of 
+       the following jsr instruction.  *../
+     jsr @#32323232
+     addl #69696969,sp
+     trap #15
+     nop
+Note this is 28 bytes.
+We actually start executing at the jsr, since the pushing of the
+registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+the arguments for the function called by the jsr would be pushed
+between the moveml and the jsr, and we could allow it to execute through.
+But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
+and we cannot allow the moveml to push the registers again lest they be
+taken for the arguments.  */
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
+
+#define CALL_DUMMY_LENGTH 28
+
+#define CALL_DUMMY_START_OFFSET 12
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
+{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
+  *(int *)((char *) dummyname + 14) = fun; }
diff --git a/gdb/tm-sun386.h b/gdb/tm-sun386.h
new file mode 100644 (file)
index 0000000..60c8986
--- /dev/null
@@ -0,0 +1,305 @@
+/* Parameters for execution on a Sun 386i, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+#ifndef sun386
+#define sun386
+#endif
+#define SUNOS4
+#define USE_MACHINE_REG_H
+
+/* Perhaps some day this will work even without the following #define */
+#define COFF_ENCAPSULATE
+
+#ifdef COFF_ENCAPSULATE
+#define NAMES_HAVE_UNDERSCORE
+/* Avoid conflicts between "a.out.gnu.h" and <sys/exec.h> */
+#define _EXEC_
+#endif
+
+#define BROKEN_LARGE_ALLOCA
+
+/* sun386 ptrace seems unable to change the frame pointer */
+#define PTRACE_FP_BUG
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(frompc)   {(frompc) = i386_skip_prologue((frompc));}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+  (read_memory_integer (read_register (SP_REGNUM), 4))
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0xfc000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xcc}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 1
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the 386.  */
+
+#define INVALID_FLOAT(p, len) (0)
+
+/* Largest integer type */
+#define LONGEST long
+
+/* Name of the builtin type for the LONGEST type above. */
+#define BUILTIN_TYPE_LONGEST builtin_type_long
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 35
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+/* the order of the first 8 registers must match the compiler's
+ * numbering scheme (which is the same as the 386 scheme)
+ * also, this table must match regmap in i386-pinsn.c.
+ */
+#define REGISTER_NAMES { "gs", "fs", "es", "ds",               \
+                        "edi", "esi", "ebp", "esp",            \
+                        "ebx", "edx", "ecx", "eax",            \
+                        "retaddr", "trapnum", "errcode", "ip", \
+                        "cs", "ps", "sp", "ss",                \
+                        "fst0", "fst1", "fst2", "fst3",        \
+                        "fst4", "fst5", "fst6", "fst7",        \
+                        "fctrl", "fstat", "ftag", "fip",       \
+                        "fcs", "fopoff", "fopsel"              \
+                        }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define FP_REGNUM 6            /* Contains address of executing stack frame */
+#define SP_REGNUM 18           /* Contains address of top of stack */
+#define PS_REGNUM 17           /* Contains processor status */
+#define PC_REGNUM 15           /* Contains program counter */
+#define FP0_REGNUM 20          /* Floating point register 0 */
+#define FPC_REGNUM 28          /* 80387 control register */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (20*4+8*10+7*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) \
+ ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 160   \
+  : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 10) + 80 \
+  : (N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+#define REGISTER_RAW_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 10 : 4)
+
+/* Number of bytes of storage in the program's representation
+   for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 8 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (((unsigned)((N) - FP0_REGNUM)) < 8)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
+    i387_to_double ((FROM), (TO));                     \
+  else                                                 \
+    bcopy ((FROM), (TO), 4); }
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
+    double_to_i387 ((FROM), (TO));     \
+  else                                 \
+    bcopy ((FROM), (TO), 4); }
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((unsigned)((N) - FP0_REGNUM)) < 8 ? builtin_type_double : builtin_type_int)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { (SP) -= sizeof (ADDR);             \
+    write_memory ((SP), &(ADDR), sizeof (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF + REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+#define FRAME_CHAIN(thisframe) \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+{ (FRAMELESS) = frameless_look_for_prologue (FI); }
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi) (numargs) = i386_frame_num_args(fi)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  { i386_pop_frame (); }
+
+/* this is 
+ *   call 11223344 (32 bit relative)
+ *   int3
+ */
+
+#define CALL_DUMMY { 0x223344e8, 0xcc11 }
+
+#define CALL_DUMMY_LENGTH 8
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ \
+       *(int *)((char *)(dummyname) + 1) = (int)(fun) - (pc) - 5; \
+}
diff --git a/gdb/tm-sun3os4.h b/gdb/tm-sun3os4.h
new file mode 100644 (file)
index 0000000..5d89d15
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 1990, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "tm-sun3.h"
+#include "tm-sunos.h"
diff --git a/gdb/tm-sun4os4.h b/gdb/tm-sun4os4.h
new file mode 100644 (file)
index 0000000..971bb4f
--- /dev/null
@@ -0,0 +1,24 @@
+/* Macro definitions for GDB for a Sun 4 running sunos 4.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "tm-sparc.h"
+#include "tm-sunos.h"
+
+#undef STACK_END_ADDRESS
+#define STACK_END_ADDRESS 0xf8000000
diff --git a/gdb/tm-sunos.h b/gdb/tm-sunos.h
new file mode 100644 (file)
index 0000000..f33e352
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is for SunOS version 4, not for earlier versions.  */
+
+#define CLEAR_SOLIB clear_solib
+
+/* If we can't set a breakpoint, and it's in a shared library, just
+   disable it.  */
+#define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr)
+extern int solib_address ();                   /* solib.c */
diff --git a/gdb/tm-symmetry.h b/gdb/tm-symmetry.h
new file mode 100644 (file)
index 0000000..0030b61
--- /dev/null
@@ -0,0 +1,488 @@
+/* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0,
+   with Weitek 1167 and i387 support.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Symmetry version by Jay Vosburgh (uunet!sequent!fubar) */
+
+/* I don't know if this will work for cross-debugging, even if you do get
+   a copy of the right include file.  */
+#include <machine/reg.h>
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  From m-i386.h */
+
+#define SKIP_PROLOGUE(frompc)   {(frompc) = i386_skip_prologue((frompc));}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+  read_memory_integer(read_register(SP_REGNUM), 4)
+
+/* I don't know the real values for these.  */
+#define TARGET_UPAGES UPAGES
+#define TARGET_NBPG NBPG
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0x40000000 - (TARGET_UPAGES * TARGET_NBPG))
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xcc}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+/* For Symmetry, this is really the 'leave' instruction, which */
+/* is right before the ret */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc9)
+
+/* Return 1 if P points to an invalid floating point value.
+*/
+
+#define INVALID_FLOAT(p, len) (0)
+
+/* code for 80387 fpu.  Functions are from i386-dep.c, copied into
+ * symm-dep.c.
+ */
+#define FLOAT_INFO { i386_float_info(); }
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+#define NUM_REGS 49
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+/* Symmetry registers are in this weird order to match the register
+   numbers in the symbol table entries.  If you change the order,
+   things will probably break mysteriously for no apparent reason.
+   Also note that the st(0)...st(7) 387 registers are represented as
+   st0...st7.  */
+
+#define REGISTER_NAMES { "eax", "edx", "ecx", "st0", "st1", \
+                            "ebx", "esi", "edi", "st2", "st3", \
+                            "st4", "st5", "st6", "st7", "esp", \
+                            "ebp", "eip", "eflags", "fp1", "fp2", \
+                            "fp3", "fp4", "fp5", "fp6", "fp7", \
+                            "fp8", "fp9", "fp10", "fp11", "fp12", \
+                            "fp13", "fp14", "fp15", "fp16", "fp17", \
+                            "fp18", "fp19", "fp20", "fp21", "fp22", \
+                            "fp23", "fp24", "fp25", "fp26", "fp27", \
+                            "fp28", "fp29", "fp30", "fp31" }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define FP1_REGNUM 18          /* first 1167 register */
+#define SP_REGNUM 14           /* Contains address of top of stack */
+#define FP_REGNUM 15           /* Contains address of executing stack frame */
+#define PC_REGNUM 16           /* Contains program counter */
+#define PS_REGNUM 17           /* Contains processor status */
+
+/* The magic numbers below are offsets into u_ar0 in the user struct.
+ * They live in <machine/reg.h>.  Gdb calls this macro with blockend
+ * holding u.u_ar0 - KERNEL_U_ADDR.  Only the registers listed are
+ * saved in the u area (along with a few others that aren't useful
+ * here.  See <machine/reg.h>).
+ */
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ struct user foo;     /* needed for finding fpu regs */ \
+switch (regno) { \
+    case 0: \
+      addr = blockend + EAX * sizeof(int); break; \
+  case 1: \
+      addr = blockend + EDX * sizeof(int); break; \
+  case 2: \
+      addr = blockend + ECX * sizeof(int); break; \
+  case 3:                      /* st(0) */ \
+      addr = blockend - \
+         ((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \
+      break; \
+  case 4:                      /* st(1) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \
+      break; \
+  case 5: \
+      addr = blockend + EBX * sizeof(int); break; \
+  case 6: \
+      addr = blockend + ESI * sizeof(int); break; \
+  case 7: \
+      addr = blockend + EDI * sizeof(int); break; \
+  case 8:                      /* st(2) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \
+      break; \
+  case 9:                      /* st(3) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \
+      break; \
+  case 10:                     /* st(4) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \
+      break; \
+  case 11:                     /* st(5) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \
+      break; \
+  case 12:                     /* st(6) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \
+      break; \
+  case 13:                     /* st(7) */ \
+      addr = blockend - \
+         ((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \
+      break; \
+  case 14: \
+      addr = blockend + ESP * sizeof(int); break; \
+  case 15: \
+      addr = blockend + EBP * sizeof(int); break; \
+  case 16: \
+      addr = blockend + EIP * sizeof(int); break; \
+  case 17: \
+      addr = blockend + FLAGS * sizeof(int); break; \
+  case 18:                     /* fp1 */ \
+  case 19:                     /* fp2 */ \
+  case 20:                     /* fp3 */ \
+  case 21:                     /* fp4 */ \
+  case 22:                     /* fp5 */ \
+  case 23:                     /* fp6 */ \
+  case 24:                     /* fp7 */ \
+  case 25:                     /* fp8 */ \
+  case 26:                     /* fp9 */ \
+  case 27:                     /* fp10 */ \
+  case 28:                     /* fp11 */ \
+  case 29:                     /* fp12 */ \
+  case 30:                     /* fp13 */ \
+  case 31:                     /* fp14 */ \
+  case 32:                     /* fp15 */ \
+  case 33:                     /* fp16 */ \
+  case 34:                     /* fp17 */ \
+  case 35:                     /* fp18 */ \
+  case 36:                     /* fp19 */ \
+  case 37:                     /* fp20 */ \
+  case 38:                     /* fp21 */ \
+  case 39:                     /* fp22 */ \
+  case 40:                     /* fp23 */ \
+  case 41:                     /* fp24 */ \
+  case 42:                     /* fp25 */ \
+  case 43:                     /* fp26 */ \
+  case 44:                     /* fp27 */ \
+  case 45:                     /* fp28 */ \
+  case 46:                     /* fp29 */ \
+  case 47:                     /* fp30 */ \
+  case 48:                     /* fp31 */ \
+     addr = blockend - \
+        ((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \
+  } \
+}
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+/* 10 i386 registers, 8 i387 registers, and 31 Weitek 1167 registers */
+#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4))
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N)               \
+((N < 3) ? (N * 4) :                   \
+(N < 5) ? (((N - 2) * 10) + 2) :       \
+(N < 8) ? (((N - 5) * 4) + 32) :       \
+(N < 14) ? (((N - 8) * 10) + 44) :     \
+    (((N - 14) * 4) + 104))
+
+/* Number of bytes of storage in the actual machine representation
+ * for register N.  All registers are 4 bytes, except 387 st(0) - st(7),
+ * which are 80 bits each. 
+ */
+
+#define REGISTER_RAW_SIZE(N) \
+((N < 3) ? 4 : \
+(N < 5) ? 10 : \
+(N < 8) ? 4 :  \
+(N < 14) ? 10 :        \
+    4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the vax, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 10
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) \
+((N < 3) ? 0 : \
+(N < 5) ? 1  : \
+(N < 8) ? 0  : \
+(N < 14) ? 1 : \
+    0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+((REGNUM < 3) ? bcopy ((FROM), (TO), 4) : \
+(REGNUM < 5) ? i387_to_double((FROM), (TO)) : \
+(REGNUM < 8) ? bcopy ((FROM), (TO), 4) : \
+(REGNUM < 14) ? i387_to_double((FROM), (TO)) : \
+    bcopy ((FROM), (TO), 4))
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+((REGNUM < 3) ? bcopy ((FROM), (TO), 4) : \
+(REGNUM < 5) ? double_to_i387((FROM), (TO)) : \
+(REGNUM < 8) ? bcopy ((FROM), (TO), 4) : \
+(REGNUM < 14) ? double_to_i387((FROM), (TO)) : \
+    bcopy ((FROM), (TO), 4))
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+((N < 3) ? builtin_type_int : \
+(N < 5) ? builtin_type_double : \
+(N < 8) ? builtin_type_int : \
+(N < 14) ? builtin_type_double : \
+    builtin_type_int)
+
+/* from m-i386.h */
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { (SP) -= sizeof (ADDR);             \
+    write_memory ((SP), &(ADDR), sizeof (ADDR)); \
+    write_register(0, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  symmetry_extract_return_value(TYPE, REGBUF, VALBUF)
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* On Symmetry, %ebp points to caller's %ebp, and the return address
+   is right on top of that.
+*/
+
+#define FRAME_CHAIN(thisframe)  \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0)
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+#define FRAME_SAVED_PC(fi) (read_memory_integer((fi)->frame + 4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.
+  
+   The weirdness in the "addl $imm8" case is due to gcc sometimes
+   issuing "addl $-int" after function call returns; this would
+   produce ridiculously huge arg counts.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)  \
+{ \
+  int op = read_memory_integer(FRAME_SAVED_PC((fi)), 4); \
+  int narg; \
+  if ((op & 0xff) == 0x59) /* 0x59  'popl %ecx' */ \
+    { \
+      numargs = 1; \
+    } \
+  else if ((op & 0xffff) == 0xc483) /* 0xc483 'addl $imm8' */ \
+    { \
+      narg = ((op >> 16) & 0xff); \
+      numargs = (narg >= 128) ? -1 : narg / 4; \
+    } \
+  else if ((op & 0xffff) == 0xc481) /* 0xc481 'addl $imm32' */ \
+    { \
+      narg = read_memory_integer(FRAME_SAVED_PC((fi))+2,4); \
+      numargs = (narg < 0) ? -1 : narg / 4; \
+    } \
+  else \
+    { \
+      numargs = -1; \
+    } \
+}
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+#define PUSH_DUMMY_FRAME \
+{  CORE_ADDR sp = read_register (SP_REGNUM); \
+  int regnum; \
+  sp = push_word (sp, read_register (PC_REGNUM)); \
+  sp = push_word (sp, read_register (FP_REGNUM)); \
+  write_register (FP_REGNUM, sp); \
+  for (regnum = 0; regnum < NUM_REGS; regnum++) \
+    sp = push_word (sp, read_register (regnum)); \
+  write_register (SP_REGNUM, sp); \
+}
+
+#define POP_FRAME  \
+{ \
+  FRAME frame = get_current_frame (); \
+  CORE_ADDR fp; \
+  int regnum; \
+  struct frame_saved_regs fsr; \
+  struct frame_info *fi; \
+  fi = get_frame_info (frame); \
+  fp = fi->frame; \
+  get_frame_saved_regs (fi, &fsr); \
+  for (regnum = 0; regnum < NUM_REGS; regnum++) { \
+      CORE_ADDR adr; \
+      adr = fsr.regs[regnum]; \
+      if (adr) \
+       write_register (regnum, read_memory_integer (adr, 4)); \
+  } \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
+  write_register (SP_REGNUM, fp + 8); \
+  flush_cached_frames (); \
+  set_current_frame ( create_new_frame (read_register (FP_REGNUM), \
+                                       read_pc ())); \
+}
+
+/* from i386-dep.c, worked better than my original... */
+/* This sequence of words is the instructions
+ * call (32-bit offset)
+ * int 3
+ * This is 6 bytes.
+ */
+
+#define CALL_DUMMY { 0x223344e8, 0xcc11 }
+
+#define CALL_DUMMY_LENGTH 8
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ \
+       int from, to, delta, loc; \
+       loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \
+       from = loc + 5; \
+       to = (int)(fun); \
+       delta = to - from; \
+       *(int *)((char *)(dummyname) + 1) = delta; \
+}
diff --git a/gdb/tm-umax.h b/gdb/tm-umax.h
new file mode 100644 (file)
index 0000000..4929065
--- /dev/null
@@ -0,0 +1,405 @@
+/* Definitions to make GDB run on an encore under umax 4.2
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Exec files and symbol tables are in COFF format */
+
+#define COFF_FORMAT
+
+/* Need to get function ends by adding this to epilogue address from .bf
+   record, not using x_fsize field.  */
+#define FUNCTION_EPILOGUE_SIZE 4
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)                              \
+{ register unsigned char op = read_memory_integer (pc, 1);     \
+  if (op == 0x82) { op = read_memory_integer (pc+2,1);  \
+                   if ((op & 0x80) == 0) pc += 3;      \
+                   else if ((op & 0xc0) == 0x80) pc += 4;      \
+                   else pc += 6;                       \
+                  }                                    \
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+       read_memory_integer (read_register (SP_REGNUM), 4)
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR (0xfffff000)
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xf2}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12)
+
+#ifndef NaN
+#include <nan.h>
+#endif NaN
+
+/* Return 1 if P points to an invalid floating point value.  */
+/* Surely wrong for cross-debugging.  */
+#define INVALID_FLOAT(p, s) \
+        ((s == sizeof (float))?        \
+               NaF (*(float *) p) :    \
+               NaD (*(double *) p))
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS               25
+
+#define NUM_GENERAL_REGS       8
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",        \
+                       "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+                       "sp", "fp", "pc", "ps",                         \
+                       "fsr",                                          \
+                       "l0", "l1", "l2", "l3", "xx",                   \
+                       }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define FP0_REGNUM 8           /* Floating point register 0 */
+#define SP_REGNUM 16           /* Contains address of top of stack */
+#define AP_REGNUM FP_REGNUM
+#define FP_REGNUM 17           /* Contains address of executing stack frame */
+#define PC_REGNUM 18           /* Contains program counter */
+#define PS_REGNUM 19           /* Contains processor status */
+#define FPS_REGNUM 20          /* Floating point status register */
+#define LP0_REGNUM 21          /* Double register 0 (same as FP0) */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double))
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \
+       LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the 32000, all regs are 4 bytes
+   except for the doubled floating registers. */
+
+#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the 32000, all regs are 4 bytes
+   except for the doubled floating registers. */
+
+#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+       (((N) < FP0_REGNUM) ?                           \
+               builtin_type_int :                      \
+               ((N) < FP0_REGNUM + 8) ?                \
+                       builtin_type_float :            \
+                       ((N) < LP0_REGNUM) ?            \
+                               builtin_type_int :      \
+                               builtin_type_double)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function.
+
+   On this machine this is a no-op, because gcc isn't used on it
+   yet.  So this calling convention is not used. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP)
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF+REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the ns32000 series, the frame's nominal address is the FP
+   value, and at that address is saved previous FP value as a 4-byte word.  */
+
+#define FRAME_CHAIN(thisframe)  \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+/* Compute base of arguments. */
+
+#define FRAME_ARGS_ADDRESS(fi) \
+  ((ns32k_get_enter_addr ((fi)->pc) > 1) ? \
+       ((fi)->frame) : (read_register (SP_REGNUM) - 4))
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Get the address of the enter opcode for this function, if it is active.
+   Returns positive address > 1 if pc is between enter/exit,
+   1 if pc before enter or after exit, 0 otherwise. */
+
+#ifndef CORE_ADDR
+#include "defs.h"   /* Make sure CORE_ADDR is defined.  */
+#endif
+
+extern CORE_ADDR ns32k_get_enter_addr ();
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.
+   Encore's C compiler often reuses same area on stack for args,
+   so this will often not work properly.  If the arg names
+   are known, it's likely most of them will be printed. */
+
+#define FRAME_NUM_ARGS(numargs, fi)                    \
+{ CORE_ADDR    pc;                                     \
+  CORE_ADDR    enter_addr;                             \
+  unsigned int insn;                                   \
+  unsigned int addr_mode;                              \
+  int width;                                           \
+                                                       \
+  numargs = -1;                                                \
+  enter_addr = ns32k_get_enter_addr ((fi)->pc);                \
+  if (enter_addr > 0)                                  \
+    {                                                  \
+      pc = (enter_addr == 1) ?                         \
+       SAVED_PC_AFTER_CALL (fi) :                      \
+       FRAME_SAVED_PC (fi);                            \
+      insn = read_memory_integer (pc,2);               \
+      addr_mode = (insn >> 11) & 0x1f;                 \
+      insn = insn & 0x7ff;                             \
+      if ((insn & 0x7fc) == 0x57c &&                   \
+               addr_mode == 0x14) /* immediate */      \
+       {                                               \
+         if (insn == 0x57c) /* adjspb */               \
+               width = 1;                              \
+         else if (insn == 0x57d) /* adjspw */          \
+               width = 2;                              \
+         else if (insn == 0x57f) /* adjspd */          \
+               width = 4;                              \
+         numargs = read_memory_integer (pc+2,width);   \
+         if (width > 1)                                \
+           flip_bytes (&numargs, width);               \
+         numargs = - sign_extend (numargs, width*8) / 4;\
+       }                                               \
+    }                                                  \
+}
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)    \
+{                                                              \
+  register int regmask, regnum;                                \
+  int          localcount;                                     \
+  register CORE_ADDR   enter_addr;                             \
+  register CORE_ADDR   next_addr;                              \
+                                                               \
+  bzero (&(frame_saved_regs), sizeof (frame_saved_regs));      \
+  enter_addr = ns32k_get_enter_addr ((frame_info)->pc);                \
+  if (enter_addr > 1)                                          \
+    {                                                          \
+      regmask = read_memory_integer (enter_addr+1, 1) & 0xff;  \
+      localcount = ns32k_localcount (enter_addr);              \
+      next_addr = (frame_info)->frame + localcount;            \
+      for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)    \
+       (frame_saved_regs).regs[regnum] = (regmask & 1) ?       \
+                                         (next_addr -= 4) : 0; \
+      (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 4;\
+      (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;\
+      (frame_saved_regs).regs[FP_REGNUM] =                     \
+                 (read_memory_integer ((frame_info)->frame, 4));\
+    }                                                          \
+  else if (enter_addr == 1)                                    \
+    {                                                          \
+      CORE_ADDR sp = read_register (SP_REGNUM);                        \
+      (frame_saved_regs).regs[PC_REGNUM] = sp;                 \
+      (frame_saved_regs).regs[SP_REGNUM] = sp + 4;             \
+    }                                                          \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+  register int regnum;                             \
+  sp = push_word (sp, read_register (PC_REGNUM));   \
+  sp = push_word (sp, read_register (FP_REGNUM));   \
+  write_register (FP_REGNUM, sp);                  \
+  for (regnum = 0; regnum < 8; regnum++)  \
+    sp = push_word (sp, read_register (regnum));    \
+  write_register (SP_REGNUM, sp);                      \
+}
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register FRAME frame = get_current_frame ();                  \
+  register CORE_ADDR fp;                                        \
+  register int regnum;                                          \
+  struct frame_saved_regs fsr;                                  \
+  struct frame_info *fi;                                                \
+  fi = get_frame_info (frame);                                  \
+  fp = fi->frame;                                               \
+  get_frame_saved_regs (fi, &fsr);                              \
+  for (regnum = 0; regnum < 8; regnum++)                        \
+    if (fsr.regs[regnum])                                       \
+      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
+  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
+  write_register (SP_REGNUM, fp + 8);                           \
+  flush_cached_frames ();                                       \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
+                                      read_pc ())); }
+
+/* This sequence of words is the instructions
+     enter     0xff,0          82 ff 00
+     jsr       @0x00010203     7f ae c0 01 02 03
+     adjspd    0x69696969      7f a5 01 02 03 04
+     bpt                       f2
+   Note this is 16 bytes.  */
+
+#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 }
+
+#define CALL_DUMMY_START_OFFSET        3
+#define CALL_DUMMY_LENGTH      16
+#define CALL_DUMMY_ADDR                5
+#define CALL_DUMMY_NARGS       11
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)                   \
+{                                                              \
+       int     flipped;                                        \
+       flipped = fun | 0xc0000000;                             \
+       flip_bytes (&flipped, 4);                               \
+       *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped;    \
+       flipped = - nargs * 4;                                  \
+       flip_bytes (&flipped, 4);                               \
+       *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped;   \
+}
diff --git a/gdb/tm-vax.h b/gdb/tm-vax.h
new file mode 100644 (file)
index 0000000..c7a91b4
--- /dev/null
@@ -0,0 +1,377 @@
+/* Definitions to make GDB run on a vax under 4.2bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* There is one known bug with VAX support that I don't know how to
+   fix:  if you do a backtrace from a signal handler, you get something
+   like:
+#0  0xbc in kill (592, 3)
+#1  0x7f in hand (...) (...)
+#2  0x7fffec7e in ?? (2, 0, 2147478112, 94)
+                  ^^ GDB doesn't know about sigtramp
+#3  0x7fffec70 in ?? (592, 2)
+    ^^^^^^^^^^ wrong address
+#4  0xae in main (...) (...)
+
+when the correct backtrace (as given by adb) is:
+_kill(250,3) from _hand+21
+_hand(2,0,7fffea60,5e) from 7fffec7e
+sigtramp(2,0,7fffea60,5e) from _kill+4
+_kill(250,2) from _main+2e
+_main(1,7fffeac4,7fffeacc) from start+3d
+
+If anyone knows enough about VAX BSD to fix this, please send the
+fix to bug-gdb@prep.ai.mit.edu.  */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* Debugger information will be in DBX format.  */
+
+#define READ_DBX_FORMAT
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 2
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)      \
+{ register int op = (unsigned char) read_memory_integer (pc, 1);  \
+  if (op == 0x11) pc += 2;  /* skip brb */                       \
+  if (op == 0x31) pc += 3;  /* skip brw */                       \
+  if (op == 0xC2 &&                                              \
+      ((unsigned char) read_memory_integer (pc+2, 1)) == 0x5E)   \
+    pc += 3;  /* skip subl2 */                                   \
+  if (op == 0x9E &&                                              \
+      ((unsigned char) read_memory_integer (pc+1, 1)) == 0xAE &&  \
+      ((unsigned char) read_memory_integer(pc+3, 1)) == 0x5E)    \
+     pc += 4;  /* skip movab */                                          \
+  if (op == 0x9E &&                                              \
+      ((unsigned char) read_memory_integer (pc+1, 1)) == 0xCE &&  \
+      ((unsigned char) read_memory_integer(pc+4, 1)) == 0x5E)    \
+    pc += 5;  /* skip movab */                                   \
+  if (op == 0x9E &&                                              \
+      ((unsigned char) read_memory_integer (pc+1, 1)) == 0xEE &&  \
+      ((unsigned char) read_memory_integer(pc+6, 1)) == 0x5E)    \
+    pc += 7;  /* skip movab */                                   \
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) FRAME_SAVED_PC(frame)
+
+#define TARGET_UPAGES 10
+#define TARGET_NBPG 512
+#define STACK_END_ADDR (0x80000000 - (TARGET_UPAGES * TARGET_NBPG))
+
+/* On the VAX, sigtramp is in the u area.  Can't check the exact
+   addresses because for cross-debugging we don't have VAX include
+   files around.  This should be close enough.  */
+#define IN_SIGTRAMP(pc, name) ((pc) >= STACK_END_ADDR && (pc < 0x80000000))
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {3}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 0
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 04)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the Vax.  */
+
+#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 17
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", "ps"}
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define AP_REGNUM 12
+#define FP_REGNUM 13           /* Contains address of executing stack frame */
+#define SP_REGNUM 14           /* Contains address of top of stack */
+#define PC_REGNUM 15           /* Contains program counter */
+#define PS_REGNUM 16           /* Contains processor status */
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (17*4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) * 4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On the vax, all regs are 4 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) 4
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the vax, all regs are 4 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 4
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  bcopy ((FROM), (TO), 4);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  bcopy ((FROM), (TO), 4);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) builtin_type_int
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { write_register (1, (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer.
+
+   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+   and produces the nominal address of the caller frame.
+
+   However, if FRAME_CHAIN_VALID returns zero,
+   it means the given frame is the outermost one and has no caller.
+   In that case, FRAME_CHAIN_COMBINE is not used.  */
+
+/* In the case of the Vax, the frame's nominal address is the FP value,
+   and 12 bytes later comes the saved previous FP value as a 4-byte word.  */
+
+#define FRAME_CHAIN(thisframe)  \
+  (outside_startup_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame + 12, 4) :\
+   0)
+
+#define FRAME_CHAIN_VALID(chain, thisframe) \
+  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
+
+#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+/* On the vax, all functions have frames.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS)  {(FRAMELESS) = 0;}
+
+/* Saved Pc.  */
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 16, 4))
+
+/* Cannot find the AP register value directly from the FP value.  Must
+   find it saved in the frame called by this one, or in the AP
+   register for the innermost frame.  However, there is no way to tell
+   the difference between the innermost frame and a frame for which we
+   just don't know the frame that it called (e.g. "info frame
+   0x7ffec789").  For the sake of argument suppose that the stack is
+   somewhat trashed (which is one reason that "info frame" exists).
+   So return 0 (indicating we don't know the address of
+   the arglist) if we don't know what frame this frame calls.  */
+#define FRAME_ARGS_ADDRESS_CORRECT(fi) \
+ (((fi)->next_frame                                  \
+   ? read_memory_integer ((fi)->next_frame + 8, 4)   \
+   : /* read_register (AP_REGNUM) */ 0))
+
+/* In most of GDB, getting the args address is too important to
+   just say "I don't know".  This is sometimes wrong for functions
+   that aren't on top of the stack, but c'est la vie.  */
+#define FRAME_ARGS_ADDRESS(fi) \
+ (((fi)->next_frame                                  \
+   ? read_memory_integer ((fi)->next_frame + 8, 4)   \
+   : read_register (AP_REGNUM) /* 0 */))
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi)  \
+{ numargs = (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1)); }
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 4
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ register int regnum;     \
+  register int regmask = read_memory_integer ((frame_info)->frame+4, 4) >> 16; \
+  register CORE_ADDR next_addr;     \
+  bzero (&frame_saved_regs, sizeof frame_saved_regs);     \
+  next_addr = (frame_info)->frame + 16;     \
+  /* Regmask's low bit is for register 0,     \
+     which is the first one that would be pushed.  */     \
+  for (regnum = 0; regnum < 12; regnum++, regmask >>= 1)  \
+    (frame_saved_regs).regs[regnum] = (regmask & 1) ? (next_addr += 4) : 0;  \
+  (frame_saved_regs).regs[SP_REGNUM] = next_addr + 4;  \
+  if (read_memory_integer ((frame_info)->frame + 4, 4) & 0x20000000)   \
+    (frame_saved_regs).regs[SP_REGNUM] += 4 + 4 * read_memory_integer (next_addr + 4, 4);  \
+  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 16;  \
+  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame + 12;  \
+  (frame_saved_regs).regs[AP_REGNUM] = (frame_info)->frame + 8;  \
+  (frame_saved_regs).regs[PS_REGNUM] = (frame_info)->frame + 4;  \
+}
+\f
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME \
+{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+  register int regnum;                             \
+  sp = push_word (sp, 0); /* arglist */                    \
+  for (regnum = 11; regnum >= 0; regnum--)         \
+    sp = push_word (sp, read_register (regnum));    \
+  sp = push_word (sp, read_register (PC_REGNUM));   \
+  sp = push_word (sp, read_register (FP_REGNUM));   \
+  sp = push_word (sp, read_register (AP_REGNUM));   \
+  sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef)   \
+                     + 0x2fff0000);                \
+  sp = push_word (sp, 0);                          \
+  write_register (SP_REGNUM, sp);                  \
+  write_register (FP_REGNUM, sp);                  \
+  write_register (AP_REGNUM, sp + 17 * sizeof (int)); }
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  \
+{ register CORE_ADDR fp = read_register (FP_REGNUM);            \
+  register int regnum;                                          \
+  register int regmask = read_memory_integer (fp + 4, 4);       \
+  write_register (PS_REGNUM,                                    \
+                 (regmask & 0xffff)                             \
+                 | (read_register (PS_REGNUM) & 0xffff0000));   \
+  write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));  \
+  write_register (FP_REGNUM, read_memory_integer (fp + 12, 4));  \
+  write_register (AP_REGNUM, read_memory_integer (fp + 8, 4));   \
+  fp += 16;                                                     \
+  for (regnum = 0; regnum < 12; regnum++)                       \
+    if (regmask & (0x10000 << regnum))                          \
+      write_register (regnum, read_memory_integer (fp += 4, 4)); \
+  fp = fp + 4 + ((regmask >> 30) & 3);                          \
+  if (regmask & 0x20000000)                                     \
+    { regnum = read_memory_integer (fp, 4);                     \
+      fp += (regnum + 1) * 4; }                                         \
+  write_register (SP_REGNUM, fp);                               \
+  flush_cached_frames ();                                       \
+  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
+                                       read_pc ())); }
+
+/* This sequence of words is the instructions
+     calls #69, @#32323232
+     bpt
+   Note this is 8 bytes.  */
+
+#define CALL_DUMMY {0x329f69fb, 0x03323232}
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ *((char *) dummyname + 1) = nargs;           \
+  *(int *)((char *) dummyname + 3) = fun; }
diff --git a/gdb/tm-vxworks68.h b/gdb/tm-vxworks68.h
new file mode 100755 (executable)
index 0000000..a3cd7c2
--- /dev/null
@@ -0,0 +1,48 @@
+/* Parameters for execution on VxWorks 68k's, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define        GDBINIT_FILENAME        ".vxgdbinit"
+
+#define        DEFAULT_PROMPT          "(vxgdb) "
+
+/* Kludge... */
+#include "tm-sun3.h"
+
+/* We have more complex, useful breakpoints on the target.  */
+#undef DECR_PC_AFTER_BREAK
+#define        DECR_PC_AFTER_BREAK     0
+
+/* We are guaranteed to have a zero frame pointer at bottom of stack, too. */
+#undef FRAME_CHAIN
+#undef FRAME_CHAIN_VALID
+
+/* Takes the current frame-struct pointer and returns the chain-pointer
+   to get to the calling frame.
+
+   If our current frame pointer is zero, we're at the top; else read out
+   the saved FP from memory pointed to by the current FP.  */
+
+#define FRAME_CHAIN(thisframe) ((thisframe)->frame? read_memory_integer ((thisframe)->frame, 4): 0)
+
+/* If the chain pointer is zero (either because the saved value fetched
+   by FRAME_CHAIN was zero, or because the current FP was zero so FRAME_CHAIN
+   never fetched anything), we are at the top of the stack.  */
+
+#define FRAME_CHAIN_VALID(chain, thisframe) (chain != 0)
diff --git a/gdb/tm-vxworks960.h b/gdb/tm-vxworks960.h
new file mode 100755 (executable)
index 0000000..fc5c214
--- /dev/null
@@ -0,0 +1,48 @@
+/* Parameters for VxWorks Intel 960's, for GDB, the GNU debugger.
+   Copyright (C) 1986-1991 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "tm-i960.h"
+
+#define        GDBINIT_FILENAME        ".vxgdbinit"
+
+#define        DEFAULT_PROMPT          "(vxgdb) "
+
+/* We have more complex, useful breakpoints on the target.
+   Amount ip must be decremented by after a breakpoint.  */
+
+#define        DECR_PC_AFTER_BREAK     0
+
+/* We are guaranteed to have a zero frame pointer at bottom of stack, too. */
+
+#define FRAME_CHAIN_VALID(chain, thisframe) (chain != 0)
+
+/* Breakpoint patching is handled at the target end in VxWorks.  */
+/* #define BREAKPOINT {0x00, 0x3e, 0x00, 0x66} */
+
+/* Not needed, because we don't support core files:
+       #define KERNEL_U_ADDR
+       #define REGISTER_U_ADDR(addr, blockend, regno)
+ */
+
+/* Address of end of stack space.
+       This doesn't matter for VxWorks, because it's only used
+       in manipulation of core files, which we don't support.  */
+
+/* #define STACK_END_ADDR (0xfe000000) */
diff --git a/gdb/umax-xdep.c b/gdb/umax-xdep.c
new file mode 100644 (file)
index 0000000..f3504da
--- /dev/null
@@ -0,0 +1,139 @@
+/* umax host stuff.
+   Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "defs.h"
+#include "param.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#include "gdbcore.h"
+#include <sys/ptrace.h>
+#define PTRACE_ATTACH PT_ATTACH
+#define PTRACE_DETACH PT_FREEPROC
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+/* Work with core dump and executable files, for GDB. 
+   This code would be in core.c if it weren't machine-dependent. */
+
+void
+core_file_command (filename, from_tty)
+     char *filename;
+     int from_tty;
+{
+  int val;
+  extern char registers[];
+
+  /* Discard all vestiges of any previous core file
+     and mark data and stack spaces as empty.  */
+
+  if (corefile)
+    free (corefile);
+  corefile = 0;
+
+  if (corechan >= 0)
+    close (corechan);
+  corechan = -1;
+
+  data_start = 0;
+  data_end = 0;
+  stack_start = STACK_END_ADDR;
+  stack_end = STACK_END_ADDR;
+
+  /* Now, if a new core file was specified, open it and digest it.  */
+
+  if (filename)
+    {
+      filename = tilde_expand (filename);
+      make_cleanup (free, filename);
+      
+      if (have_inferior_p ())
+       error ("To look at a core file, you must kill the inferior with \"kill\".");
+      corechan = open (filename, O_RDONLY, 0);
+      if (corechan < 0)
+       perror_with_name (filename);
+      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
+      {
+       struct ptrace_user u;
+       int reg_offset;
+
+       val = myread (corechan, &u, sizeof u);
+       if (val < 0)
+         perror_with_name (filename);
+       data_start = exec_data_start;
+
+       data_end = data_start + u.pt_dsize;
+       stack_start = stack_end - u.pt_ssize;
+       data_offset = sizeof u;
+       stack_offset = data_offset + u.pt_dsize;
+       reg_offset = 0;
+
+       bcopy (&u.pt_aouthdr, &core_aouthdr, sizeof (AOUTHDR));
+       printf ("Core file is from \"%s\".\n", u.pt_comm);
+       if (u.pt_signal > 0)
+         printf ("Program terminated with signal %d, %s.\n",
+                       u.pt_signal,
+                       u.pt_signal < NSIG
+                       ? sys_siglist[u.pt_signal]
+                       : "(undocumented)");
+
+       /* Read the register values out of the core file and store
+          them where `read_register' will find them.  */
+
+       {
+         register int regno;
+
+         for (regno = 0; regno < NUM_REGS; regno++)
+           {
+             char buf[MAX_REGISTER_RAW_SIZE];
+
+             val = lseek (corechan, register_addr (regno, reg_offset), 0);
+             if (val < 0)
+               perror_with_name (filename);
+
+             val = myread (corechan, buf, sizeof buf);
+             if (val < 0)
+               perror_with_name (filename);
+             supply_register (regno, buf);
+           }
+       }
+      }
+      if (filename[0] == '/')
+       corefile = savestring (filename, strlen (filename));
+      else
+       {
+         corefile = concat (current_directory, "/", filename);
+       }
+
+      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
+                                           read_pc ()));
+      select_frame (get_current_frame (), 0);
+      validate_files ();
+    }
+  else if (from_tty)
+    printf ("No core file now.\n");
+}
diff --git a/gdb/values.c b/gdb/values.c
new file mode 100644 (file)
index 0000000..39ec8ea
--- /dev/null
@@ -0,0 +1,1337 @@
+/* Low level packing and unpacking of values for GDB.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include <string.h>
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcore.h"
+#include "frame.h"
+#include "command.h"
+
+/* The value-history records all the values printed
+   by print commands during this session.  Each chunk
+   records 60 consecutive values.  The first chunk on
+   the chain records the most recent values.
+   The total number of values is in value_history_count.  */
+
+#define VALUE_HISTORY_CHUNK 60
+
+struct value_history_chunk
+{
+  struct value_history_chunk *next;
+  value values[VALUE_HISTORY_CHUNK];
+};
+
+/* Chain of chunks now in use.  */
+
+static struct value_history_chunk *value_history_chain;
+
+static int value_history_count;        /* Abs number of last entry stored */
+
+\f
+/* List of all value objects currently allocated
+   (except for those released by calls to release_value)
+   This is so they can be freed after each command.  */
+
+static value all_values;
+
+/* Allocate a  value  that has the correct length for type TYPE.  */
+
+value
+allocate_value (type)
+     struct type *type;
+{
+  register value val;
+
+  check_stub_type (type);
+
+  val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type));
+  VALUE_NEXT (val) = all_values;
+  all_values = val;
+  VALUE_TYPE (val) = type;
+  VALUE_LVAL (val) = not_lval;
+  VALUE_ADDRESS (val) = 0;
+  VALUE_FRAME (val) = 0;
+  VALUE_OFFSET (val) = 0;
+  VALUE_BITPOS (val) = 0;
+  VALUE_BITSIZE (val) = 0;
+  VALUE_REPEATED (val) = 0;
+  VALUE_REPETITIONS (val) = 0;
+  VALUE_REGNO (val) = -1;
+  VALUE_LAZY (val) = 0;
+  VALUE_OPTIMIZED_OUT (val) = 0;
+  return val;
+}
+
+/* Allocate a  value  that has the correct length
+   for COUNT repetitions type TYPE.  */
+
+value
+allocate_repeat_value (type, count)
+     struct type *type;
+     int count;
+{
+  register value val;
+
+  val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count);
+  VALUE_NEXT (val) = all_values;
+  all_values = val;
+  VALUE_TYPE (val) = type;
+  VALUE_LVAL (val) = not_lval;
+  VALUE_ADDRESS (val) = 0;
+  VALUE_FRAME (val) = 0;
+  VALUE_OFFSET (val) = 0;
+  VALUE_BITPOS (val) = 0;
+  VALUE_BITSIZE (val) = 0;
+  VALUE_REPEATED (val) = 1;
+  VALUE_REPETITIONS (val) = count;
+  VALUE_REGNO (val) = -1;
+  VALUE_LAZY (val) = 0;
+  VALUE_OPTIMIZED_OUT (val) = 0;
+  return val;
+}
+
+/* Free all the values that have been allocated (except for those released).
+   Called after each command, successful or not.  */
+
+void
+free_all_values ()
+{
+  register value val, next;
+
+  for (val = all_values; val; val = next)
+    {
+      next = VALUE_NEXT (val);
+      value_free (val);
+    }
+
+  all_values = 0;
+}
+
+/* Remove VAL from the chain all_values
+   so it will not be freed automatically.  */
+
+void
+release_value (val)
+     register value val;
+{
+  register value v;
+
+  if (all_values == val)
+    {
+      all_values = val->next;
+      return;
+    }
+
+  for (v = all_values; v; v = v->next)
+    {
+      if (v->next == val)
+       {
+         v->next = val->next;
+         break;
+       }
+    }
+}
+
+/* Return a copy of the value ARG.
+   It contains the same contents, for same memory address,
+   but it's a different block of storage.  */
+
+static value
+value_copy (arg)
+     value arg;
+{
+  register value val;
+  register struct type *type = VALUE_TYPE (arg);
+  if (VALUE_REPEATED (arg))
+    val = allocate_repeat_value (type, VALUE_REPETITIONS (arg));
+  else
+    val = allocate_value (type);
+  VALUE_LVAL (val) = VALUE_LVAL (arg);
+  VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
+  VALUE_OFFSET (val) = VALUE_OFFSET (arg);
+  VALUE_BITPOS (val) = VALUE_BITPOS (arg);
+  VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
+  VALUE_REGNO (val) = VALUE_REGNO (arg);
+  VALUE_LAZY (val) = VALUE_LAZY (arg);
+  if (!VALUE_LAZY (val))
+    {
+      bcopy (VALUE_CONTENTS_RAW (arg), VALUE_CONTENTS_RAW (val),
+            TYPE_LENGTH (VALUE_TYPE (arg))
+            * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
+    }
+  return val;
+}
+\f
+/* Access to the value history.  */
+
+/* Record a new value in the value history.
+   Returns the absolute history index of the entry.
+   Result of -1 indicates the value was not saved; otherwise it is the
+   value history index of this new item.  */
+
+int
+record_latest_value (val)
+     value val;
+{
+  int i;
+
+  /* Check error now if about to store an invalid float.  We return -1
+     to the caller, but allow them to continue, e.g. to print it as "Nan". */
+  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT) {
+    (void) unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i);
+    if (i) return -1;          /* Indicate value not saved in history */
+  }
+
+  /* Here we treat value_history_count as origin-zero
+     and applying to the value being stored now.  */
+
+  i = value_history_count % VALUE_HISTORY_CHUNK;
+  if (i == 0)
+    {
+      register struct value_history_chunk *new
+       = (struct value_history_chunk *)
+         xmalloc (sizeof (struct value_history_chunk));
+      bzero (new->values, sizeof new->values);
+      new->next = value_history_chain;
+      value_history_chain = new;
+    }
+
+  value_history_chain->values[i] = val;
+  release_value (val);
+
+  /* Now we regard value_history_count as origin-one
+     and applying to the value just stored.  */
+
+  return ++value_history_count;
+}
+
+/* Return a copy of the value in the history with sequence number NUM.  */
+
+value
+access_value_history (num)
+     int num;
+{
+  register struct value_history_chunk *chunk;
+  register int i;
+  register int absnum = num;
+
+  if (absnum <= 0)
+    absnum += value_history_count;
+
+  if (absnum <= 0)
+    {
+      if (num == 0)
+       error ("The history is empty.");
+      else if (num == 1)
+       error ("There is only one value in the history.");
+      else
+       error ("History does not go back to $$%d.", -num);
+    }
+  if (absnum > value_history_count)
+    error ("History has not yet reached $%d.", absnum);
+
+  absnum--;
+
+  /* Now absnum is always absolute and origin zero.  */
+
+  chunk = value_history_chain;
+  for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK;
+       i > 0; i--)
+    chunk = chunk->next;
+
+  return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
+}
+
+/* Clear the value history entirely.
+   Must be done when new symbol tables are loaded,
+   because the type pointers become invalid.  */
+
+void
+clear_value_history ()
+{
+  register struct value_history_chunk *next;
+  register int i;
+  register value val;
+
+  while (value_history_chain)
+    {
+      for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
+       if (val = value_history_chain->values[i])
+         free (val);
+      next = value_history_chain->next;
+      free (value_history_chain);
+      value_history_chain = next;
+    }
+  value_history_count = 0;
+}
+
+static void
+value_history_info (num_exp, from_tty)
+     char *num_exp;
+     int from_tty;
+{
+  register int i;
+  register value val;
+  static int num = 1;
+
+  if (num_exp)
+    {
+      if (num_exp[0] == '+' && num_exp[1] == '\0')
+       /* "info history +" should print from the stored position.  */
+       ;
+      else
+       /* "info history <exp>" should print around value number <exp>.  */
+       num = parse_and_eval_address (num_exp) - 5;
+    }
+  else
+    {
+      /* "info history" means print the last 10 values.  */
+      num = value_history_count - 9;
+    }
+
+  if (num <= 0)
+    num = 1;
+
+  for (i = num; i < num + 10 && i <= value_history_count; i++)
+    {
+      val = access_value_history (i);
+      printf_filtered ("$%d = ", i);
+      value_print (val, stdout, 0, Val_pretty_default);
+      printf_filtered ("\n");
+    }
+
+  /* The next "info history +" should start after what we just printed.  */
+  num += 10;
+
+  /* Hitting just return after this command should do the same thing as
+     "info history +".  If num_exp is null, this is unnecessary, since
+     "info history +" is not useful after "info history".  */
+  if (from_tty && num_exp)
+    {
+      num_exp[0] = '+';
+      num_exp[1] = '\0';
+    }
+}
+\f
+/* Internal variables.  These are variables within the debugger
+   that hold values assigned by debugger commands.
+   The user refers to them with a '$' prefix
+   that does not appear in the variable names stored internally.  */
+
+static struct internalvar *internalvars;
+
+/* Look up an internal variable with name NAME.  NAME should not
+   normally include a dollar sign.
+
+   If the specified internal variable does not exist,
+   one is created, with a void value.  */
+
+struct internalvar *
+lookup_internalvar (name)
+     char *name;
+{
+  register struct internalvar *var;
+
+  for (var = internalvars; var; var = var->next)
+    if (!strcmp (var->name, name))
+      return var;
+
+  var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
+  var->name = concat (name, "", "");
+  var->value = allocate_value (builtin_type_void);
+  release_value (var->value);
+  var->next = internalvars;
+  internalvars = var;
+  return var;
+}
+
+value
+value_of_internalvar (var)
+     struct internalvar *var;
+{
+  register value val;
+
+#ifdef IS_TRAPPED_INTERNALVAR
+  if (IS_TRAPPED_INTERNALVAR (var->name))
+    return VALUE_OF_TRAPPED_INTERNALVAR (var);
+#endif 
+
+  val = value_copy (var->value);
+  if (VALUE_LAZY (val))
+    value_fetch_lazy (val);
+  VALUE_LVAL (val) = lval_internalvar;
+  VALUE_INTERNALVAR (val) = var;
+  return val;
+}
+
+void
+set_internalvar_component (var, offset, bitpos, bitsize, newval)
+     struct internalvar *var;
+     int offset, bitpos, bitsize;
+     value newval;
+{
+  register char *addr = VALUE_CONTENTS (var->value) + offset;
+
+#ifdef IS_TRAPPED_INTERNALVAR
+  if (IS_TRAPPED_INTERNALVAR (var->name))
+    SET_TRAPPED_INTERNALVAR (var, newval, bitpos, bitsize, offset);
+#endif
+
+  if (bitsize)
+    modify_field (addr, (int) value_as_long (newval),
+                 bitpos, bitsize);
+  else
+    bcopy (VALUE_CONTENTS (newval), addr,
+          TYPE_LENGTH (VALUE_TYPE (newval)));
+}
+
+void
+set_internalvar (var, val)
+     struct internalvar *var;
+     value val;
+{
+#ifdef IS_TRAPPED_INTERNALVAR
+  if (IS_TRAPPED_INTERNALVAR (var->name))
+    SET_TRAPPED_INTERNALVAR (var, val, 0, 0, 0);
+#endif
+
+  free (var->value);
+  var->value = value_copy (val);
+  release_value (var->value);
+}
+
+char *
+internalvar_name (var)
+     struct internalvar *var;
+{
+  return var->name;
+}
+
+/* Free all internalvars.  Done when new symtabs are loaded,
+   because that makes the values invalid.  */
+
+void
+clear_internalvars ()
+{
+  register struct internalvar *var;
+
+  while (internalvars)
+    {
+      var = internalvars;
+      internalvars = var->next;
+      free (var->name);
+      free (var->value);
+      free (var);
+    }
+}
+
+static void
+convenience_info ()
+{
+  register struct internalvar *var;
+  int varseen = 0;
+
+  for (var = internalvars; var; var = var->next)
+    {
+#ifdef IS_TRAPPED_INTERNALVAR
+      if (IS_TRAPPED_INTERNALVAR (var->name))
+       continue;
+#endif
+      if (!varseen)
+       {
+#if 0
+         /* Useless noise.  */
+         printf ("Debugger convenience variables:\n\n");
+#endif
+         varseen = 1;
+       }
+      printf ("$%s = ", var->name);
+      value_print (var->value, stdout, 0, Val_pretty_default);
+      printf ("\n");
+    }
+  if (!varseen)
+    printf ("No debugger convenience variables now defined.\n\
+Convenience variables have names starting with \"$\";\n\
+use \"set\" as in \"set $foo = 5\" to define them.\n");
+}
+\f
+/* Extract a value as a C number (either long or double).
+   Knows how to convert fixed values to double, or
+   floating values to long.
+   Does not deallocate the value.  */
+
+LONGEST
+value_as_long (val)
+     register value val;
+{
+  /* This coerces arrays and functions, which is necessary (e.g.
+     in disassemble_command).  It also dereferences references, which
+     I suspect is the most logical thing to do.  */
+  if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM)
+    COERCE_ARRAY (val);
+  return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+}
+
+double
+value_as_double (val)
+     register value val;
+{
+  double foo;
+  int inv;
+  
+  foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
+  if (inv)
+    error ("Invalid floating value found in program.");
+  return foo;
+}
+\f
+/* Unpack raw data (copied from debugee, target byte order) at VALADDR
+   as a long, or as a double, assuming the raw data is described
+   by type TYPE.  Knows how to convert different sizes of values
+   and can convert between fixed and floating point.  We don't assume
+   any alignment for the raw data.  Return value is in host byte order.
+
+   If you want functions and arrays to be coerced to pointers, and
+   references to be dereferenced, call value_as_long() instead.
+
+   C++: It is assumed that the front-end has taken care of
+   all matters concerning pointers to members.  A pointer
+   to member which reaches here is considered to be equivalent
+   to an INT (or some size).  After all, it is only an offset.  */
+
+LONGEST
+unpack_long (type, valaddr)
+     struct type *type;
+     char *valaddr;
+{
+  register enum type_code code = TYPE_CODE (type);
+  register int len = TYPE_LENGTH (type);
+  register int nosign = TYPE_UNSIGNED (type);
+
+  if (code == TYPE_CODE_ENUM)
+    code = TYPE_CODE_INT;
+  if (code == TYPE_CODE_FLT)
+    {
+      if (len == sizeof (float))
+       {
+         float retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (double))
+       {
+         double retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+      else
+       {
+         error ("Unexpected type of floating point number.");
+       }
+    }
+  else if (code == TYPE_CODE_INT && nosign)
+    {
+      if (len == sizeof (char))
+       {
+         unsigned char retval = * (unsigned char *) valaddr;
+         /* SWAP_TARGET_AND_HOST (&retval, sizeof (unsigned char)); */
+         return retval;
+       }
+
+      if (len == sizeof (short))
+       {
+         unsigned short retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (int))
+       {
+         unsigned int retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (long))
+       {
+         unsigned long retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+#ifdef LONG_LONG
+      if (len == sizeof (long long))
+       {
+         unsigned long long retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+#endif
+      else
+       {
+         error ("That operation is not possible on an integer of that size.");
+       }
+    }
+  else if (code == TYPE_CODE_INT)
+    {
+      if (len == sizeof (char))
+       {
+         char retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (short))
+       {
+         short retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (int))
+       {
+         int retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (long))
+       {
+         long retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+#ifdef LONG_LONG
+      if (len == sizeof (long long))
+       {
+         long long retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+#endif
+      else
+       {
+         error ("That operation is not possible on an integer of that size.");
+       }
+    }
+  else if (code == TYPE_CODE_PTR
+          || code == TYPE_CODE_REF)
+    {
+      if (len == sizeof (char *))
+       {
+         CORE_ADDR retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+    }
+  else if (code == TYPE_CODE_MEMBER)
+    error ("not implemented: member types in unpack_long");
+
+  error ("Value not integer or pointer.");
+  return 0;    /* For lint -- never reached */
+}
+
+/* Return a double value from the specified type and address.
+   INVP points to an int which is set to 0 for valid value,
+   1 for invalid value (bad float format).  In either case,
+   the returned double is OK to use.  Argument is in target
+   format, result is in host format.  */
+
+double
+unpack_double (type, valaddr, invp)
+     struct type *type;
+     char *valaddr;
+     int *invp;
+{
+  register enum type_code code = TYPE_CODE (type);
+  register int len = TYPE_LENGTH (type);
+  register int nosign = TYPE_UNSIGNED (type);
+
+  *invp = 0;                   /* Assume valid.   */
+  if (code == TYPE_CODE_FLT)
+    {
+      if (INVALID_FLOAT (valaddr, len))
+       {
+         *invp = 1;
+         return 1.234567891011121314;
+       }
+
+      if (len == sizeof (float))
+       {
+         float retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+
+      if (len == sizeof (double))
+       {
+         double retval;
+         bcopy (valaddr, &retval, sizeof (retval));
+         SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+         return retval;
+       }
+      else
+       {
+         error ("Unexpected type of floating point number.");
+       }
+    }
+  else if (nosign) {
+   /* Unsigned -- be sure we compensate for signed LONGEST.  */
+#ifdef LONG_LONG
+   return (unsigned long long) unpack_long (type, valaddr);
+#else
+   return (unsigned long     ) unpack_long (type, valaddr);
+#endif
+  } else {
+    /* Signed -- we are OK with unpack_long.  */
+    return unpack_long (type, valaddr);
+  }
+}
+\f
+/* Given a value ARG1 (offset by OFFSET bytes)
+   of a struct or union type ARG_TYPE,
+   extract and return the value of one of its fields.
+   FIELDNO says which field.
+
+   For C++, must also be able to return values from static fields */
+
+value
+value_primitive_field (arg1, offset, fieldno, arg_type)
+     register value arg1;
+     int offset;
+     register int fieldno;
+     register struct type *arg_type;
+{
+  register value v;
+  register struct type *type;
+
+  check_stub_type (arg_type);
+  type = TYPE_FIELD_TYPE (arg_type, fieldno);
+
+  /* Handle packed fields */
+
+  offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+  if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
+    {
+      v = value_from_long (type,
+                          unpack_field_as_long (arg_type,
+                                                VALUE_CONTENTS (arg1),
+                                                fieldno));
+      VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
+      VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+    }
+  else
+    {
+      v = allocate_value (type);
+      if (VALUE_LAZY (arg1))
+       VALUE_LAZY (v) = 1;
+      else
+       bcopy (VALUE_CONTENTS_RAW (arg1) + offset,
+              VALUE_CONTENTS_RAW (v),
+              TYPE_LENGTH (type));
+    }
+  VALUE_LVAL (v) = VALUE_LVAL (arg1);
+  if (VALUE_LVAL (arg1) == lval_internalvar)
+    VALUE_LVAL (v) = lval_internalvar_component;
+  VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
+  VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);
+  return v;
+}
+
+/* Given a value ARG1 of a struct or union type,
+   extract and return the value of one of its fields.
+   FIELDNO says which field.
+
+   For C++, must also be able to return values from static fields */
+
+value
+value_field (arg1, fieldno)
+     register value arg1;
+     register int fieldno;
+{
+  return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));
+}
+
+value
+value_fn_field (arg1, fieldno, subfieldno)
+     register value arg1;
+     register int fieldno;
+     int subfieldno;
+{
+  register value v;
+  struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno);
+  register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno);
+  struct symbol *sym;
+
+  sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno),
+                      0, VAR_NAMESPACE, 0, NULL);
+  if (! sym) error ("Internal error: could not find physical method named %s",
+                   TYPE_FN_FIELD_PHYSNAME (f, subfieldno));
+  
+  v = allocate_value (type);
+  VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+  VALUE_TYPE (v) = type;
+  return v;
+}
+
+/* Return a virtual function as a value.
+   ARG1 is the object which provides the virtual function
+   table pointer.  ARG1 is side-effected in calling this function.
+   F is the list of member functions which contains the desired virtual
+   function.
+   J is an index into F which provides the desired virtual function.  */
+value
+value_virtual_fn_field (arg1, f, j)
+     value arg1;
+     struct fn_field *f;
+     int j;
+{
+  /* First, get the virtual function table pointer.  That comes
+     with a strange type, so cast it to type `pointer to long' (which
+     should serve just fine as a function type).  Then, index into
+     the table, and convert final value to appropriate function type.  */
+  value entry, vfn, vtbl;
+  value vi = value_from_long (builtin_type_int, 
+                             (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+  struct type *context = lookup_pointer_type (TYPE_FN_FIELD_FCONTEXT (f, j));
+  if (TYPE_TARGET_TYPE (context) != VALUE_TYPE (arg1))
+    arg1 = value_ind (value_cast (context, value_addr (arg1)));
+
+  context = VALUE_TYPE (arg1);
+
+  /* This type may have been defined before its virtual function table
+     was.  If so, fill in the virtual function table entry for the
+     type now.  */
+  if (TYPE_VPTR_FIELDNO (context) < 0)
+    TYPE_VPTR_FIELDNO (context)
+      = fill_in_vptr_fieldno (context);
+
+  /* The virtual function table is now an array of structures
+     which have the form { int16 offset, delta; void *pfn; }.  */
+  vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (context)));
+
+  /* Index into the virtual function table.  This is hard-coded because
+     looking up a field is not cheap, and it may be important to save
+     time, e.g. if the user has set a conditional breakpoint calling
+     a virtual function.  */
+  entry = value_subscript (vtbl, vi);
+
+  /* Move the `this' pointer according to the virtual function table.  */
+  VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
+  if (! VALUE_LAZY (arg1))
+    {
+      VALUE_LAZY (arg1) = 1;
+      value_fetch_lazy (arg1);
+    }
+
+  vfn = value_field (entry, 2);
+  /* Reinstantiate the function pointer with the correct type.  */
+  VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+
+  return vfn;
+}
+
+/* The value of a static class member does not depend
+   on its instance, only on its type.  If FIELDNO >= 0,
+   then fieldno is a valid field number and is used directly.
+   Otherwise, FIELDNAME is the name of the field we are
+   searching for.  If it is not a static field name, an
+   error is signaled.  TYPE is the type in which we look for the
+   static field member.  */
+value
+value_static_field (type, fieldname, fieldno)
+     register struct type *type;
+     char *fieldname;
+     register int fieldno;
+{
+  register value v;
+  struct symbol *sym;
+  char *phys_name;
+
+  if (fieldno < 0)
+    {
+      register struct type *t = type;
+      /* Look for static field.  */
+      while (t)
+       {
+         int i;
+         for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
+           if (! strcmp (TYPE_FIELD_NAME (t, i), fieldname))
+             {
+               if (TYPE_FIELD_STATIC (t, i))
+                 {
+                   fieldno = i;
+                   goto found;
+                 }
+               else
+                 error ("field `%s' is not static");
+             }
+         /* FIXME: this does not recursively check multiple baseclasses.  */
+         t = TYPE_N_BASECLASSES (t) ? TYPE_BASECLASS (t, 0) : 0;
+       }
+
+      t = type;
+
+      if (destructor_name_p (fieldname, t))
+       error ("Cannot get value of destructor");
+
+      while (t)
+       {
+         int i;
+
+         for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--)
+           {
+             if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), fieldname))
+               {
+                 error ("Cannot get value of method \"%s\"", fieldname);
+               }
+           }
+         t = TYPE_N_BASECLASSES (t) ? TYPE_BASECLASS (t, 0) : 0;
+       }
+      error("there is no field named %s", fieldname);
+    }
+
+ found:
+  phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+  sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+  if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name);
+
+  type = TYPE_FIELD_TYPE (type, fieldno);
+  v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+  return v;
+}
+
+/* Compute the address of the baseclass which is
+   the INDEXth baseclass of TYPE.  The TYPE base
+   of the object is at VALADDR.  */
+
+char *
+baseclass_addr (type, index, valaddr, valuep)
+     struct type *type;
+     int index;
+     char *valaddr;
+     value *valuep;
+{
+  struct type *basetype = TYPE_BASECLASS (type, index);
+
+  if (BASETYPE_VIA_VIRTUAL (type, index))
+    {
+      /* Must hunt for the pointer to this virtual baseclass.  */
+      register int i, len = TYPE_NFIELDS (type);
+      register int n_baseclasses = TYPE_N_BASECLASSES (type);
+      char *vbase_name, *type_name = type_name_no_tag (basetype);
+
+      if (TYPE_MAIN_VARIANT (basetype))
+       basetype = TYPE_MAIN_VARIANT (basetype);
+
+      vbase_name = (char *)alloca (strlen (type_name) + 8);
+      sprintf (vbase_name, "_vb$%s", type_name);
+      /* First look for the virtual baseclass pointer
+        in the fields.  */
+      for (i = n_baseclasses; i < len; i++)
+       {
+         if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i)))
+           {
+             value v = value_at (basetype,
+                                 unpack_long (TYPE_FIELD_TYPE (type, i),
+                                              valaddr + (TYPE_FIELD_BITPOS (type, i) / 8)));
+             if (valuep)
+               *valuep = v;
+             return (char *) VALUE_CONTENTS (v);
+           }
+       }
+      /* Not in the fields, so try looking through the baseclasses.  */
+      for (i = index+1; i < n_baseclasses; i++)
+       {
+         char *baddr;
+
+         baddr = baseclass_addr (type, i, valaddr, valuep);
+         if (baddr)
+           return baddr;
+       }
+      /* Not found.  */
+      if (valuep)
+       *valuep = 0;
+      return 0;
+    }
+
+  /* Baseclass is easily computed.  */
+  if (valuep)
+    *valuep = 0;
+  return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
+}
+
+/* Ugly hack to convert method stubs into method types.
+
+   He ain't kiddin'.  This demangles the name of the method into a string
+   including argument types, parses out each argument type, generates
+   a string casting a zero to that type, evaluates the string, and stuffs
+   the resulting type into an argtype vector!!!  Then it knows the type
+   of the whole function (including argument types for overloading),
+   which info used to be in the stab's but was removed to hack back
+   the space required for them.  */
+void
+check_stub_method (type, i, j)
+     struct type *type;
+     int i, j;
+{
+  extern char *gdb_mangle_typename (), *strchr ();
+  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+  char *inner_name = gdb_mangle_typename (type);
+  char *mangled_name
+    = (char *)xmalloc (strlen (TYPE_FN_FIELDLIST_NAME (type, i))
+                      + strlen (inner_name)
+                      + strlen (TYPE_FN_FIELD_PHYSNAME (f, j))
+                      + 1);
+  char *demangled_name, *cplus_demangle ();
+  char *argtypetext, *p;
+  int depth = 0, argcount = 1;
+  struct type **argtypes;
+
+  strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i));
+  strcat (mangled_name, inner_name);
+  strcat (mangled_name, TYPE_FN_FIELD_PHYSNAME (f, j));
+  demangled_name = cplus_demangle (mangled_name, 0);
+
+  /* Now, read in the parameters that define this type.  */
+  argtypetext = strchr (demangled_name, '(') + 1;
+  p = argtypetext;
+  while (*p)
+    {
+      if (*p == '(')
+       depth += 1;
+      else if (*p == ')')
+       depth -= 1;
+      else if (*p == ',' && depth == 0)
+       argcount += 1;
+
+      p += 1;
+    }
+  /* We need one more slot for the void [...] or NULL [end of arglist] */
+  argtypes = (struct type **)xmalloc ((argcount+1) * sizeof (struct type *));
+  p = argtypetext;
+  argtypes[0] = lookup_pointer_type (type);
+  argcount = 1;
+
+  if (*p != ')')                       /* () means no args, skip while */
+    {
+      while (*p)
+       {
+         if (*p == '(')
+           depth += 1;
+         else if (*p == ')')
+           depth -= 1;
+
+         if (depth <= 0 && (*p == ',' || *p == ')'))
+           {
+             char *tmp = (char *)alloca (p - argtypetext + 4);
+             value val;
+             tmp[0] = '(';
+             bcopy (argtypetext, tmp+1, p - argtypetext);
+             tmp[p-argtypetext+1] = ')';
+             tmp[p-argtypetext+2] = '0';
+             tmp[p-argtypetext+3] = '\0';
+             val = parse_and_eval (tmp);
+             argtypes[argcount] = VALUE_TYPE (val);
+             argcount += 1;
+             argtypetext = p + 1;
+           }
+         p += 1;
+       }
+    }
+
+  if (p[-2] != '.')                    /* ... */
+    argtypes[argcount] = builtin_type_void;    /* Ellist terminator */
+  else
+    argtypes[argcount] = NULL;         /* List terminator */
+
+  free (demangled_name);
+  smash_to_method_type (TYPE_FN_FIELD_TYPE (f, j), type,
+                       TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+                       argtypes);
+  TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
+  TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, j)) &= ~TYPE_FLAG_STUB;
+}
+\f
+long
+unpack_field_as_long (type, valaddr, fieldno)
+     struct type *type;
+     char *valaddr;
+     int fieldno;
+{
+  long val;
+  int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
+  int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
+
+  bcopy (valaddr + bitpos / 8, &val, sizeof val);
+  SWAP_TARGET_AND_HOST (&val, sizeof val);
+
+  /* Extracting bits depends on endianness of the machine.  */
+#ifdef BITS_BIG_ENDIAN
+  val = val >> (sizeof val * 8 - bitpos % 8 - bitsize);
+#else
+  val = val >> (bitpos % 8);
+#endif
+
+  val &= (1 << bitsize) - 1;
+  return val;
+}
+
+void
+modify_field (addr, fieldval, bitpos, bitsize)
+     char *addr;
+     int fieldval;
+     int bitpos, bitsize;
+{
+  long oword;
+
+  /* Reject values too big to fit in the field in question.
+     Otherwise adjoining fields may be corrupted.  */
+  if (fieldval & ~((1<<bitsize)-1))
+    error ("Value %d does not fit in %d bits.", fieldval, bitsize);
+  
+  bcopy (addr, &oword, sizeof oword);
+
+  /* Shifting for bit field depends on endianness of the machine.  */
+#ifdef BITS_BIG_ENDIAN
+  bitpos = sizeof (oword) * 8 - bitpos - bitsize;
+#endif
+
+  oword &= ~(((1 << bitsize) - 1) << bitpos);
+  oword |= fieldval << bitpos;
+  bcopy (&oword, addr, sizeof oword);
+}
+\f
+/* Convert C numbers into newly allocated values */
+
+value
+value_from_long (type, num)
+     struct type *type;
+     register LONGEST num;
+{
+  register value val = allocate_value (type);
+  register enum type_code code = TYPE_CODE (type);
+  register int len = TYPE_LENGTH (type);
+
+  if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM)
+    {
+      if (len == sizeof (char))
+       * (char *) VALUE_CONTENTS_RAW (val) = num;
+      else if (len == sizeof (short))
+       * (short *) VALUE_CONTENTS_RAW (val) = num;
+      else if (len == sizeof (int))
+       * (int *) VALUE_CONTENTS_RAW (val) = num;
+      else if (len == sizeof (long))
+       * (long *) VALUE_CONTENTS_RAW (val) = num;
+#ifdef LONG_LONG
+      else if (len == sizeof (long long))
+       * (long long *) VALUE_CONTENTS_RAW (val) = num;
+#endif
+      else
+       error ("Integer type encountered with unexpected data length.");
+    }
+  else
+    error ("Unexpected type encountered for integer constant.");
+
+  /* num was in host byte order.  So now put the value's contents
+     into target byte order.  */
+  SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (val), len);
+
+  return val;
+}
+
+value
+value_from_double (type, num)
+     struct type *type;
+     double num;
+{
+  register value val = allocate_value (type);
+  register enum type_code code = TYPE_CODE (type);
+  register int len = TYPE_LENGTH (type);
+
+  if (code == TYPE_CODE_FLT)
+    {
+      if (len == sizeof (float))
+       * (float *) VALUE_CONTENTS_RAW (val) = num;
+      else if (len == sizeof (double))
+       * (double *) VALUE_CONTENTS_RAW (val) = num;
+      else
+       error ("Floating type encountered with unexpected data length.");
+    }
+  else
+    error ("Unexpected type encountered for floating constant.");
+
+  /* num was in host byte order.  So now put the value's contents
+     into target byte order.  */
+  SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (val), len);
+
+  return val;
+}
+\f
+/* Deal with the value that is "about to be returned".  */
+
+/* Return the value that a function returning now
+   would be returning to its caller, assuming its type is VALTYPE.
+   RETBUF is where we look for what ought to be the contents
+   of the registers (in raw form).  This is because it is often
+   desirable to restore old values to those registers
+   after saving the contents of interest, and then call
+   this function using the saved values.
+   struct_return is non-zero when the function in question is
+   using the structure return conventions on the machine in question;
+   0 when it is using the value returning conventions (this often
+   means returning pointer to where structure is vs. returning value). */
+
+value
+value_being_returned (valtype, retbuf, struct_return)
+     register struct type *valtype;
+     char retbuf[REGISTER_BYTES];
+     int struct_return;
+     /*ARGSUSED*/
+{
+  register value val;
+  CORE_ADDR addr;
+
+#if defined (EXTRACT_STRUCT_VALUE_ADDRESS)
+  /* If this is not defined, just use EXTRACT_RETURN_VALUE instead.  */
+  if (struct_return) {
+    addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);
+    if (!addr)
+      error ("Function return value unknown");
+    return value_at (valtype, addr);
+  }
+#endif
+
+  val = allocate_value (valtype);
+  EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
+
+  return val;
+}
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+   EXTRACT_RETURN_VALUE?  GCC_P is true if compiled with gcc
+   and TYPE is the type (which is known to be struct, union or array).
+
+   On most machines, the struct convention is used unless we are
+   using gcc and the type is of a special size.  */
+#if !defined (USE_STRUCT_CONVENTION)
+#define USE_STRUCT_CONVENTION(gcc_p, type)\
+  (!((gcc_p) && (TYPE_LENGTH (value_type) == 1                \
+                || TYPE_LENGTH (value_type) == 2             \
+                || TYPE_LENGTH (value_type) == 4             \
+                || TYPE_LENGTH (value_type) == 8             \
+                )                                            \
+     ))
+#endif
+
+/* Return true if the function specified is using the structure returning
+   convention on this machine to return arguments, or 0 if it is using
+   the value returning convention.  FUNCTION is the value representing
+   the function, FUNCADDR is the address of the function, and VALUE_TYPE
+   is the type returned by the function.  GCC_P is nonzero if compiled
+   with GCC.  */
+
+int
+using_struct_return (function, funcaddr, value_type, gcc_p)
+     value function;
+     CORE_ADDR funcaddr;
+     struct type *value_type;
+     int gcc_p;
+     /*ARGSUSED*/
+{
+  register enum type_code code = TYPE_CODE (value_type);
+
+  if (code == TYPE_CODE_ERROR)
+    error ("Function return type unknown.");
+
+  if (code == TYPE_CODE_STRUCT ||
+      code == TYPE_CODE_UNION ||
+      code == TYPE_CODE_ARRAY)
+    return USE_STRUCT_CONVENTION (gcc_p, value_type);
+
+  return 0;
+}
+
+/* Store VAL so it will be returned if a function returns now.
+   Does not verify that VAL's type matches what the current
+   function wants to return.  */
+
+void
+set_return_value (val)
+     value val;
+{
+  register enum type_code code = TYPE_CODE (VALUE_TYPE (val));
+  double dbuf;
+  LONGEST lbuf;
+
+  if (code == TYPE_CODE_ERROR)
+    error ("Function return type unknown.");
+
+  if (code == TYPE_CODE_STRUCT
+      || code == TYPE_CODE_UNION)
+    error ("Specifying a struct or union return value is not supported.");
+
+  /* FIXME, this is bogus.  We don't know what the return conventions
+     are, or how values should be promoted.... */
+  if (code == TYPE_CODE_FLT)
+    {
+      dbuf = value_as_double (val);
+
+      STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&dbuf);
+    }
+  else
+    {
+      lbuf = value_as_long (val);
+      STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&lbuf);
+    }
+}
+\f
+void
+_initialize_values ()
+{
+  add_info ("convenience", convenience_info,
+           "Debugger convenience (\"$foo\") variables.\n\
+These variables are created when you assign them values;\n\
+thus, \"print $foo=1\" gives \"$foo\" the value 1.  Values may be any type.\n\n\
+A few convenience variables are given values automatically:\n\
+\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
+\"$__\" holds the contents of the last address examined with \"x\".");
+
+  add_info ("values", value_history_info,
+           "Elements of value history around item number IDX (or last ten).");
+  add_info_alias ("history", "values", 0);
+}
diff --git a/gdb/vax-opcode.h b/gdb/vax-opcode.h
new file mode 100755 (executable)
index 0000000..18a2ffb
--- /dev/null
@@ -0,0 +1,382 @@
+/* Vax opcde list.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+GDB and GAS are free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB and GAS are distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB or GAS; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef vax_opcodeT
+#define vax_opcodeT int
+#endif /* no vax_opcodeT */
+
+struct vot_wot                 /* vax opcode table: wot to do with this */
+                               /* particular opcode */
+{
+  char *            args;      /* how to compile said opcode */
+  vax_opcodeT       code;      /* op-code (may be > 8 bits!) */
+};
+
+struct vot                     /* vax opcode text */
+{
+  char *            name;      /* opcode name: lowercase string  [key]  */
+  struct vot_wot    detail;    /* rest of opcode table          [datum] */
+};
+
+#define vot_how args
+#define vot_code code
+#define vot_detail detail
+#define vot_name name
+
+static struct vot
+votstrs[] =
+{
+{    "halt",   {"",                    0x00    } },
+{    "nop",    {"",                    0x01    } },
+{    "rei",    {"",                    0x02    } },
+{    "bpt",    {"",                    0x03    } },
+{    "ret",    {"",                    0x04    } },
+{    "rsb",    {"",                    0x05    } },
+{    "ldpctx", {"",                    0x06    } },
+{    "svpctx", {"",                    0x07    } },
+{    "cvtps",  {"rwabrwab",            0x08    } },
+{    "cvtsp",  {"rwabrwab",            0x09    } },
+{    "index",  {"rlrlrlrlrlwl",        0x0a    } },
+{    "crc",    {"abrlrwab",            0x0b    } },
+{    "prober", {"rbrwab",              0x0c    } },
+{    "probew", {"rbrwab",              0x0d    } },
+{    "insque", {"abab",                0x0e    } },
+{    "remque", {"abwl",                0x0f    } },
+{    "bsbb",   {"bb",                  0x10    } },
+{    "brb",    {"bb",                  0x11    } },
+{    "bneq",   {"bb",                  0x12    } },
+{    "bnequ",  {"bb",                  0x12    } },
+{    "beql",   {"bb",                  0x13    } },
+{    "beqlu",  {"bb",                  0x13    } },
+{    "bgtr",   {"bb",                  0x14    } },
+{    "bleq",   {"bb",                  0x15    } },
+{    "jsb",    {"ab",                  0x16    } },
+{    "jmp",    {"ab",                  0x17    } },
+{    "bgeq",   {"bb",                  0x18    } },
+{    "blss",   {"bb",                  0x19    } },
+{    "bgtru",  {"bb",                  0x1a    } },
+{    "blequ",  {"bb",                  0x1b    } },
+{    "bvc",    {"bb",                  0x1c    } },
+{    "bvs",    {"bb",                  0x1d    } },
+{    "bcc",    {"bb",                  0x1e    } },
+{    "bgequ",  {"bb",                  0x1e    } },
+{    "blssu",  {"bb",                  0x1f    } },
+{    "bcs",    {"bb",                  0x1f    } },
+{    "addp4",  {"rwabrwab",            0x20    } },
+{    "addp6",  {"rwabrwabrwab",        0x21    } },
+{    "subp4",  {"rwabrwab",            0x22    } },
+{    "subp6",  {"rwabrwabrwab",        0x23    } },
+{    "cvtpt",  {"rwababrwab",          0x24    } },
+{    "mulp",   {"rwabrwabrwab",        0x25    } },
+{    "cvttp",  {"rwababrwab",          0x26    } },
+{    "divp",   {"rwabrwabrwab",        0x27    } },
+{    "movc3",  {"rwabab",              0x28    } },
+{    "cmpc3",  {"rwabab",              0x29    } },
+{    "scanc",  {"rwababrb",            0x2a    } },
+{    "spanc",  {"rwababrb",            0x2b    } },
+{    "movc5",  {"rwabrbrwab",          0x2c    } },
+{    "cmpc5",  {"rwabrbrwab",          0x2d    } },
+{    "movtc",  {"rwabrbabrwab",        0x2e    } },
+{    "movtuc", {"rwabrbabrwab",        0x2f    } },
+{    "bsbw",   {"bw",                  0x30    } },
+{    "brw",    {"bw",                  0x31    } },
+{    "cvtwl",  {"rwwl",                0x32    } },
+{    "cvtwb",  {"rwwb",                0x33    } },
+{    "movp",   {"rwabab",              0x34    } },
+{    "cmpp3",  {"rwabab",              0x35    } },
+{    "cvtpl",  {"rwabwl",              0x36    } },
+{    "cmpp4",  {"rwabrwab",            0x37    } },
+{    "editpc", {"rwababab",            0x38    } },
+{    "matchc", {"rwabrwab",            0x39    } },
+{    "locc",   {"rbrwab",              0x3a    } },
+{    "skpc",   {"rbrwab",              0x3b    } },
+{    "movzwl", {"rwwl",                0x3c    } },
+{    "acbw",   {"rwrwmwbw",            0x3d    } },
+{    "movaw",  {"awwl",                0x3e    } },
+{    "pushaw", {"aw",                  0x3f    } },
+{    "addf2",  {"rfmf",                0x40    } },
+{    "addf3",  {"rfrfwf",              0x41    } },
+{    "subf2",  {"rfmf",                0x42    } },
+{    "subf3",  {"rfrfwf",              0x43    } },
+{    "mulf2",  {"rfmf",                0x44    } },
+{    "mulf3",  {"rfrfwf",              0x45    } },
+{    "divf2",  {"rfmf",                0x46    } },
+{    "divf3",  {"rfrfwf",              0x47    } },
+{    "cvtfb",  {"rfwb",                0x48    } },
+{    "cvtfw",  {"rfww",                0x49    } },
+{    "cvtfl",  {"rfwl",                0x4a    } },
+{    "cvtrfl", {"rfwl",                0x4b    } },
+{    "cvtbf",  {"rbwf",                0x4c    } },
+{    "cvtwf",  {"rwwf",                0x4d    } },
+{    "cvtlf",  {"rlwf",                0x4e    } },
+{    "acbf",   {"rfrfmfbw",            0x4f    } },
+{    "movf",   {"rfwf",                0x50    } },
+{    "cmpf",   {"rfrf",                0x51    } },
+{    "mnegf",  {"rfwf",                0x52    } },
+{    "tstf",   {"rf",                  0x53    } },
+{    "emodf",  {"rfrbrfwlwf",          0x54    } },
+{    "polyf",  {"rfrwab",              0x55    } },
+{    "cvtfd",  {"rfwd",                0x56    } },
+                                        /* opcode 57 is not defined yet */
+{    "adawi",  {"rwmw",                0x58    } },
+                                        /* opcode 59 is not defined yet */
+                                        /* opcode 5a is not defined yet */
+                                        /* opcode 5b is not defined yet */
+{    "insqhi", {"abaq",                0x5c    } },
+{    "insqti", {"abaq",                0x5d    } },
+{    "remqhi", {"aqwl",                0x5e    } },
+{    "remqti", {"aqwl",                0x5f    } },
+{    "addd2",  {"rdmd",                0x60    } },
+{    "addd3",  {"rdrdwd",              0x61    } },
+{    "subd2",  {"rdmd",                0x62    } },
+{    "subd3",  {"rdrdwd",              0x63    } },
+{    "muld2",  {"rdmd",                0x64    } },
+{    "muld3",  {"rdrdwd",              0x65    } },
+{    "divd2",  {"rdmd",                0x66    } },
+{    "divd3",  {"rdrdwd",              0x67    } },
+{    "cvtdb",  {"rdwb",                0x68    } },
+{    "cvtdw",  {"rdww",                0x69    } },
+{    "cvtdl",  {"rdwl",                0x6a    } },
+{    "cvtrdl", {"rdwl",                0x6b    } },
+{    "cvtbd",  {"rbwd",                0x6c    } },
+{    "cvtwd",  {"rwwd",                0x6d    } },
+{    "cvtld",  {"rlwd",                0x6e    } },
+{    "acbd",   {"rdrdmdbw",            0x6f    } },
+{    "movd",   {"rdwd",                0x70    } },
+{    "cmpd",   {"rdrd",                0x71    } },
+{    "mnegd",  {"rdwd",                0x72    } },
+{    "tstd",   {"rd",                  0x73    } },
+{    "emodd",  {"rdrbrdwlwd",          0x74    } },
+{    "polyd",  {"rdrwab",              0x75    } },
+{    "cvtdf",  {"rdwf",                0x76    } },
+                                        /* opcode 77 is not defined yet */
+{    "ashl",   {"rbrlwl",              0x78    } },
+{    "ashq",   {"rbrqwq",              0x79    } },
+{    "emul",   {"rlrlrlwq",            0x7a    } },
+{    "ediv",   {"rlrqwlwl",            0x7b    } },
+{    "clrd",   {"wd",                  0x7c    } },
+{    "clrg",   {"wg",                  0x7c    } },
+{    "clrq",   {"wd",                  0x7c    } },
+{    "movq",   {"rqwq",                0x7d    } },
+{    "movaq",  {"aqwl",                0x7e    } },
+{    "movad",  {"adwl",                0x7e    } },
+{    "pushaq", {"aq",                  0x7f    } },
+{    "pushad", {"ad",                  0x7f    } },
+{    "addb2",  {"rbmb",                0x80    } },
+{    "addb3",  {"rbrbwb",              0x81    } },
+{    "subb2",  {"rbmb",                0x82    } },
+{    "subb3",  {"rbrbwb",              0x83    } },
+{    "mulb2",  {"rbmb",                0x84    } },
+{    "mulb3",  {"rbrbwb",              0x85    } },
+{    "divb2",  {"rbmb",                0x86    } },
+{    "divb3",  {"rbrbwb",              0x87    } },
+{    "bisb2",  {"rbmb",                0x88    } },
+{    "bisb3",  {"rbrbwb",              0x89    } },
+{    "bicb2",  {"rbmb",                0x8a    } },
+{    "bicb3",  {"rbrbwb",              0x8b    } },
+{    "xorb2",  {"rbmb",                0x8c    } },
+{    "xorb3",  {"rbrbwb",              0x8d    } },
+{    "mnegb",  {"rbwb",                0x8e    } },
+{    "caseb",  {"rbrbrb",              0x8f    } },
+{    "movb",   {"rbwb",                0x90    } },
+{    "cmpb",   {"rbrb",                0x91    } },
+{    "mcomb",  {"rbwb",                0x92    } },
+{    "bitb",   {"rbrb",                0x93    } },
+{    "clrb",   {"wb",                  0x94    } },
+{    "tstb",   {"rb",                  0x95    } },
+{    "incb",   {"mb",                  0x96    } },
+{    "decb",   {"mb",                  0x97    } },
+{    "cvtbl",  {"rbwl",                0x98    } },
+{    "cvtbw",  {"rbww",                0x99    } },
+{    "movzbl", {"rbwl",                0x9a    } },
+{    "movzbw", {"rbww",                0x9b    } },
+{    "rotl",   {"rbrlwl",              0x9c    } },
+{    "acbb",   {"rbrbmbbw",            0x9d    } },
+{    "movab",  {"abwl",                0x9e    } },
+{    "pushab", {"ab",                  0x9f    } },
+{    "addw2",  {"rwmw",                0xa0    } },
+{    "addw3",  {"rwrwww",              0xa1    } },
+{    "subw2",  {"rwmw",                0xa2    } },
+{    "subw3",  {"rwrwww",              0xa3    } },
+{    "mulw2",  {"rwmw",                0xa4    } },
+{    "mulw3",  {"rwrwww",              0xa5    } },
+{    "divw2",  {"rwmw",                0xa6    } },
+{    "divw3",  {"rwrwww",              0xa7    } },
+{    "bisw2",  {"rwmw",                0xa8    } },
+{    "bisw3",  {"rwrwww",              0xa9    } },
+{    "bicw2",  {"rwmw",                0xaa    } },
+{    "bicw3",  {"rwrwww",              0xab    } },
+{    "xorw2",  {"rwmw",                0xac    } },
+{    "xorw3",  {"rwrwww",              0xad    } },
+{    "mnegw",  {"rwww",                0xae    } },
+{    "casew",  {"rwrwrw",              0xaf    } },
+{    "movw",   {"rwww",                0xb0    } },
+{    "cmpw",   {"rwrw",                0xb1    } },
+{    "mcomw",  {"rwww",                0xb2    } },
+{    "bitw",   {"rwrw",                0xb3    } },
+{    "clrw",   {"ww",                  0xb4    } },
+{    "tstw",   {"rw",                  0xb5    } },
+{    "incw",   {"mw",                  0xb6    } },
+{    "decw",   {"mw",                  0xb7    } },
+{    "bispsw", {"rw",                  0xb8    } },
+{    "bicpsw", {"rw",                  0xb9    } },
+{    "popr",   {"rw",                  0xba    } },
+{    "pushr",  {"rw",                  0xbb    } },
+{    "chmk",   {"rw",                  0xbc    } },
+{    "chme",   {"rw",                  0xbd    } },
+{    "chms",   {"rw",                  0xbe    } },
+{    "chmu",   {"rw",                  0xbf    } },
+{    "addl2",  {"rlml",                0xc0    } },
+{    "addl3",  {"rlrlwl",              0xc1    } },
+{    "subl2",  {"rlml",                0xc2    } },
+{    "subl3",  {"rlrlwl",              0xc3    } },
+{    "mull2",  {"rlml",                0xc4    } },
+{    "mull3",  {"rlrlwl",              0xc5    } },
+{    "divl2",  {"rlml",                0xc6    } },
+{    "divl3",  {"rlrlwl",              0xc7    } },
+{    "bisl2",  {"rlml",                0xc8    } },
+{    "bisl3",  {"rlrlwl",              0xc9    } },
+{    "bicl2",  {"rlml",                0xca    } },
+{    "bicl3",  {"rlrlwl",              0xcb    } },
+{    "xorl2",  {"rlml",                0xcc    } },
+{    "xorl3",  {"rlrlwl",              0xcd    } },
+{    "mnegl",  {"rlwl",                0xce    } },
+{    "casel",  {"rlrlrl",              0xcf    } },
+{    "movl",   {"rlwl",                0xd0    } },
+{    "cmpl",   {"rlrl",                0xd1    } },
+{    "mcoml",  {"rlwl",                0xd2    } },
+{    "bitl",   {"rlrl",                0xd3    } },
+{    "clrf",   {"wf",                  0xd4    } },
+{    "clrl",   {"wl",                  0xd4    } },
+{    "tstl",   {"rl",                  0xd5    } },
+{    "incl",   {"ml",                  0xd6    } },
+{    "decl",   {"ml",                  0xd7    } },
+{    "adwc",   {"rlml",                0xd8    } },
+{    "sbwc",   {"rlml",                0xd9    } },
+{    "mtpr",   {"rlrl",                0xda    } },
+{    "mfpr",   {"rlwl",                0xdb    } },
+{    "movpsl", {"wl",                  0xdc    } },
+{    "pushl",  {"rl",                  0xdd    } },
+{    "moval",  {"alwl",                0xde    } },
+{    "movaf",  {"afwl",                0xde    } },
+{    "pushal", {"al",                  0xdf    } },
+{    "pushaf", {"af",                  0xdf    } },
+{    "bbs",    {"rlabbb",              0xe0    } },
+{    "bbc",    {"rlabbb",              0xe1    } },
+{    "bbss",   {"rlabbb",              0xe2    } },
+{    "bbcs",   {"rlabbb",              0xe3    } },
+{    "bbsc",   {"rlabbb",              0xe4    } },
+{    "bbcc",   {"rlabbb",              0xe5    } },
+{    "bbssi",  {"rlabbb",              0xe6    } },
+{    "bbcci",  {"rlabbb",              0xe7    } },
+{    "blbs",   {"rlbb",                0xe8    } },
+{    "blbc",   {"rlbb",                0xe9    } },
+{    "ffs",    {"rlrbvbwl",            0xea    } },
+{    "ffc",    {"rlrbvbwl",            0xeb    } },
+{    "cmpv",   {"rlrbvbrl",            0xec    } },
+{    "cmpzv",  {"rlrbvbrl",            0xed    } },
+{    "extv",   {"rlrbvbwl",            0xee    } },
+{    "extzv",  {"rlrbvbwl",            0xef    } },
+{    "insv",   {"rlrlrbvb",            0xf0    } },
+{    "acbl",   {"rlrlmlbw",            0xf1    } },
+{    "aoblss", {"rlmlbb",              0xf2    } },
+{    "aobleq", {"rlmlbb",              0xf3    } },
+{    "sobgeq", {"mlbb",                0xf4    } },
+{    "sobgtr", {"mlbb",                0xf5    } },
+{    "cvtlb",  {"rlwb",                0xf6    } },
+{    "cvtlw",  {"rlww",                0xf7    } },
+{    "ashp",   {"rbrwabrbrwab",        0xf8    } },
+{    "cvtlp",  {"rlrwab",              0xf9    } },
+{    "callg",  {"abab",                0xfa    } },
+{    "calls",  {"rlab",                0xfb    } },
+{    "xfc",    {"",                    0xfc    } },
+                                        /* undefined opcodes here */
+{    "cvtdh",  {"rdwh",                0x32fd  } },
+{    "cvtgf",  {"rgwh",                0x33fd  } },
+{    "addg2",  {"rgmg",                0x40fd  } },
+{    "addg3",  {"rgrgwg",              0x41fd  } },
+{    "subg2",  {"rgmg",                0x42fd  } },
+{    "subg3",  {"rgrgwg",              0x43fd  } },
+{    "mulg2",  {"rgmg",                0x44fd  } },
+{    "mulg3",  {"rgrgwg",              0x45fd  } },
+{    "divg2",  {"rgmg",                0x46fd  } },
+{    "divg3",  {"rgrgwg",              0x47fd  } },
+{    "cvtgb",  {"rgwb",                0x48fd  } },
+{    "cvtgw",  {"rgww",                0x49fd  } },
+{    "cvtgl",  {"rgwl",                0x4afd  } },
+{    "cvtrgl", {"rgwl",                0x4bfd  } },
+{    "cvtbg",  {"rbwg",                0x4cfd  } },
+{    "cvtwg",  {"rwwg",                0x4dfd  } },
+{    "cvtlg",  {"rlwg",                0x4efd  } },
+{    "acbg",   {"rgrgmgbw",            0x4ffd  } },
+{    "movg",   {"rgwg",                0x50fd  } },
+{    "cmpg",   {"rgrg",                0x51fd  } },
+{    "mnegg",  {"rgwg",                0x52fd  } },
+{    "tstg",   {"rg",                  0x53fd  } },
+{    "emodg",  {"rgrwrgwlwg",          0x54fd  } },
+{    "polyg",  {"rgrwab",              0x55fd  } },
+{    "cvtgh",  {"rgwh",                0x56fd  } },
+                                        /* undefined opcodes here */
+{    "addh2",  {"rhmh",                0x60fd  } },
+{    "addh3",  {"rhrhwh",              0x61fd  } },
+{    "subh2",  {"rhmh",                0x62fd  } },
+{    "subh3",  {"rhrhwh",              0x63fd  } },
+{    "mulh2",  {"rhmh",                0x64fd  } },
+{    "mulh3",  {"rhrhwh",              0x65fd  } },
+{    "divh2",  {"rhmh",                0x66fd  } },
+{    "divh3",  {"rhrhwh",              0x67fd  } },
+{    "cvthb",  {"rhwb",                0x68fd  } },
+{    "cvthw",  {"rhww",                0x69fd  } },
+{    "cvthl",  {"rhwl",                0x6afd  } },
+{    "cvtrhl", {"rhwl",                0x6bfd  } },
+{    "cvtbh",  {"rbwh",                0x6cfd  } },
+{    "cvtwh",  {"rwwh",                0x6dfd  } },
+{    "cvtlh",  {"rlwh",                0x6efd  } },
+{    "acbh",   {"rhrhmhbw",            0x6ffd  } },
+{    "movh",   {"rhwh",                0x70fd  } },
+{    "cmph",   {"rhrh",                0x71fd  } },
+{    "mnegh",  {"rhwh",                0x72fd  } },
+{    "tsth",   {"rh",                  0x73fd  } },
+{    "emodh",  {"rhrwrhwlwh",          0x74fd  } },
+{    "polyh",  {"rhrwab",              0x75fd  } },
+{    "cvthg",  {"rhwg",                0x76fd  } },
+                                        /* undefined opcodes here */
+{    "clrh",   {"wh",                  0x7cfd  } },
+{    "clro",   {"wo",                  0x7cfd  } },
+{    "movo",   {"rowo",                0x7dfd  } },
+{    "movah",  {"ahwl",                0x7efd  } },
+{    "movao",  {"aowl",                0x7efd  } },
+{    "pushah", {"ah",                  0x7ffd  } },
+{    "pushao", {"ao",                  0x7ffd  } },
+                                        /* undefined opcodes here */
+{    "cvtfh",  {"rfwh",                0x98fd  } },
+{    "cvtfg",  {"rfwg",                0x99fd  } },
+                                        /* undefined opcodes here */
+{    "cvthf",  {"rhwf",                0xf6fd  } },
+{    "cvthd",  {"rhwd",                0xf7fd  } },
+                                        /* undefined opcodes here */
+{    "bugl",   {"rl",                  0xfdff  } },
+{    "bugw",   {"rw",                  0xfeff  } },
+                                        /* undefined opcodes here */
+
+{      ""       ,   ""          } /* empty is end sentinel */
+
+};                             /* votstrs */
+
+/* end: vax.opcode.h */
diff --git a/gdb/vax-pinsn.c b/gdb/vax-pinsn.c
new file mode 100644 (file)
index 0000000..4c159af
--- /dev/null
@@ -0,0 +1,240 @@
+/* Print vax instructions for GDB, the GNU debugger.
+   Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+
+#include "defs.h"
+#include "param.h"
+#include "symtab.h"
+#include "vax-opcode.h"
+
+/* Vax instructions are never longer than this.  */
+#define MAXLEN 62
+
+/* Number of elements in the opcode table.  */
+#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
+
+extern char *reg_names[];
+
+static unsigned char *print_insn_arg ();
+\f
+/* Print the vax instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn (memaddr, stream)
+     CORE_ADDR memaddr;
+     FILE *stream;
+{
+  unsigned char buffer[MAXLEN];
+  register int i;
+  register unsigned char *p;
+  register char *d;
+
+  read_memory (memaddr, buffer, MAXLEN);
+
+  for (i = 0; i < NOPCODES; i++)
+    if (votstrs[i].detail.code == buffer[0]
+       || votstrs[i].detail.code == *(unsigned short *)buffer)
+      break;
+
+  /* Handle undefined instructions.  */
+  if (i == NOPCODES)
+    {
+      fprintf (stream, "0%o", buffer[0]);
+      return 1;
+    }
+
+  fprintf (stream, "%s", votstrs[i].name);
+
+  /* Point at first byte of argument data,
+     and at descriptor for first argument.  */
+  p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
+  d = votstrs[i].detail.args;
+
+  if (*d)
+    fputc (' ', stream);
+
+  while (*d)
+    {
+      p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
+      d += 2;
+      if (*d)
+       fprintf (stream, ",");
+    }
+  return p - buffer;
+}
+
+static unsigned char *
+print_insn_arg (d, p, addr, stream)
+     char *d;
+     register char *p;
+     CORE_ADDR addr;
+     FILE *stream;
+{
+  register int regnum = *p & 0xf;
+  float floatlitbuf;
+
+  if (*d == 'b')
+    {
+      if (d[1] == 'b')
+       fprintf (stream, "0x%x", addr + *p++ + 1);
+      else
+       {
+         fprintf (stream, "0x%x", addr + *(short *)p + 2);
+         p += 2;
+       }
+    }
+  else
+    switch ((*p++ >> 4) & 0xf)
+      {
+      case 0:
+      case 1:
+      case 2:
+      case 3:                  /* Literal mode */
+       if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
+         {
+           *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
+           fprintf (stream, "$%f", floatlitbuf);
+         }
+       else
+         fprintf (stream, "$%d", p[-1] & 0x3f);
+       break;
+
+      case 4:                  /* Indexed */
+       p = (char *) print_insn_arg (d, p, addr + 1, stream);
+       fprintf (stream, "[%s]", reg_names[regnum]);
+       break;
+
+      case 5:                  /* Register */
+       fprintf (stream, reg_names[regnum]);
+       break;
+
+      case 7:                  /* Autodecrement */
+       fputc ('-', stream);
+      case 6:                  /* Register deferred */
+       fprintf (stream, "(%s)", reg_names[regnum]);
+       break;
+
+      case 9:                  /* Autoincrement deferred */
+       fputc ('@', stream);
+       if (regnum == PC_REGNUM)
+         {
+           fputc ('#', stream);
+           print_address (*(long *)p, stream);
+           p += 4;
+           break;
+         }
+      case 8:                  /* Autoincrement */
+       if (regnum == PC_REGNUM)
+         {
+           fputc ('#', stream);
+           switch (d[1])
+             {
+             case 'b':
+               fprintf (stream, "%d", *p++);
+               break;
+
+             case 'w':
+               fprintf (stream, "%d", *(short *)p);
+               p += 2;
+               break;
+
+             case 'l':
+               fprintf (stream, "%d", *(long *)p);
+               p += 4;
+               break;
+
+             case 'q':
+               fprintf (stream, "0x%x%08x", ((long *)p)[1], ((long *)p)[0]);
+               p += 8;
+               break;
+
+             case 'o':
+               fprintf (stream, "0x%x%08x%08x%08x",
+                        ((long *)p)[3], ((long *)p)[2],
+                        ((long *)p)[1], ((long *)p)[0]);
+               p += 16;
+               break;
+
+             case 'f':
+               if (INVALID_FLOAT (p, 4))
+                 fprintf (stream, "<<invalid float 0x%x>>", *(int *) p);
+               else
+                 fprintf (stream, "%f", *(float *) p);
+               p += 4;
+               break;
+
+             case 'd':
+               if (INVALID_FLOAT (p, 8))
+                 fprintf (stream, "<<invalid float 0x%x%08x>>",
+                          ((long *)p)[1], ((long *)p)[0]);
+               else
+                 fprintf (stream, "%f", *(double *) p);
+               p += 8;
+               break;
+
+             case 'g':
+               fprintf (stream, "g-float");
+               p += 8;
+               break;
+
+             case 'h':
+               fprintf (stream, "h-float");
+               p += 16;
+               break;
+
+             }
+         }
+       else
+         fprintf (stream, "(%s)+", reg_names[regnum]);
+       break;
+
+      case 11:                 /* Byte displacement deferred */
+       fputc ('@', stream);
+      case 10:                 /* Byte displacement */
+       if (regnum == PC_REGNUM)
+         print_address (addr + *p + 2, stream);
+       else
+         fprintf (stream, "%d(%s)", *p, reg_names[regnum]);
+       p += 1;
+       break;
+
+      case 13:                 /* Word displacement deferred */
+       fputc ('@', stream);
+      case 12:                 /* Word displacement */
+       if (regnum == PC_REGNUM)
+         print_address (addr + *(short *)p + 3, stream);
+       else
+         fprintf (stream, "%d(%s)", *(short *)p, reg_names[regnum]);
+       p += 2;
+       break;
+
+      case 15:                 /* Long displacement deferred */
+       fputc ('@', stream);
+      case 14:                 /* Long displacement */
+       if (regnum == PC_REGNUM)
+         print_address (addr + *(long *)p + 5, stream);
+       else
+         fprintf (stream, "%d(%s)", *(long *)p, reg_names[regnum]);
+       p += 4;
+      }
+
+  return (unsigned char *) p;
+}
diff --git a/gdb/vx-share/dbgRpcLib.h b/gdb/vx-share/dbgRpcLib.h
new file mode 100644 (file)
index 0000000..c420075
--- /dev/null
@@ -0,0 +1,28 @@
+/* dbgRpcLib.h - header file for remote debugging via rpc */
+
+/*
+modification history
+--------------------
+01b,04oct90,maf  added VX_BOOT_FILE_INQ.
+01a,05jun90,llk  extracted from xdr_dbx.h.
+*/
+
+#ifndef INCdbxRpcLibh
+#define INCdbxRpcLibh  1
+
+#define PROCESS_START          50
+#define PROCESS_WAIT           51
+#define VX_STATE_INQ           60
+#define VX_LOAD                        61
+#define VX_SYMBOL_INQ          62
+#define VX_BREAK_ADD           63
+#define VX_BREAK_DELETE                64
+#define VX_FP_INQUIRE          65
+#define VX_TASK_SUSPEND                66
+#define VX_CALL_FUNC           67
+#define VX_CONV_FROM_68881     68
+#define VX_CONV_TO_68881       69
+#define VX_BOOT_FILE_INQ       70
+#define        VX_SOURCE_STEP          71
+
+#endif INCdbxRpcLibh
diff --git a/gdb/vx-share/ptrace.h b/gdb/vx-share/ptrace.h
new file mode 100644 (file)
index 0000000..34801c7
--- /dev/null
@@ -0,0 +1,44 @@
+/*     @(#)ptrace.h 1.1 86/07/07 SMI   */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  borrowed.
+*/
+
+#ifndef _PTRACE_
+#define _PTRACE_
+
+/*
+ * Request values for the ptrace system call
+ */
+enum ptracereq {
+       PTRACE_TRACEME = 0,             /* 0, by tracee to begin tracing */
+       PTRACE_CHILDDONE = 0,           /* 0, tracee is done with his half */
+       PTRACE_PEEKTEXT,                /* 1, read word from text segment */
+       PTRACE_PEEKDATA,                /* 2, read word from data segment */
+       PTRACE_PEEKUSER,                /* 3, read word from user struct */
+       PTRACE_POKETEXT,                /* 4, write word into text segment */
+       PTRACE_POKEDATA,                /* 5, write word into data segment */
+       PTRACE_POKEUSER,                /* 6, write word into user struct */
+       PTRACE_CONT,                    /* 7, continue process */
+       PTRACE_KILL,                    /* 8, terminate process */
+       PTRACE_SINGLESTEP,              /* 9, single step process */
+       PTRACE_ATTACH,                  /* 10, attach to an existing process */
+       PTRACE_DETACH,                  /* 11, detach from a process */
+       PTRACE_GETREGS,                 /* 12, get all registers */
+       PTRACE_SETREGS,                 /* 13, set all registers */
+       PTRACE_GETFPREGS,               /* 14, get all floating point regs */
+       PTRACE_SETFPREGS,               /* 15, set all floating point regs */
+       PTRACE_READDATA,                /* 16, read data segment */
+       PTRACE_WRITEDATA,               /* 17, write data segment */
+       PTRACE_READTEXT,                /* 18, read text segment */
+       PTRACE_WRITETEXT,               /* 19, write text segment */
+       PTRACE_GETFPAREGS,              /* 20, get all fpa regs */
+       PTRACE_SETFPAREGS,              /* 21, set all fpa regs */
+};
+#endif !_PTRACE
diff --git a/gdb/vx-share/reg.h b/gdb/vx-share/reg.h
new file mode 100644 (file)
index 0000000..84658b7
--- /dev/null
@@ -0,0 +1,209 @@
+/*      @(#)reg.h 1.1 86/07/07 SMI      */
+
+/*
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  borrowed.
+*/
+
+#ifndef _REG_
+#define _REG_
+
+#ifdef I80960
+
+/* Intel 960 register values passed over the wire by RPC:  */
+
+struct regs
+{
+  int r_lreg[16];              /* local registers              */
+  int r_greg[16];              /* global registers             */
+  int r_pcw;                   /* process control word         */
+  int r_acw;                   /* arithmetic control word      */
+  int r_tcw;                   /* trace control word           */
+};
+
+#define FP_REG_SIZE    12
+
+struct fp_status {
+       char    fps_regs[4][FP_REG_SIZE];       /* floating point regs */
+};
+
+#else  /* For now, just 68000 */
+
+/*
+ * Location of the users' stored
+ * registers relative to R0.
+ * Usage is u.u_ar0[XX].
+ */
+#define        R0      (0)
+#define        R1      (1)
+#define        R2      (2)
+#define        R3      (3)
+#define        R4      (4)
+#define        R5      (5)
+#define        R6      (6)
+#define        R7      (7)
+#define        AR0     (8)
+#define        AR1     (9)
+#define        AR2     (10)
+#define        AR3     (11)
+#define        AR4     (12)
+#define        AR5     (13)
+#define        AR6     (14)
+#define        AR7     (15)
+#define        SP      (15)
+#define        PS      (16)
+#define        PC      (17)
+
+/*
+ * And now for something completely the same...
+ */
+#ifndef LOCORE
+struct regs {  
+       int     r_dreg[8];      /* data registers */
+#define r_r0   r_dreg[0]       /* r0 for portability */
+       int     r_areg[8];      /* address registers */
+#define r_sp   r_areg[7]       /* user stack pointer */
+       int     r_sr;           /* status register (actually a short) */
+#define        r_ps    r_sr
+       int     r_pc;           /* program counter */
+};
+
+struct stkfmt {
+       int     f_stkfmt : 4;   /* stack format */
+       int              : 2;
+       int     f_vector : 10;  /* vector offset */
+       short   f_beibase;      /* start of bus error info (if any) */
+};
+
+
+/*
+ * Struct for floating point registers and general state
+ * for the MC68881 (the sky fpp has no user visible state).
+ * If fps_flags == FPS_UNUSED, the other 68881 fields have no meaning.
+ * fps_code and fps_flags are software implemented fields.
+ * fps_flags is not used when set by user level programs,
+ * but changing fps_code has the side effect of changing u.u_code.
+ */
+
+typedef        struct ext_fp {
+       int     fp[3];
+} ext_fp;              /* extended 96-bit 68881 fp registers */
+
+struct fp_status {
+       ext_fp  fps_regs[8];            /* 68881 floating point regs */
+       int     fps_control;            /* 68881 control reg */
+       int     fps_status;             /* 68881 status reg */
+       int     fps_iaddr;              /* 68881 instruction address reg */
+       int     fps_code;               /* additional word for signals */
+       int     fps_flags;              /* r/o - unused, idle or busy */
+};
+#endif !LOCORE
+
+/*
+ * Values defined for `fps_flags'.
+ */
+#define        FPS_UNUSED      0               /* 68881 never used yet */
+#define        FPS_IDLE        1               /* 68881 instruction completed */
+#define        FPS_BUSY        2               /* 68881 instruction interrupted */
+
+/*
+ * The EXT_FPS_FLAGS() macro is used to convert a pointer to an
+ * fp_istate into a value to be used for the user visible state
+ * found in fps_flags.  As a speed optimization, this convertion
+ * is only done is required (e.g.  the PTRACE_GETFPREGS ptrace
+ * call or when dumping core) instead of on each context switch.
+ * The tests that we base the state on are that a fpis_vers of
+ * FPIS_VERSNULL means NULL state, else a fpis_bufsiz of FPIS_IDLESZ
+ * means IDLE state, else we assume BUSY state.
+ */
+#define        FPIS_VERSNULL   0x0
+#define        FPIS_IDLESIZE   0x18
+
+#define EXT_FPS_FLAGS(istatep) \
+       ((istatep)->fpis_vers == FPIS_VERSNULL ? FPS_UNUSED : \
+           (istatep)->fpis_bufsiz == FPIS_IDLESIZE ? FPS_IDLE : FPS_BUSY)
+
+#ifndef LOCORE
+/*
+ * Struct for the internal state of the MC68881
+ * Although the MC68881 can have a smaller maximum for
+ * internal state, we allow for more to allow for expansion.
+ */
+#define        FPIS_BUFSIZ     0xc0
+
+struct fp_istate {
+       unsigned char   fpis_vers;              /* version number */
+       unsigned char   fpis_bufsiz;            /* size of info in fpis_buf */
+       unsigned short  fpis_reserved;          /* reserved word */
+       unsigned char   fpis_buf[FPIS_BUFSIZ];  /* fpp internal state buffer */
+};
+
+/* 
+ * Structures for the status and data registers are defined here.
+ * Struct fpa_status are included in the u area.
+ * Struct fpa_regs is included in struct core.
+ */
+
+/* struct fpa_status is saved/restored during context switch */
+struct fpa_status {
+       unsigned int    fpas_state;     /* STATE, supervisor privileged reg */
+       unsigned int    fpas_imask;     /* IMASK */
+       unsigned int    fpas_load_ptr;  /* LOAD_PTR */
+       unsigned int    fpas_ierr;      /* IERR */
+       unsigned int    fpas_act_instr; /* pipe active instruction halves */
+       unsigned int    fpas_nxt_instr; /* pipe next instruction halves */
+       unsigned int    fpas_act_d1half;/* pipe active data first half */
+       unsigned int    fpas_act_d2half;/* pipe active data second half */
+       unsigned int    fpas_nxt_d1half;/* pipe next data first half */
+       unsigned int    fpas_nxt_d2half;/* pipe next data second half */
+       unsigned int    fpas_mode3_0;   /* FPA MODE3_0 register */
+       unsigned int    fpas_wstatus;   /* FPA WSTATUS register */
+};
+
+/* 
+ * Since there are 32 contexts supported by the FPA hardware,
+ * when we do context switch on the FPA, we don't save/restore
+ * the data registers between the FPA and the u area.
+ * If there are already 32 processes using the fpa concurrently,
+ * we give an error message to the 33rd process trying to use the fpa.
+ * (Hopefully there will not be this many processes using FPA concurrently.)
+ */
+
+#define FPA_NCONTEXTS          32
+#define FPA_NDATA_REGS         32
+
+typedef struct fpa_long {
+       int     fpl_data[2];
+} fpa_long;             /* 64 bit double precision registers */
+
+/* Struct fpa_regs is included in struct core. */
+struct fpa_regs {
+       unsigned int    fpar_flags; /* if zero, other fields are meaningless */
+        struct fpa_status      fpar_status;
+        fpa_long       fpar_data[FPA_NDATA_REGS];
+};
+
+/*
+ * The size of struct fpa_regs is changed from 141 ints in 3.0 to
+ * 77 ints in 3.x.  A pad of this size difference is added to struct core.
+ */
+#define CORE_PADLEN     64
+
+/*
+ * If there is going to be external FPU state then we must define the FPU
+ * variable
+ */
+struct fpu {
+        struct  fp_status f_fpstatus;   /* External FPP state, if any */
+        struct  fpa_regs f_fparegs;     /* FPA registers, if any */
+        int     f_pad[CORE_PADLEN];     /* see comment above */
+};
+
+#endif !LOCORE
+#endif /* !I80960 */
+#endif !_REG_
diff --git a/gdb/vx-share/vxTypes.h b/gdb/vx-share/vxTypes.h
new file mode 100644 (file)
index 0000000..3ebd7c6
--- /dev/null
@@ -0,0 +1,70 @@
+/* vxTypes.h - VxWorks type definition header */
+
+/* Copyright 1984-1990 Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01c,05oct90,shl  added copyright notice.
+                 made #endif ANSI style.
+01b,10aug90,dnw  added VOIDFUNCPTR
+01a,29may90,del  written.
+*/
+
+#ifndef INCvxTypesh
+#define INCvxTypesh
+
+/* The following stuff must NOT be included if this include file is used
+ * from assembly language.  Just #define ASMLANGUAGE before the include,
+ * to get rid of it.
+ */
+
+#ifndef ASMLANGUAGE
+
+/* vxWorks types */
+
+typedef        char            INT8;
+typedef        short           INT16;
+typedef        int             INT32;
+
+typedef        unsigned char   UINT8;
+typedef        unsigned short  UINT16;
+typedef        unsigned int    UINT32;
+
+typedef        unsigned char   UCHAR;
+typedef unsigned short USHORT;
+typedef        unsigned int    UINT;
+typedef unsigned long  ULONG;
+
+typedef        int             BOOL;
+typedef        int             VOID;
+typedef        int             STATUS; 
+typedef int            ARGINT;
+
+typedef int            (*FUNCPTR) ();      /* ptr to function returning int */
+typedef VOID           (*VOIDFUNCPTR) ();  /* ptr to function returning VOID */
+
+
+/* historical definitions - now obsolete */
+
+typedef char           TINY;           /* obsolete */
+typedef char           TBOOL;          /* obsolete */
+typedef unsigned char  UTINY;          /* obsolete */
+
+
+/* architecture dependent typedefs */
+
+#ifdef CPU_FAMILY
+
+#if    CPU_FAMILY==MC680X0
+typedef unsigned short INSTR;          /* word-aligned instructions */
+#endif /* CPU_FAMILY==MC680X0 */
+
+#if    CPU_FAMILY==SPARC
+typedef unsigned long INSTR;           /* 32 bit word-aligned instructions */
+#endif /* CPU_FAMILY==SPARC */
+
+#endif 
+
+#endif /* ASMLANGUAGE */
+#endif /* INCvxTypesh */
diff --git a/gdb/vx-share/vxWorks.h b/gdb/vx-share/vxWorks.h
new file mode 100644 (file)
index 0000000..483313e
--- /dev/null
@@ -0,0 +1,177 @@
+/* vxWorks.h - VxWorks standard definitions header */
+
+/* Copyright 1984-1990 Wind River Systems, Inc. */
+
+/*
+modification history
+--------------------
+01z,05oct90,shl  added copyright notice.
+                 made #endif ANSI style.
+01y,28sep90,del  added I960 defines.
+01x,29may90,del         moved types to vxTypes.h
+01w,09apr90,jcf  added timeout definitions.
+01v,24jan90,gae  moved network configuration flags here from makefile's.
+01u,01sep88,mcl  definition of INSTR dependent on processor family; added SPARC.
+          +gae  added MC680X0 and defined CPU_FAMILY.
+01t,08apr89,dnw  added ifdef to prevent inclusion of vxWorks.h more than once.
+01s,22jun88,dnw         moved READ, WRITE, and UPDATE back here from ioLib.h.
+01r,22apr88,gae  oops! forgot some #endif's in 01q.
+01q,12apr88,gae  removed QUICK & WAIT; added STD_{IN,OUT,ERR}.
+                fixed #define's of FALSE, TRUE, etc.
+                moved READ, WRITE, and UPDATE to ioLib.h.
+01p,04dec87,dnw  added undefine of MC68000 to get around Green Hills bug that
+                  pre-defines MC68000.
+01o,12nov87,ecs  added type ULONG.
+01n,08feb86,dnw  added types INSTR, UINT, USHORT.
+01m,14oct85,rdc  added BUS types.
+01l,16jul85,jlf  added conditional for NULL and EOF.
+01k,24jun85,rdc  installed condtional compile so we can include in
+                assembly language files.  See instructions below.
+                Added System type macro and CPU type macro.
+01j,13jun85,dnw  cleaned-up, removed more obsolete stuff to wrs.h
+01i,11sep84,jlf  changed name from wrs.h to vxWorks.h.  removed GLOBAL.
+01h,03jun84,dnw  removed IGNORE declaration.
+01g,09apr84,jlf  added MEMBER_SIZE macro.
+01f,14dec83,dnw  added MSB, LSB macros
+01e,17nov83,jlf  added STATUS type, for routines which return a status.
+01d,13jul83,dnw  added NELEMENTS macro
+01c,14May83,dnw  added OFFSET macro
+01b,17Feb83,dnw  added stuff from Whitesmiths std.h
+01a,15Feb83,dnw  written
+*/
+
+#ifndef INCvxWorksh
+#define INCvxWorksh
+
+#if    !defined(NULL) || (NULL!=0)
+#define NULL           0
+#endif 
+
+#if    !defined(EOF) || (EOF!=(-1))
+#define EOF            (-1)
+#endif 
+
+#if    !defined(FALSE) || (FALSE!=0)
+#define FALSE          0
+#endif 
+
+#if    !defined(TRUE) || (TRUE!=1)
+#define TRUE           1
+#endif 
+
+
+#define NONE           (-1)    /* for times when NULL won't do */
+#define EOS            '\0'    /* C string terminator */
+
+
+/* return status values */
+
+#define OK             0
+#define ERROR          (-1)
+
+/* timeout defines */
+
+#define NO_WAIT                0
+#define WAIT_FOREVER   (-1)
+
+/* low-level I/O input, output, error fd's */
+
+#define        STD_IN  0
+#define        STD_OUT 1
+#define        STD_ERR 2
+
+/* modes - must match O_RDONLY/O_WRONLY/O_RDWR in ioLib.h! */
+
+#define READ           0
+#define WRITE          1
+#define UPDATE         2
+
+/* SYSTEM types */
+
+#define V7             1       /* ATT version 7 */
+#define SYS_V          2       /* ATT System 5 */
+#define BSD_4_2                3       /* Berkeley BSD 4.2 */
+
+/* CPU types */
+
+/* The Green Hills compiler pre-defines "MC68000"!! */
+#ifdef MC68000
+#undef MC68000
+#endif 
+
+#define MC68000                1
+#define MC68010                2
+#define MC68020                3
+#define MC68030                4
+#define MC68040                5
+#define MC680X0                9
+
+#define SPARC          10
+
+#ifndef I960
+#define        I960            20
+#endif 
+
+#define        I960KB          21
+#define        I960CA          22
+
+#if    CPU==MC68000 || CPU==MC68010 || CPU==MC68020 || CPU==MC68030
+#define        CPU_FAMILY      MC680X0
+#endif /* CPU==MC68000 || CPU==MC68010 || CPU==MC68020 || CPU==MC68030 */
+
+#if    CPU==SPARC
+#define        CPU_FAMILY      SPARC
+#endif /* CPU==SPARC */
+
+#if    CPU==I960KB
+#define        CPU_FAMILY      I960
+#endif /*      CPU==I960KB */
+
+#if    CPU==I960CA
+#define        CPU_FAMILY      I960
+#endif /*      CPU==I960CA */
+
+/* BUS types */
+
+#define VME_BUS                1
+#define MULTI_BUS      2
+
+/* network configuration parameters */
+
+#define        INET            /* include internet protocols */
+#define        BSD     43      /* BSD 4.3 -like OS */
+#define        BSDDEBUG        /* turn on debug */
+#define        GATEWAY         /* tables to be initialized for gateway routing */
+
+/* common macros */
+
+#define MSB(x) (((x) >> 8) & 0xff)     /* most signif byte of 2-byte integer */
+#define LSB(x) ((x) & 0xff)            /* least signif byte of 2-byte integer*/
+
+#define OFFSET(structure, member)      /* byte offset of member in structure*/\
+               ((int) &(((structure *) 0) -> member))
+
+#define MEMBER_SIZE(structure, member) /* size of a member of a structure */\
+               (sizeof (((structure *) 0) -> member))
+
+#define NELEMENTS(array)               /* number of elements in an array */ \
+               (sizeof (array) / sizeof ((array) [0]))
+
+#define FOREVER        for (;;)
+
+#define max(x, y)      (((x) < (y)) ? (y) : (x))
+#define min(x, y)      (((x) < (y)) ? (x) : (y))
+
+
+/* storage class specifier definitions */
+
+#define FAST   register
+#define IMPORT extern
+#define LOCAL  static
+
+
+/* include typedefs - must come after CPU_FAMILY definitions above */
+
+#include "vxTypes.h"
+
+#endif /* INCvxWorksh */
diff --git a/gdb/vx-share/wait.h b/gdb/vx-share/wait.h
new file mode 100644 (file)
index 0000000..bb81f5b
--- /dev/null
@@ -0,0 +1,42 @@
+/* wait.h - header file for remote wait call */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  borrowed.
+*/
+
+/* Define how to access the structure that the wait system call stores.
+   On many systems, there is a structure defined for this.
+   But on vanilla-ish USG systems there is not.  */
+
+#ifndef HAVE_WAIT_STRUCT
+#define WAITTYPE int
+#define WIFSTOPPED(w) (((w)&0377) == 0177)
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#define WIFEXITED(w) (((w)&0377) == 0)
+#define WRETCODE(w) ((w) >> 8)
+#define WSTOPSIG(w) ((w) >> 8)
+#define WCOREDUMP(w) (((w)&0200) != 0)
+#define WTERMSIG(w) ((w) & 0177)
+#define WSETEXIT(w, status) ((w) = (status))
+#define WSETSTOP(w,sig)  ((w) = (0177 | ((sig) << 8)))
+#else
+#if FALSE
+#ifndef ORIG
+
+/* don't include sys/wait.h */
+
+#else ORIG
+#include <sys/wait.h>
+#endif ORIG
+#endif FALSE
+#define WAITTYPE union wait
+#define WRETCODE(w) (w).w_retcode
+#define WSTOPSIG(w) (w).w_stopsig
+#define WCOREDUMP(w) (w).w_coredump
+#define WTERMSIG(w) (w).w_termsig
+#define WSETEXIT(w, status) ((w).w_status = (status))
+#define WSETSTOP(w,sig)  \
+  ((w).w_stopsig = (sig), (w).w_coredump = 0, (w).w_termsig = 0177)
+#endif
diff --git a/gdb/vx-share/xdr_ld.c b/gdb/vx-share/xdr_ld.c
new file mode 100644 (file)
index 0000000..4935c34
--- /dev/null
@@ -0,0 +1,82 @@
+/* xdr_ld.c  - xdr routines for remote dbx interface to VxWorks  */
+
+/* Copyright 1984,1985,1986,1987,1988,1989 Wind River Systems, Inc. */
+/*extern char copyright_wind_river[]; static char *copyright=copyright_wind_river;*/
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  extracted from xdr_dbx.c.
+*/
+
+/*
+DESCRIPTION
+This module contains the eXternal Data Representation (XDR) routines
+for object files that are downloaded to VxWorks.  They are used by
+remote debuggers that use RPC (such as dbxWorks and vxGdb).
+*/
+
+#include "vxWorks.h"
+#include "rpc/rpc.h"
+#include "xdr_ld.h"
+
+/* forward declarations */
+
+bool_t xdr_String();           /* xdr routine for argument list */
+
+
+/*******************************************************************************
+*
+* xdr_String - xdr routine for strings.
+* 
+* Used by xdr_arg_info to handle the actual argument
+* strings.  normally calls xdr_string - but does something 
+* reasonable encode of null pointer.
+*/
+
+bool_t xdr_String (xdrs, strp)
+    XDR        *xdrs;
+    char **strp;
+
+    {
+    if ((*strp == NULL) & (xdrs->x_op == XDR_ENCODE)) 
+       return(FALSE);
+    else 
+       return(xdr_string(xdrs, strp, MAXSTRLEN));
+    }
+/*******************************************************************************
+*
+* xdr_ldfile - xdr routine for a single element in the load table 
+*/
+
+bool_t xdr_ldfile (xdrs, objp)
+    XDR *xdrs;
+    ldfile *objp;
+
+    {
+    if (! xdr_String(xdrs, &objp->name)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->txt_addr)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->data_addr)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->bss_addr)) 
+       return(FALSE);
+
+    return(TRUE);
+    }
+/*******************************************************************************
+*
+* xdr_ldtabl -
+*
+* xdr routine for a list of files and load addresses loaded into VxWorks.
+*/
+
+bool_t xdr_ldtabl (xdrs,objp)
+    XDR *xdrs;
+    ldtabl *objp;
+
+    {
+    return (xdr_array (xdrs, (char *) &objp->tbl_ent, (UINT *) &objp->tbl_size, 
+           MAXTBLSZ, sizeof(ldfile), xdr_ldfile));
+    }
diff --git a/gdb/vx-share/xdr_ld.h b/gdb/vx-share/xdr_ld.h
new file mode 100644 (file)
index 0000000..8021ccf
--- /dev/null
@@ -0,0 +1,41 @@
+/* xdr_ld.h - xdr for additional dbxWorks structures */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  extracted from xdr_dbx.h.
+*/
+
+#ifndef INCxdrldh
+#define INCxdrldh
+
+#define MAXSTRLEN 256
+#define MAXTBLSZ 100
+
+/*
+ * structure used to pass back the information for a single file
+ * loaded in VxWorks
+ */
+struct ldfile {
+       char    *name;
+       int     txt_addr;
+       int     data_addr;
+       int     bss_addr;
+};
+typedef struct ldfile ldfile;
+
+/*
+ * structure used to return a list of all files loaded over to 
+ * VxWorks. (VX_STATE_INQ return)
+ */
+struct ldtabl {
+       u_int tbl_size;
+       ldfile *tbl_ent;
+};
+typedef struct ldtabl ldtabl;
+
+
+bool_t xdr_ldfile();
+bool_t xdr_ldtabl();
+
+#endif INCxdrldh
diff --git a/gdb/vx-share/xdr_ptrace.c b/gdb/vx-share/xdr_ptrace.c
new file mode 100644 (file)
index 0000000..08813fc
--- /dev/null
@@ -0,0 +1,171 @@
+/* xdr_ptrace.c  - xdr routines for remote ptrace calls */
+/* Copyright 1984,1985,1986,1987,1988,1989 Wind River Systems, Inc. */
+/* extern char copyright_wind_river[]; static char *copyright=copyright_wind_river;*/
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  extracted from xdr_ptrace.h, version 01c.
+*/
+
+#include <vxWorks.h>
+#include <rpc/rpc.h>
+#include <xdr_ptrace.h>
+
+#define MAX_LEN 32000
+
+/********************************************************************
+*
+* xdr_regs_ptr -
+*
+* xdr routine to get regs* branch of discriminated union ptrace_info
+*
+*/
+
+LOCAL bool_t xdr_regs_ptr(xdrs,objp)
+    XDR *xdrs;
+    struct regs **objp;
+    {
+    return (xdr_pointer(xdrs, (char **) objp, sizeof(struct regs), xdr_regs));
+    } /* xdr_regs_ptr */
+
+/********************************************************************
+*
+* xdr_fp_status_ptr -
+*
+* xdr routine for fp_status * branch of discrimanated union
+*
+*/
+
+LOCAL bool_t xdr_fp_status_ptr(xdrs,objp)
+    XDR *xdrs;
+    struct fp_status **objp;
+    {
+    return(xdr_pointer(xdrs, (char **) objp, sizeof(struct fp_status), 
+           xdr_fp_status));
+    } /* xdr_fp_status_ptr */
+
+#ifndef I80960
+/********************************************************************
+*
+* xdr_fpa_regs_ptr - 
+*
+* xdr routine for fpa_regs* branch of ptrace_info
+*
+*/
+
+LOCAL bool_t xdr_fpa_regs_ptr(xdrs,objp)
+    XDR *xdrs;
+    struct fpa_regs **objp;
+    {
+    if (! xdr_pointer(xdrs, (char **) objp, sizeof(struct fpa_regs), 
+                     xdr_fpa_regs)) 
+       return(FALSE);
+    else
+       return(TRUE);
+    } /* xdr_fpa_regs_ptr */
+#endif
+
+/********************************************************************
+*
+* xdr_c_bytes_ptr -
+*
+* xdr routine for counted bytes branch of ptrace_info
+*
+*/
+
+LOCAL bool_t xdr_c_bytes_ptr(xdrs,objp)
+    XDR *xdrs;
+    C_bytes **objp;
+    {
+    return(xdr_pointer(xdrs, (char **) objp, sizeof(C_bytes), xdr_c_bytes));
+    } /* xdr_c_bytes_ptr */
+
+/********************************************************************
+*
+* xdr_ptrace_info -
+*
+* xdr routine for discriminated union ptrace_info
+*
+*/
+
+bool_t xdr_ptrace_info(xdrs,objp)
+    XDR *xdrs;
+    Ptrace_info *objp;
+    {
+    static struct xdr_discrim choices[] = 
+       {
+           { (int) REGS, xdr_regs_ptr },
+           { (int) FPREGS, xdr_fp_status_ptr },
+#ifndef I80960
+           { (int) FPAREGS, xdr_fpa_regs_ptr },
+#endif
+           { (int) DATA, xdr_c_bytes_ptr },
+           { __dontcare__, NULL }
+       };
+
+    return(xdr_union(xdrs, (enum_t *) &objp->ttype, 
+       (char *) &objp->more_data, choices, xdr_void));
+    } /* xdr_ptrace_info */
+
+/********************************************************************
+*
+* xdr_rptrace - 
+*
+* xdr routine for remote ptrace data into server
+*
+*/
+
+bool_t xdr_rptrace(xdrs,objp)
+    XDR *xdrs;
+    Rptrace *objp;
+    {
+    if (! xdr_int(xdrs, &objp->pid)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->data)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->addr)) 
+       return(FALSE);
+    if (! xdr_ptrace_info(xdrs, &objp->info)) 
+       return(FALSE);
+
+    return(TRUE);
+    } /* xdr_rptrace */
+
+/********************************************************************
+*
+* xdr_ptrace_return - 
+*
+* xdr routine for remote ptrace data returned by server
+*
+*/
+
+bool_t xdr_ptrace_return(xdrs, objp)
+    XDR *xdrs;
+    Ptrace_return *objp;
+    {
+    if (! xdr_int(xdrs, &objp->status)) 
+       return(FALSE);
+    if (! xdr_int(xdrs, &objp->errno)) 
+       return(FALSE);
+    if (! xdr_ptrace_info(xdrs, &objp->info)) 
+       return(FALSE);
+
+    return(TRUE);
+    } /* xdr_ptrace_return */  
+
+/********************************************************************
+*
+* xdr_c_bytes -
+*
+* xdr routine for counted bytes  
+*
+*/
+bool_t xdr_c_bytes(xdrs,objp)
+    XDR *xdrs;
+    C_bytes *objp;
+    {
+    return(xdr_bytes(xdrs, &objp->bytes, (u_int *) &objp->len, MAX_LEN));
+    } /* xdr_c_bytes */
+
diff --git a/gdb/vx-share/xdr_ptrace.h b/gdb/vx-share/xdr_ptrace.h
new file mode 100644 (file)
index 0000000..1fe7ab4
--- /dev/null
@@ -0,0 +1,68 @@
+/* xdr_ptrace.h - xdr header for remote ptrace structures */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  extracted from xdr_ptrace.h.
+*/
+
+
+#include "xdr_regs.h"
+#include "reg.h"
+
+/*
+ *  Counted byte structure used by READ/WRITE TEXT/DATA
+ */
+struct c_bytes {
+       u_int   len;
+       caddr_t bytes;
+};
+typedef struct c_bytes C_bytes;
+
+/*
+ * enum for discriminated union ptrace_info
+ */
+enum ptype {
+       NOINFO = 0,             /* no additional infomation     */
+       REGS = 1,               /* regs         (SETREGS)       */
+       FPREGS = 2,             /* fp_status    (SETFPREGS)     */
+       FPAREGS = 3,            /* fpa_regs     (SETFPAREGS)    */
+       DATA = 4,               /* c_bytes      (WRITETEXT/DATA)*/
+};
+typedef enum ptype ptype;
+
+/*
+ * discrimnated union for passing additional data to be 
+ * written to the debugged process. With the exception of
+ * c_bytes, the structures are defined in <machine/reg.h>
+ */
+struct ptrace_info {
+       ptype   ttype;
+       caddr_t more_data;      
+};
+typedef struct ptrace_info Ptrace_info;
+
+/*
+ * structure passed to server on all remote ptrace calls
+ */
+struct rptrace {
+       int     pid;
+       int     data;
+       int     addr;   /* FIX! this really should be caddr_t or something */
+       Ptrace_info     info;
+};
+typedef struct rptrace Rptrace;
+/*
+ * structure returned by server on all remote ptrace calls
+ */
+struct ptrace_return {
+       int status;
+       int errno;
+       Ptrace_info     info;
+};
+typedef struct ptrace_return Ptrace_return;
+
+bool_t xdr_c_bytes();
+bool_t xdr_ptrace_info();
+bool_t xdr_rptrace();
+bool_t xdr_ptrace_return();
diff --git a/gdb/vx-share/xdr_rdb.c b/gdb/vx-share/xdr_rdb.c
new file mode 100644 (file)
index 0000000..3c70fbf
--- /dev/null
@@ -0,0 +1,207 @@
+/* xdr_rdb.c  - xdr routines for Remote Debug interface to VxWorks  */
+
+/*
+modification history
+--------------------
+01a,21mar90,llk  created using modification 01d of xdr_dbx.c.
+*/
+
+/*
+DESCRIPTION
+This module contains the eXternal Data Representation (XDR) routines
+for the RDB interface for VxWorks.
+*/
+
+#include "vxWorks.h"
+#include <rpc/rpc.h>
+#include "xdr_rdb.h"
+
+/* forward declarations */
+
+bool_t
+xdr_arg_type(xdrs, objp)
+        XDR *xdrs;
+        arg_type *objp;
+{
+        if (!xdr_enum(xdrs, (enum_t *)objp)) {
+                return (FALSE);
+        }
+        return (TRUE);
+}
+
+bool_t
+xdr_arg_value(xdrs, objp)
+        XDR *xdrs;
+        arg_value *objp;
+{
+        if (!xdr_arg_type(xdrs, &objp->type)) {
+                return (FALSE);
+        }
+        switch (objp->type) {
+        case T_BYTE:
+                if (!xdr_char(xdrs, &objp->arg_value_u.v_byte)) {
+                        return (FALSE);
+                }
+                break;
+        case T_WORD:
+                if (!xdr_short(xdrs, &objp->arg_value_u.v_word)) {
+                        return (FALSE);
+                }
+                break;
+        case T_INT:
+                if (!xdr_int(xdrs, &objp->arg_value_u.v_int)) {
+                        return (FALSE);
+                }
+                break;
+        case T_FLOAT:
+                if (!xdr_float(xdrs, &objp->arg_value_u.v_fp)) {
+                        return (FALSE);
+                }
+                break;
+        case T_DOUBLE:
+                if (!xdr_double(xdrs, &objp->arg_value_u.v_dp)) {
+                        return (FALSE);
+                }
+                break;
+        case T_UNKNOWN:
+                break;
+        }
+        return (TRUE);
+}
+
+bool_t
+xdr_func_call(xdrs, objp)
+        XDR *xdrs;
+        func_call *objp;
+{
+        if (!xdr_int(xdrs, &objp->func_addr)) {
+                return (FALSE);
+        }
+        if (!xdr_array(xdrs, (char **)&objp->args.args_val, (u_int *)&objp->args.args_len, MAX_FUNC_ARGS, sizeof(arg_value), xdr_arg_value)) {
+                return (FALSE);
+        }
+        return (TRUE);
+}
+
+bool_t
+xdr_arg_one(xdrs, objp)
+        XDR *xdrs;
+        arg_one *objp;
+{
+        if (!xdr_string(xdrs, objp, MAX_ARG_LEN)) {
+                return (FALSE);
+        }
+        return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_arg_array(xdrs, objp)
+        XDR *xdrs;
+        arg_array *objp;
+{
+        if (!xdr_array(xdrs, (char **)&objp->arg_array_val, (u_int *)&objp->arg_array_len, MAX_ARG_CNT, sizeof(arg_one), xdr_arg_one)) {
+                return (FALSE);
+        }
+        return (TRUE);
+}
+
+/*********************************************************************
+*
+* xdr_EVENT_TYPE -
+*
+*/
+
+bool_t xdr_EVENT_TYPE(xdrs, objp)
+    XDR *xdrs;
+    EVENT_TYPE *objp;
+
+    {
+    if (!xdr_enum (xdrs, (enum_t *) objp))
+       return (FALSE);
+    return (TRUE);
+    }
+
+/*********************************************************************
+*
+* xdr_RDB_EVENT -
+*
+*/
+
+bool_t xdr_RDB_EVENT (xdrs, objp)
+    XDR *xdrs;
+    RDB_EVENT *objp;
+
+    {
+    if (!xdr_int (xdrs, &objp->status))
+       return (FALSE);
+    if (!xdr_int (xdrs, &objp->taskId))
+       return (FALSE);
+    if (!xdr_EVENT_TYPE (xdrs, &objp->eventType))
+       return (FALSE);
+    if (!xdr_int (xdrs, &objp->sigType))
+       return (FALSE);
+    return (TRUE);
+    }        
+
+/*********************************************************************
+*
+* xdr_TASK_START -
+*
+*/
+
+bool_t
+xdr_TASK_START (xdrs, objp)
+    XDR *xdrs;
+    TASK_START *objp;
+
+    {
+    if (!xdr_int (xdrs, &objp->status))
+       return (FALSE);
+    if (!xdr_int (xdrs, &objp->pid))
+       return (FALSE);
+    return (TRUE);
+    }
+
+
+/*********************************************************************
+*
+* xdr_SYMBOL_ADDR -
+*
+*/
+
+bool_t
+xdr_SYMBOL_ADDR (xdrs, objp)
+    XDR *xdrs;
+    SYMBOL_ADDR *objp;
+
+    {
+    if (!xdr_int (xdrs, &objp->status))
+       return (FALSE);
+    if (!xdr_u_int (xdrs, &objp->addr))
+       return (FALSE);
+    return (TRUE);
+    }
+
+/*********************************************************************
+*
+* xdr_SOURCE_STEP -
+*
+*/
+
+bool_t
+xdr_SOURCE_STEP (xdrs, objp)
+    XDR *xdrs;
+    SOURCE_STEP *objp;
+
+    {
+    if (!xdr_int (xdrs, &objp->taskId))
+       return (FALSE);
+    if (!xdr_u_int (xdrs, &objp->startAddr))
+       return (FALSE);
+    if (!xdr_u_int (xdrs, &objp->endAddr))
+       return (FALSE);
+    return (TRUE);
+    }
diff --git a/gdb/vx-share/xdr_rdb.h b/gdb/vx-share/xdr_rdb.h
new file mode 100644 (file)
index 0000000..eebec43
--- /dev/null
@@ -0,0 +1,132 @@
+/* xdr_rdb.h - xdr for additional rdb structures */
+
+/*
+modification history
+--------------------
+01a,23may90,llk  created using xdr_dbx.h.
+                added arg_array to replace arg_info.  arg_info had
+                  MAXNCMDARGS (= 100) as the max limit of char strings,
+                  but it should be MAX_TASK_ARGS (= 10).
+*/
+
+#ifndef INCxdrrdbh
+#define INCxdrrdbh
+
+enum arg_type {
+        T_UNKNOWN = 0,
+        T_BYTE = 1,
+        T_WORD = 2,
+        T_INT = 3,
+        T_FLOAT = 4,
+        T_DOUBLE = 5,
+};
+typedef enum arg_type arg_type;
+bool_t xdr_arg_type();
+
+
+struct arg_value {
+        arg_type type;
+        union {
+                char v_byte;
+                short v_word;
+                int v_int;
+                float v_fp;
+                double v_dp;
+        } arg_value_u;
+};
+typedef struct arg_value arg_value;
+bool_t xdr_arg_value();
+
+struct func_call {
+        int func_addr;
+        struct {
+                u_int args_len;
+                arg_value *args_val;
+        } args;
+};
+typedef struct func_call func_call;
+bool_t xdr_func_call();
+
+
+typedef char *arg_one;
+bool_t xdr_arg_one();
+
+
+typedef struct {
+        u_int arg_array_len;
+        arg_one *arg_array_val;
+} arg_array;
+bool_t xdr_arg_array();
+
+
+/*
+ * Structures used to pass structures required for
+ * process control but not part of the standard ptrace interface
+ */
+
+/*
+ * arg_info is used to pass arguments into process start
+ */
+struct arg_info {
+       int rargc;
+       char **rargv;
+};
+typedef struct arg_info Arg_info;
+
+
+enum EVENT_TYPE {
+        EVENT_BREAK = 0,
+        EVENT_STOP = 1,
+        EVENT_EXIT = 2,
+        EVENT_BUS_ERR = 3,
+        EVENT_SUSPEND = 4,
+        EVENT_ZERO_DIV = 5,
+        EVENT_SIGNAL = 6,
+        EVENT_START = 7,
+};
+typedef enum EVENT_TYPE EVENT_TYPE;
+
+
+struct RDB_EVENT {
+       int status;
+       int taskId;
+        EVENT_TYPE eventType;
+        int sigType;
+};
+typedef struct RDB_EVENT RDB_EVENT;
+
+
+struct TASK_START {
+        int status;
+        int pid;
+};
+typedef struct TASK_START TASK_START;
+
+
+struct SYMBOL_ADDR {
+        int status;
+        u_int addr;
+};
+typedef struct SYMBOL_ADDR SYMBOL_ADDR;
+
+struct SOURCE_STEP {
+       int taskId;
+       u_int startAddr;
+       u_int endAddr;
+};
+typedef struct SOURCE_STEP SOURCE_STEP;
+
+#define MAX_ARG_CNT 10
+#define MAX_FUNC_ARGS 100
+#define MAX_ARG_LEN   100
+
+bool_t xdr_arg_info();
+bool_t xdr_EVENT_TYPE();
+bool_t xdr_RDB_EVENT();
+bool_t xdr_TASK_START();
+bool_t xdr_SYMBOL_ADDR();
+bool_t xdr_SOURCE_STEP();
+
+#define RDBPROG (u_long) 0x44444444
+#define RDBVERS (u_long) 1
+#endif INCxdrrdbh
diff --git a/gdb/vx-share/xdr_regs.c b/gdb/vx-share/xdr_regs.c
new file mode 100644 (file)
index 0000000..9152423
--- /dev/null
@@ -0,0 +1,216 @@
+/* xdr_regs.c - xdr routines for 68k registers */
+
+/* Copyright 1984,1985,1986,1987,1988,1989 Wind River Systems, Inc. */
+
+/*
+DESCRIPTION
+This module contains the eXternal Data Representation (XDR) routines
+for the GDB interface for VxWorks.
+*/
+
+#include <vxWorks.h>
+#include <rpc/rpc.h>
+#include <reg.h>
+#include <xdr_regs.h>
+
+
+#ifdef I80960
+/*******************************************************************************
+*
+* xdr_regs - xdr routine for i960 registers
+*/
+
+bool_t xdr_regs (xdrs, objp)
+    XDR *xdrs;
+    struct regs *objp;
+
+    {
+    if (! xdr_opaque(xdrs, (char *) objp->r_lreg, 16 * sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) objp->r_greg, 16 * sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) &objp->r_pcw, sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) &objp->r_acw, sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) &objp->r_tcw, sizeof(int)))
+       return(FALSE);
+
+    return(TRUE);
+    }
+
+/*******************************************************************************
+*
+* xdr_fp_status - xdr routine for i960 floating point registers
+*/
+
+bool_t xdr_fp_status (xdrs, objp)
+    XDR *xdrs;
+    struct fp_status *objp;
+
+    {
+    unsigned int size = 4 * FP_REG_SIZE;
+
+    /* We use xdr_bytes to indicate how many bytes of FP regs there are! */
+    if (! xdr_bytes (xdrs, (char *) objp->fps_regs, &size, 4 * FP_REG_SIZE))
+       return (FALSE);
+    return (TRUE);
+    }
+
+/*******************************************************************************
+*
+* xdr_ext_fp - xdr for a single fp register
+*/
+
+bool_t xdr_ext_fp (xdrs, objp)
+    XDR *xdrs;
+    char *objp;
+
+    {
+    unsigned int size = FP_REG_SIZE;
+
+    if (! xdr_bytes (xdrs, objp, &size, FP_REG_SIZE)) 
+       return(FALSE);
+
+    return(TRUE);
+    }
+#else  /* Must be 68K if it isn't i960 -- for now.  FIXME!  */
+
+/*******************************************************************************
+*
+* xdr_regs - xdr routine for 68k registers
+*/
+
+bool_t xdr_regs (xdrs, objp)
+    XDR *xdrs;
+    struct regs *objp;
+
+    {
+    if (! xdr_opaque(xdrs, (char *) objp->r_dreg, 8 * sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) objp->r_areg, 8 * sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) &objp->r_sr, sizeof(int)))
+       return(FALSE);
+    if (! xdr_opaque(xdrs, (char *) &objp->r_pc, sizeof(int)))
+       return(FALSE);
+
+    return(TRUE);
+    }
+
+/*******************************************************************************
+*
+* xdr_ext_fp - xdr for a single fp register
+*/
+
+bool_t xdr_ext_fp (xdrs, objp)
+    XDR *xdrs;
+    ext_fp *objp;
+
+    {
+    if (! xdr_vector(xdrs, (char *) objp->fp, 3, sizeof(int), xdr_int)) 
+       return(FALSE);
+
+    return(TRUE);
+    }
+/*******************************************************************************
+*
+* xdr_fp_status - xdr routine for floating point registers
+*/
+
+bool_t xdr_fp_status (xdrs, objp)
+    XDR *xdrs;
+    struct fp_status *objp;
+
+    {
+    if (! xdr_vector (xdrs, (char *) objp->fps_regs, 8, 
+               sizeof(ext_fp), xdr_ext_fp))
+       return (FALSE);
+    if (! xdr_int (xdrs, &objp->fps_control)) 
+       return (FALSE);
+    if (! xdr_int (xdrs, &objp->fps_status)) 
+       return (FALSE);
+    if (! xdr_int (xdrs, &objp->fps_iaddr)) 
+       return (FALSE);
+    if (! xdr_int (xdrs, &objp->fps_code)) 
+       return (FALSE);
+    if (! xdr_int (xdrs, &objp->fps_flags)) 
+       return (FALSE);
+
+    return (TRUE);
+    }
+/*******************************************************************************
+*
+* xdr_fpa_status - xdr for fpa status
+*/
+
+bool_t xdr_fpa_status (xdrs, objp)
+    XDR *xdrs;
+    struct fpa_status *objp;
+
+    {
+    if (! xdr_u_int (xdrs, &objp->fpas_state)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_imask)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_load_ptr)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_ierr)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_act_instr)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_nxt_instr)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_act_d1half)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_act_d2half)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_nxt_d1half)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_nxt_d2half)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_mode3_0)) 
+       return (FALSE);
+    if (! xdr_u_int (xdrs, &objp->fpas_wstatus)) 
+       return (FALSE);
+
+    return (TRUE);
+    }
+/*******************************************************************************
+*
+* xdr_fpa_long - xdr for fpa data register
+*/
+
+bool_t xdr_fpa_long (xdrs,objp)
+    XDR *xdrs;
+    fpa_long *objp;
+
+    {
+    if (! xdr_vector (xdrs, (char *) objp->fpl_data, 2, sizeof(int), xdr_int)) 
+       return (FALSE);
+
+    return (TRUE);
+    }
+/*******************************************************************************
+*
+* xdr_fpa_regs - xdr for fpa_regs 
+*/
+
+bool_t xdr_fpa_regs (xdrs, objp)
+    XDR *xdrs;
+    struct fpa_regs *objp;
+
+    {
+    if (! xdr_u_int (xdrs, &objp->fpar_flags)) 
+       return (FALSE);
+    if (! xdr_fpa_status (xdrs, &objp->fpar_status)) 
+       return (FALSE);
+    if (! xdr_vector (xdrs, (char *) objp->fpar_data, 
+                   FPA_NDATA_REGS, sizeof(fpa_long), xdr_fpa_long)) 
+       return (FALSE);
+
+    return (TRUE);
+    }
+
+#endif /* I80960 */
+
diff --git a/gdb/vx-share/xdr_regs.h b/gdb/vx-share/xdr_regs.h
new file mode 100644 (file)
index 0000000..c829d64
--- /dev/null
@@ -0,0 +1,16 @@
+/* xdr_regs.h - xdr header for 68k registers */
+
+/*
+modification history
+--------------------
+01a,05jun90,llk  extracted from xdr_regs.h.
+*/
+
+/* xdr structures are defined in reg.h (a bad place for them, i might add) */
+
+bool_t xdr_regs();
+bool_t xdr_ext_fp();
+bool_t xdr_fp_status();
+bool_t xdr_fpa_status();
+bool_t xdr_fpa_long();
+bool_t xdr_fpa_regs();
diff --git a/gdb/xm-3b1.h b/gdb/xm-3b1.h
new file mode 100644 (file)
index 0000000..6efef40
--- /dev/null
@@ -0,0 +1,87 @@
+/* Parameters for execution on a 3b1.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#define HAVE_TERMIO
+#define USG
+
+#define MAXPATHLEN 200
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR 0x70000
+
+#define REGISTER_U_ADDR(addr, blockend, regno)         \
+{ addr = blockend + regno * 4; }
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+
+#endif
diff --git a/gdb/xm-altos.h b/gdb/xm-altos.h
new file mode 100644 (file)
index 0000000..3a4dc5f
--- /dev/null
@@ -0,0 +1,208 @@
+/* Definitions to make GDB run on an Altos 3068 (m68k running SVR2)
+   Copyright (C) 1987,1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* The altos support would make a good base for a port to other USGR2 systems
+   (like the 3b1 and the Convergent miniframe).  */
+
+/* This is only needed in one file, but it's cleaner to put it here than
+   putting in more #ifdef's.  */
+#include <sys/page.h>
+#include <sys/net.h>
+
+#define USG
+
+#define HAVE_TERMIO
+
+#define CBREAK XTABS   /* It takes all kinds... */
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_OK 0
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN (1024)
+#endif
+
+/* Get sys/wait.h ie. from a Sun and edit it a little (mc68000 to m68k) */
+/* Why bother?  */
+#if 0
+#define HAVE_WAIT_STRUCT
+#endif
+
+#define vfork fork
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR 0x1fbf000
+
+#define REGISTER_U_ADDR(addr, blockend, regno)         \
+{      if (regno <= SP_REGNUM) \
+         addr = blockend + regno * 4; \
+       else if (regno == PS_REGNUM) \
+         addr = blockend + regno * 4 + 4; \
+       else if (regno == PC_REGNUM) \
+         addr = blockend + regno * 4 + 2; \
+}
+
+#define REGISTER_ADDR(u_ar0, regno)                                    \
+  (((regno) < PS_REGNUM)                                               \
+   ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)])     \
+   : (((regno) == PS_REGNUM)                                           \
+      ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS))                \
+      : (&((struct exception_stack *) (u_ar0))->e_PC)))
+
+#define FP_REGISTER_ADDR(u, regno)                                     \
+  (((char *)                                                           \
+    (((regno) < FPC_REGNUM)                                            \
+     ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
+     : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)])))   \
+   - ((char *) (& u)))
+
+\f
+#ifndef __GNUC__
+#undef USE_GAS
+#define ALTOS_AS
+#else
+#define USE_GAS
+#endif
+
+/* Motorola assembly format */
+#if !defined(USE_GAS) && !defined(ALTOS)
+#define MOTOROLA
+#endif
+
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#ifdef MOTOROLA
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("move.l $ end, sp");      \
+  asm ("clr.l fp"); }
+#else
+#ifdef ALTOS_AS
+#define INIT_STACK(beg, end)  \
+{ asm ("global end");         \
+  asm ("mov.l &end,%sp");      \
+  asm ("clr.l %fp"); }
+#else
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+#endif
+#endif
+
+/* Push the frame pointer register on the stack.  */
+#ifdef MOTOROLA
+#define PUSH_FRAME_PTR        \
+  asm ("move.l fp, -(sp)");
+#else
+#ifdef ALTOS_AS
+#define PUSH_FRAME_PTR        \
+  asm ("mov.l %fp, -(%sp)");
+#else
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+#endif
+#endif
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#ifdef MOTOROLA
+#define POP_FRAME_PTR  \
+  asm ("move.l (sp), fp");
+#else
+#ifdef ALTOS_AS
+#define POP_FRAME_PTR  \
+  asm ("mov.l (%sp), %fp");
+#else
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+#endif
+#endif
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#ifdef MOTOROLA
+#define PUSH_REGISTERS        \
+{ asm ("clr.w -(sp)");       \
+  asm ("pea (10,sp)");       \
+  asm ("movem $ 0xfffe,-(sp)"); }
+#else
+#ifdef ALTOS_AS
+#define PUSH_REGISTERS        \
+{ asm ("clr.w -(%sp)");              \
+  asm ("pea (10,%sp)");              \
+  asm ("movm.l &0xfffe,-(%sp)"); }
+#else
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+#endif
+#endif
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#ifdef MOTOROLA
+#define POP_REGISTERS          \
+{ asm ("subi.l $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+#else
+#ifdef ALTOS_AS
+#define POP_REGISTERS          \
+{ asm ("sub.l &8,28(%sp)");     \
+  asm ("movem (%sp),&0xffff"); \
+  asm ("rte"); }
+#else
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+#endif
+#endif
diff --git a/gdb/xm-arm.h b/gdb/xm-arm.h
new file mode 100644 (file)
index 0000000..3251fae
--- /dev/null
@@ -0,0 +1,88 @@
+/* Definitions to make GDB run on an ARM under RISCiX (4.3bsd).
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR (0x01000000 - (UPAGES * NBPG))
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+#define FETCH_INFERIOR_REGISTERS
+
+\f
+#if 0
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+  0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movl $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("pushl fp");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("pushl 8(sp)");        \
+  asm ("pushl 8(sp)");        \
+  asm ("pushal 0x14(sp)");    \
+  asm ("pushr $037777"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      \
+{ asm ("popr $037777");    \
+  asm ("subl2 $8,(sp)");   \
+  asm ("movl (sp),sp");    \
+  asm ("rei"); }
+#endif /* 0 */
diff --git a/gdb/xm-bigmips.h b/gdb/xm-bigmips.h
new file mode 100644 (file)
index 0000000..0c1102d
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#include "xm-mips.h"
diff --git a/gdb/xm-convex.h b/gdb/xm-convex.h
new file mode 100644 (file)
index 0000000..ed102bb
--- /dev/null
@@ -0,0 +1,51 @@
+/* Definitions to make GDB run on Convex Unix (4bsd)
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#define LONG_LONG
+#define ATTACH_DETACH
+#define HAVE_WAIT_STRUCT
+#define NO_SIGINTERRUPT
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* Use SIGCONT rather than SIGTSTP because convex Unix occasionally
+   turkeys SIGTSTP.  I think.  */
+
+#define STOP_SIGNAL SIGCONT
+
+/* Use csh to do argument expansion so we get ~ and such.  */
+
+/* Doesn't work.  */
+/* #define SHELL_FILE "/bin/csh" */
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+
+/* Hook to call after creating inferior process.  */
+
+#define CREATE_INFERIOR_HOOK create_inferior_hook
+
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* (no kdb) */
diff --git a/gdb/xm-hp300bsd.h b/gdb/xm-hp300bsd.h
new file mode 100644 (file)
index 0000000..4ae5a5c
--- /dev/null
@@ -0,0 +1,113 @@
+/* Parameters for execution on a Hewlett-Packard 9000/300, running bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Configuration file for HP9000/300 series machine running
+ * University of Utah's 4.3bsd port.  This is NOT for HP-UX.
+ * Problems to hpbsd-bugs@cs.utah.edu
+ */
+
+#include <machine/endian.h>
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* Get kernel u area address at run-time using BSD style nlist ().  */
+#define KERNEL_U_ADDR_BSD
+
+/* This is a piece of magic that is given a register number REGNO
+   and as BLOCKEND the address in the system of the end of the user structure
+   and stores in ADDR the address in the kernel or core dump
+   of that register.  */
+
+#define REGISTER_U_ADDR(addr, blockend, regno)                         \
+{                                                                      \
+  if (regno < PS_REGNUM)                                               \
+    addr = (int) &((struct frame *)(blockend))->f_regs[regno];         \
+  else if (regno == PS_REGNUM)                                         \
+    addr = (int) &((struct frame *)(blockend))->f_stackadj;            \
+  else if (regno == PC_REGNUM)                                         \
+    addr = (int) &((struct frame *)(blockend))->f_pc;                  \
+  else if (regno < FPC_REGNUM)                                         \
+    addr = (int)                                                       \
+      &((struct user *)0)->u_pcb.pcb_fpregs.fpf_regs[((regno)-FP0_REGNUM)*3];\
+  else if (regno == FPC_REGNUM)                                                \
+    addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpcr;       \
+  else if (regno == FPS_REGNUM)                                                \
+    addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpsr;       \
+  else                                                                 \
+    addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpiar;      \
+}
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel #end, sp");      \
+  asm ("movel #0,a6"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel a6,sp@-");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl sp@,a6");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea sp@(10)");       \
+  asm ("movem #0xfffe,sp@-"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil #8,sp@(28)");     \
+  asm ("movem sp@,#0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-hp300hpux.h b/gdb/xm-hp300hpux.h
new file mode 100644 (file)
index 0000000..6583748
--- /dev/null
@@ -0,0 +1,173 @@
+/* Parameters for execution on an HP 9000 model 320, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Define this to indicate problems with traps after continuing.  */
+#define HP_OS_BUG
+
+/* fetch_inferior_registers is in hp300hpux-dep.c.  */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Set flag to indicate whether HP's assembler is in use. */
+#ifdef __GNUC__
+#ifdef __HPUX_ASM__
+#define HPUX_ASM
+#endif
+#else /* not GNU C.  */
+#define HPUX_ASM
+#endif /* not GNU C.  */
+
+/* Define this for versions of hp-ux older than 6.0 */
+/* #define HPUX_VERSION_5 */
+
+/* define USG if you are using sys5 /usr/include's */
+#undef USG     /* In case it was defined in the Makefile for cplus-dem.c */
+#define USG
+
+#define HAVE_TERMIO
+
+/* Get rid of any system-imposed stack limit if possible.  */
+/* The hp9k320.h doesn't seem to have this feature.  */
+/* #define SET_STACK_LIMIT_HUGE */
+/* So we'll just have to avoid big alloca's.  */
+#define BROKEN_LARGE_ALLOCA
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#ifdef HPUX_VERSION_5
+#define KERNEL_U_ADDR 0x00979000
+#else /* Not HPUX version 5.  */
+/* Use HPUX-style nlist() to get kernel_u_addr.  */
+#define KERNEL_U_ADDR_HPUX
+#endif /* Not HPUX version 5.  */
+
+#define REGISTER_ADDR(u_ar0, regno)                                    \
+  (unsigned int)                                                       \
+  (((regno) < PS_REGNUM)                                               \
+   ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)])     \
+   : (((regno) == PS_REGNUM)                                           \
+      ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS))                \
+      : (&((struct exception_stack *) (u_ar0))->e_PC)))
+
+#define FP_REGISTER_ADDR(u, regno)                                     \
+  (((char *)                                                           \
+    (((regno) < FPC_REGNUM)                                            \
+     ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
+     : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)])))   \
+   - ((char *) (& u)))
+\f
+/* Do implement the attach and detach commands.  */
+
+#define ATTACH_DETACH
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+#ifndef HPUX_ASM
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+
+#else /* HPUX_ASM */
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)                                           \
+{ asm ("global end");                                                  \
+  asm ("mov.l &end,%sp");                                              \
+  asm ("clr.l %a6"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR                                                 \
+  asm ("mov.l %fp,-(%sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR                                                  \
+  asm ("mov.l (%sp),%fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS                                                 \
+{ asm ("clr.w -(%sp)");                                                        \
+  asm ("pea 10(%sp)");                                                 \
+  asm ("movm.l &0xfffe,-(%sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS                                                  \
+{ asm ("subi.l &8,28(%sp)");                                           \
+  asm ("mov.m (%sp),&0xffff");                                         \
+  asm ("rte"); }
+
+#endif /* HPUX_ASM */
diff --git a/gdb/xm-i386v.h b/gdb/xm-i386v.h
new file mode 100644 (file)
index 0000000..840cb58
--- /dev/null
@@ -0,0 +1,99 @@
+/* Macro defintions for i386.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
+Sys V/386 3.2.
+
+On some machines, gdb crashes when it's starting up while calling the
+vendor's termio tgetent() routine.  It always works when run under
+itself (actually, under 3.2, it's not an infinitely recursive bug.)
+After some poking around, it appears that depending on the environment
+size, or whether you're running YP, or the phase of the moon or something,
+the stack is not always long-aligned when main() is called, and tgetent()
+takes strong offense at that.  On some machines this bug never appears, but
+on those where it does, it occurs quite reliably.  */
+#define ALIGN_STACK_ON_STARTUP
+
+/* define USG if you are using sys5 /usr/include's */
+#define USG
+
+/* USG systems need these */
+#define vfork() fork()
+#define MAXPATHLEN 500
+
+#define HAVE_TERMIO
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+/* #define SET_STACK_LIMIT_HUGE not in sys5 */
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR 0xe0000000
+
+\f
+#if 0
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  {}
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        {}
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  {}
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        {}
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      {}
+#endif /* 0 */
diff --git a/gdb/xm-i386v32.h b/gdb/xm-i386v32.h
new file mode 100644 (file)
index 0000000..b343be0
--- /dev/null
@@ -0,0 +1,28 @@
+/* Macro defintions for i386, running System V 3.2.
+   Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "xm-i386v.h"
+
+/* Apparently there is inconsistency among various System V's about what
+   the name of this field is.  */
+#define U_FPSTATE(u) u.u_fps.u_fpstate
+
+/* TIOCGETC is defined in System V 3.2 termio.h, but struct tchars
+   is not.  This makes problems for inflow.c.  */
+#define TIOCGETC_BROKEN
diff --git a/gdb/xm-isi.h b/gdb/xm-isi.h
new file mode 100644 (file)
index 0000000..21c0134
--- /dev/null
@@ -0,0 +1,95 @@
+/* Definitions to make GDB run on an ISI Optimum V (3.05) under 4.3bsd.
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* This has not been tested on ISI's running BSD 4.2, but it will probably
+   work.  */
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+/*#define KERNEL_U_ADDR 0x10800000*/
+#define KERNEL_U_ADDR 0
+
+/* expects blockend to be u.u_ar0 */
+extern int rloc[];     /* Defined in isi-dep.c */
+#define REGISTER_U_ADDR(addr, blockend, regno)                  \
+{       blockend &= UPAGES*NBPG - 1;                            \
+       if (regno < 18) addr = (int)blockend + rloc[regno]*4;   \
+        else if (regno < 26) addr = (int) &((struct user *)0)->u_68881_regs \
+            + (regno - 18) * 12;                                \
+        else if (regno < 29) addr = (int) &((struct user *)0)->u_68881_regs \
+            + 8 * 12 + (regno - 26) * 4;                        \
+}
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movl $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-m88k.h b/gdb/xm-m88k.h
new file mode 100644 (file)
index 0000000..240459b
--- /dev/null
@@ -0,0 +1,124 @@
+/* Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is currently for a 88000 running DGUX.  If other 88k ports are
+   done, OS-specific stuff should be moved (see tm-68k.h, for example).  */
+/* g++ support is not yet included.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#define USG
+/* DGUX has bcopy(), etc.  */
+#define USG_UTILS 0
+
+#include <sys/param.h>
+
+#define vfork() fork()
+#define index strchr
+#define rindex strrchr
+#define getwd(BUF) getcwd(BUF,MAXPATHLEN);
+#define bzero(ptr,count) (memset((ptr),0,(count)))
+#define bcopy(src,dst,count) (memcpy((dst),(src),(count)))
+#define bcmp(left,right,count) (memcmp((right),(left),(count)))
+#ifdef __GNUC__
+#define memcpy __builtin_memcpy
+#define memset __builtin_memset
+#define strcmp __builtin_strcmp
+#endif
+
+#ifdef DGUX
+#define x_foff _x_x._x_offset
+#define x_fname _x_name
+#define USER ptrace_user
+#define _BSD_WAIT_FLAVOR
+#endif
+
+#define HAVE_TERMIO
+
+
+#define USIZE 2048
+#define NBPG NBPC
+#define UPAGES USIZE
+
+#define HAVE_GETPAGESIZE
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* number of traps that happen between exec'ing the shell
+ * to run an inferior, and when we finally get to
+ * the inferior code.  This is 2 on most implementations.
+ */
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+/* Since registers r0 through r31 are stored directly in the struct ptrace_user,
+   (for m88k BCS)
+   the ptrace_user offsets are sufficient and KERNEL_U_ADDRESS can be 0 */
+
+#define KERNEL_U_ADDR 0
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+        (addr) = m88k_register_u_addr ((blockend),(regno));
+
+#define HAVE_WAIT_STRUCT
+
+#define FETCH_INFERIOR_REGISTERS
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  {}
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        {}
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  {}
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        {}
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      {}
diff --git a/gdb/xm-merlin.h b/gdb/xm-merlin.h
new file mode 100644 (file)
index 0000000..54c1baf
--- /dev/null
@@ -0,0 +1,120 @@
+/* Definitions to make GDB run on a merlin under utek 2.1
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This machine doesn't have the siginterrupt call.  */
+#define NO_SIGINTERRUPT
+
+/* Under Utek, a ptrace'd process can be the only active process for
+   an executable.  Therefore instead of /bin/sh use gdb-sh (which should
+   just be a copy of /bin/sh which is world readable and writeable).  */
+#define SHELL_FILE "/usr/gnu/lib/gdb-sh"
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR (0xfef000)
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{                                                                      \
+  switch (regno) {                                                     \
+  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:      \
+       addr = blockend + (R0 - regno) * sizeof (int); break;           \
+  case PC_REGNUM:                                                      \
+       addr = blockend + PC * sizeof (int); break;                     \
+  case SP_REGNUM:                                                      \
+       addr = blockend + SP * sizeof (int); break;                     \
+  case FP_REGNUM:                                                      \
+       addr = blockend + FP * sizeof (int); break;                     \
+  case PS_REGNUM:                                                      \
+       addr = blockend + 12 * sizeof (int); break;                     \
+  case FPS_REGNUM:                                                     \
+       addr = 108; break;                                              \
+  case FP0_REGNUM + 0: case FP0_REGNUM + 1:                            \
+  case FP0_REGNUM + 2: case FP0_REGNUM + 3:                            \
+  case FP0_REGNUM + 4: case FP0_REGNUM + 5:                            \
+  case FP0_REGNUM + 6: case FP0_REGNUM + 7:                            \
+       addr = 76 + (regno - FP0_REGNUM) * sizeof (float); break;       \
+  case LP0_REGNUM + 0: case LP0_REGNUM + 1:                            \
+  case LP0_REGNUM + 2: case LP0_REGNUM + 3:                            \
+       addr = 76 + (regno - LP0_REGNUM) * sizeof (double); break;      \
+  default:                                                             \
+       printf ("bad argument to REGISTER_U_ADDR %d\n", regno);         \
+       abort ();                                                       \
+  }                                                                    \
+}
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+\f
+#if 0
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+  0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movl $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("pushl fp");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("pushl 8(sp)");        \
+  asm ("pushl 8(sp)");        \
+  asm ("pushal 0x14(sp)");    \
+  asm ("pushr $037777"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      \
+{ asm ("popr $037777");    \
+  asm ("subl2 $8,(sp)");   \
+  asm ("movl (sp),sp");    \
+  asm ("rei"); }
+#endif /* 0 */
diff --git a/gdb/xm-mips.h b/gdb/xm-mips.h
new file mode 100644 (file)
index 0000000..3f7fce2
--- /dev/null
@@ -0,0 +1,44 @@
+/* Definitions to make GDB run on a mips box under 4.3bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+   Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
+   and by Alessandro Forin(af@cs.cmu.edu) at CMU
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (HOST_BYTE_ORDER)
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* wait.h */
+#define HAVE_WAIT_STRUCT
+
+/* Get rid of any system-imposed stack limit if possible */
+
+#define        SET_STACK_LIMIT_HUGE
+
+/* This WOULD BE the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.
+   But Mips' ptrace works on regnums, not displacements */
+
+#define KERNEL_U_ADDR (int)u.u_ar0
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+#define FETCH_INFERIOR_REGISTERS
+\f
+/* Interface definitions for kernel debugger KDB */
+
+/* I am not going to pretend I've done anything about this */
diff --git a/gdb/xm-news.h b/gdb/xm-news.h
new file mode 100644 (file)
index 0000000..1c5c6f1
--- /dev/null
@@ -0,0 +1,143 @@
+/* Parameters for execution on a Sony/NEWS, for GDB, the GNU debugger.
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#define HAVE_WAIT_STRUCT
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* We can't use "isatty" or "fileno" on this machine.  This isn't good,
+   but it will have to do.  */
+#define ISATTY(FP)     ((FP) == stdin || (FP) == stdout)
+
+/* THis is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values. */
+
+#define KERNEL_U_ADDR UADDR
+
+/* The offsets in this macro are from /usr/include/machine/reg.h */
+
+#define REGISTER_U_ADDR(addr, blockend, regno)         \
+{   static char offsets[] = { \
+       /*d0-d7:*/1,2,3,4,5,6,7,8, \
+       /*a0-a6:*/9,10,11,12,13,14,15, /*sp:*/-4, /*ps:*/0, /*pc:*/-1, \
+       /*fp0-fp7:*/19,22,25,28,31,34,37,40, /*fpc:*/16,17,18 }; \
+       addr = blockend + 4 * offsets[regno]; \
+}
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+
+/* NewsOS 3 apparently dies on large alloca's -- roland@ai.mit.edu.  */
+#define        BROKEN_LARGE_ALLOCA
+
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Use GNU assembler instead of standard assembler */
+#define USE_GAS
+
+/* Motorola assembly format */
+#ifndef USE_GAS
+#define MOTOROLA
+#endif
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#ifdef MOTOROLA
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("move.l $ end, sp");      \
+  asm ("clr.l fp"); }
+#else
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+#endif
+
+/* Push the frame pointer register on the stack.  */
+#ifdef MOTOROLA
+#define PUSH_FRAME_PTR        \
+  asm ("move.l fp, -(sp)");
+#else
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+#endif
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#ifdef MOTOROLA
+#define POP_FRAME_PTR  \
+  asm ("move.l (sp), fp");
+#else
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+#endif
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#ifdef MOTOROLA
+#define PUSH_REGISTERS        \
+{ asm ("clr.w -(sp)");       \
+  asm ("pea (10,sp)");       \
+  asm ("movem $ 0xfffe,-(sp)"); }
+#else
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+#endif
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#ifdef MOTOROLA
+#define POP_REGISTERS          \
+{ asm ("subi.l $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+#else
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
+#endif
diff --git a/gdb/xm-news1000.h b/gdb/xm-news1000.h
new file mode 100644 (file)
index 0000000..aade898
--- /dev/null
@@ -0,0 +1,26 @@
+/* Parameters for a Sony/NEWS series 1000 with News-OS version 3,
+   for GDB, the GNU debugger.
+   Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This is required by Sony include files like <sys/user.h> so we
+   get the right offset into the u area.  Relying on the compiler
+   to define this only works for cc, not gcc.  */
+#undef mc68030
+#define mc68030
+#include "xm-news.h"
diff --git a/gdb/xm-np1.h b/gdb/xm-np1.h
new file mode 100644 (file)
index 0000000..0608e36
--- /dev/null
@@ -0,0 +1,99 @@
+/* Parameters for execution on a Gould NP1, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+#define SET_STACK_LIMIT_HUGE
+
+/* Address of U in kernel space */
+#define        KERNEL_U_ADDR           0x7fffc000
+
+/* This is a piece of magic that is given a register number REGNO
+   and as BLOCKEND the address in the system of the end of the user structure
+   and stores in ADDR the address in the kernel or core dump
+   of that register. */
+#define REGISTER_U_ADDR(addr, blockend, regno) {                       \
+       addr = blockend + regno * 4;                                    \
+       if (regno == VE_REGNUM) addr = blockend - 9 * 4;                \
+       if (regno == PC_REGNUM) addr = blockend - 8 * 4;                \
+       if (regno == PS_REGNUM) addr = blockend - 7 * 4;                \
+       if (regno == FP_REGNUM) addr = blockend - 6 * 4;                \
+       if (regno >= V1_REGNUM)                                         \
+           addr = blockend + 16 * 4 + (regno - V1_REGNUM) * VR_SIZE;   \
+}
+
+/* Don't try to write the frame pointer.  */
+#define CANNOT_STORE_REGISTER(regno) ((regno) == FP_REGNUM)
+
+#define MISSING_VPRINTF
+\f
+/*
+ * No KDB support, Yet! */
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-pn.h b/gdb/xm-pn.h
new file mode 100644 (file)
index 0000000..f9fa986
--- /dev/null
@@ -0,0 +1,82 @@
+/* Parameters for execution on a Gould PN, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+#define SET_STACK_LIMIT_HUGE
+
+#define MISSING_VPRINTF
+
+/* Address of U in kernel space */
+#define        KERNEL_U_ADDR           0x3fc000
+\f
+/*
+ * No KDB support, Yet! */
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-pyr.h b/gdb/xm-pyr.h
new file mode 100644 (file)
index 0000000..8a01569
--- /dev/null
@@ -0,0 +1,105 @@
+/* Definitions to make GDB run on a Pyramidax under OSx 4.0 (4.2bsd).
+   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Define PYRAMID_CONTROL_FRAME_DEBUGGING to get copious messages
+   about reading the control stack on standard output. This
+   makes gdb unusable as a debugger. */
+
+/* #define PYRAMID_CONTROL_FRAME_DEBUGGING */
+
+/* Define PYRAMID_FRAME_DEBUGGING for ? */
+
+/* use Pyramid's slightly strange ptrace */
+#define PYRAMID_PTRACE
+
+/* Traditional Unix virtual address spaces have thre regions: text,
+   data and stack.  The text, initialised data, and uninitialised data
+   are represented in separate segments of the a.out file.
+   When a process dumps core, the data and stack regions are written
+   to a core file.  This gives a debugger enough information to
+   reconstruct (and debug) the virtual address space at the time of
+   the coredump.
+   Pyramids have an distinct fourth region of the virtual address
+   space, in which the contents of the windowed registers are stacked
+   in fixed-size frames.  Pyramid refer to this region as the control
+   stack.  Each call (or trap) automatically allocates a new register
+   frame; each return deallocates the current frame and restores the
+   windowed registers to their values before the call.
+
+   When dumping core, the control stack is written to a core files as
+   a third segment. The core-handling functions need to know to deal
+   with it. */ 
+
+/* Tell dep.c what the extra segment is.  */
+#define PYRAMID_CORE
+
+#define NO_SIGINTERRUPT
+
+#define HAVE_WAIT_STRUCT
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
+
+/* Define offsets of registers in the core file (or maybe u area) */
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{ struct user __u;                                     \
+  addr = blockend  + (regno - 16 ) * 4;                        \
+  if (regno == 67) {                                           \
+      printf("\\geting reg 67\\");                     \
+      addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u;   \
+  } else if (regno == KSP_REGNUM) {                    \
+      printf("\\geting KSP (reg %d)\\", KSP_REGNUM);   \
+      addr = (int)(&__u.u_pcb.pcb_ksp) - (int) &__u;   \
+  } else if (regno == CSP_REGNUM) {                    \
+      printf("\\geting CSP (reg %d\\",CSP_REGNUM);     \
+      addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u;   \
+  } else if (regno == 64) {                            \
+      printf("\\geting reg 64\\");                     \
+      addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u;   \
+   } else if (regno == PS_REGNUM)                      \
+      addr = blockend - 4;                             \
+  else if (1 && ((16 > regno) && (regno > 11)))                \
+      addr = last_frame_offset + (4 *(regno+32));      \
+  else if (0 && (12 > regno))                          \
+      addr = global_reg_offset + (4 *regno);           \
+  else if (16 > regno)                                 \
+      addr = global_reg_offset + (4 *regno);           \
+ else                                                  \
+      addr = blockend  + (regno - 16 ) * 4;            \
+}
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+#define FETCH_INFERIOR_REGISTERS
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
+
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* I have *no idea* how to debug OSx kernels, so this
+   is flushed, possible forever. */
diff --git a/gdb/xm-sparc.h b/gdb/xm-sparc.h
new file mode 100644 (file)
index 0000000..c8b9b34
--- /dev/null
@@ -0,0 +1,60 @@
+/* Parameters for execution on a Sun 4, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+   Contributed by Michael Tiemann (tiemann@mcc.com)
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* Enable use of alternate code for Sun's format of core dump file.  */
+
+#define NEW_SUN_CORE
+
+/* Do implement the attach and detach commands.  */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* Before storing, we need to read all the registers.  */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+
+/* It does have a wait structure, and it might help things out . . . */
+
+#define HAVE_WAIT_STRUCT
+
+/* Optimization for storing registers to the inferior.  The hook
+   DO_DEFERRED_STORES
+   actually executes any deferred stores.  It is called any time
+   we are going to proceed the child, or read its registers.
+   The hook CLEAR_DEFERRED_STORES is called when we want to throw
+   away the inferior process, e.g. when it dies or we kill it.
+   FIXME, this does not handle remote debugging cleanly.  */
+
+extern int deferred_stores;
+extern int store_inferior_registers ();
+#define        DO_DEFERRED_STORES      \
+  if (deferred_stores)         \
+    store_inferior_registers (-2);
+#define        CLEAR_DEFERRED_STORES   \
+  deferred_stores = 0;
diff --git a/gdb/xm-sun2.h b/gdb/xm-sun2.h
new file mode 100644 (file)
index 0000000..278198a
--- /dev/null
@@ -0,0 +1,96 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR 0x2800
+
+/* Enable use of alternate code for Sun's format of core dump file.  */
+
+#define NEW_SUN_CORE
+
+/* Do implement the attach and detach commands.  */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+#define FETCH_INFERIOR_REGISTERS
+
+/* This is a piece of magic that is given a register number REGNO
+   and as BLOCKEND the address in the system of the end of the user structure
+   and stores in ADDR the address in the kernel or core dump
+   of that register.  */
+
+#define REGISTER_U_ADDR(addr, blockend, regno)         \
+{ addr = blockend + regno * 4; }
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel fp, -(sp)");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea 10(sp)");        \
+  asm ("movem $ 0xfffe,-(sp)"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil $8,28(sp)");     \
+  asm ("movem (sp),$ 0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-sun3.h b/gdb/xm-sun3.h
new file mode 100644 (file)
index 0000000..e67cc13
--- /dev/null
@@ -0,0 +1,93 @@
+/* Parameters for execution on a Sun, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* Enable use of alternate code for Sun's format of core dump file.  */
+
+#define NEW_SUN_CORE
+
+/* Do implement the attach and detach commands.  */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* We have to grab the regs since we store all regs at once.  */
+
+#define CHILD_PREPARE_TO_STORE() \
+       read_register_bytes (0, (char *)NULL, REGISTER_BYTES)
+\f
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
+  0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
+  0, 0, 0, 0, 0, 0, 0, 0, \
+  SIGILL }
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movel #end, sp");      \
+  asm ("movel #0,a6"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("movel a6,sp@-");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl sp@,a6");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("clrw -(sp)");        \
+  asm ("pea sp@(10)");       \
+  asm ("movem #0xfffe,sp@-"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS          \
+{ asm ("subil #8,sp@(28)");     \
+  asm ("movem sp@,#0xffff"); \
+  asm ("rte"); }
diff --git a/gdb/xm-sun386.h b/gdb/xm-sun386.h
new file mode 100644 (file)
index 0000000..69b3673
--- /dev/null
@@ -0,0 +1,37 @@
+/* Parameters for execution on a Sun 386i, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* Enable use of alternate code for Sun's format of core dump file.  */
+
+#define NEW_SUN_CORE
+
+/* Do implement the attach and detach commands.  */
+
+#define ATTACH_DETACH
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+#define FETCH_INFERIOR_REGISTERS
+
+#define PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
diff --git a/gdb/xm-sun3os4.h b/gdb/xm-sun3os4.h
new file mode 100644 (file)
index 0000000..b9ffc8d
--- /dev/null
@@ -0,0 +1,28 @@
+/* Macro definitions for a sun 3 running os 4.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "xm-sun3.h"
+#define FPU
+
+/* There is a bug which can cause alloca to fail to allocate large
+   areas of memory one time in every 4096 (we think).  */
+/* chase@orc.olivetti.com says that 4 megabyte alloca's consistently fail,
+   even though the stack limit (SET_STACK_LIMIT_HUGE) has been set
+   to 250 megabytes.  */
+#define BROKEN_LARGE_ALLOCA
diff --git a/gdb/xm-sun4os4.h b/gdb/xm-sun4os4.h
new file mode 100644 (file)
index 0000000..eaf7473
--- /dev/null
@@ -0,0 +1,22 @@
+/* Macro definitions for running gdb on a Sun 4 running sunos 4.
+   Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "xm-sparc.h"
+
+#define FPU
diff --git a/gdb/xm-symmetry.h b/gdb/xm-symmetry.h
new file mode 100644 (file)
index 0000000..c941cf0
--- /dev/null
@@ -0,0 +1,152 @@
+/* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0,
+   with Weitek 1167 and i387 support.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Symmetry version by Jay Vosburgh (uunet!sequent!fubar) */
+
+/* This machine doesn't have the siginterrupt call.  */
+#define NO_SIGINTERRUPT
+
+#define HAVE_WAIT_STRUCT
+
+/* XPT_DEBUG doesn't work yet under Dynix 3.0.12, but UNDEBUG does... */
+/* #define PTRACE_ATTACH XPT_DEBUG
+#define PTRACE_DETACH XPT_UNDEBUG
+#define ATTACH_DETACH  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
+
+/* Compensate for lack of `vprintf' function.  */
+
+#define MISSING_VPRINTF
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c.  */
+
+#define FETCH_INFERIOR_REGISTERS
+
+/* We must fetch all the regs before storing, since we store all at once.  */
+
+#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+\f
+/* Interface definitions for kernel debugger KDB.  */
+/* This doesn't work... */
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+  0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movl $ end, %esp");      \
+  asm ("movl %ebp, $0"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("pushl %ebp");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (%esp), %ebp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm("pushad"); }
+/*
+{ asm("pushl %eax"); \
+  asm("pushl %edx"); \
+  asm("pushl %ecx"); \
+  asm("pushl %st(0)"); \
+  asm("pushl %st(1)"); \
+  asm("pushl %ebx"); \
+  asm("pushl %esi"); \
+  asm("pushl %edi"); \
+  asm("pushl %st(2)"); \
+  asm("pushl %st(3)"); \
+  asm("pushl %st(4)"); \
+  asm("pushl %st(5)"); \
+  asm("pushl %st(6)"); \
+  asm("pushl %st(7)"); \
+  asm("pushl %esp"); \
+  asm("pushl %ebp"); \
+  asm("pushl %eip"); \
+  asm("pushl %eflags"); \
+  asm("pushl %fp1"); \
+  asm("pushl %fp2"); \
+  asm("pushl %fp3"); \
+  asm("pushl %fp4"); \
+  asm("pushl %fp5"); \
+  asm("pushl %fp6"); \
+  asm("pushl %fp7"); \
+  asm("pushl %fp8"); \ 
+  asm("pushl %fp9"); \
+  asm("pushl %fp10"); \
+  asm("pushl %fp11"); \
+  asm("pushl %fp12"); \
+  asm("pushl %fp13"); \
+  asm("pushl %fp14"); \
+  asm("pushl %fp15"); \
+  asm("pushl %fp16"); \
+  asm("pushl %fp17"); \
+  asm("pushl %fp18"); \
+  asm("pushl %fp19"); \
+  asm("pushl %fp20"); \
+  asm("pushl %fp21"); \
+  asm("pushl %fp22"); \ 
+  asm("pushl %fp23"); \
+  asm("pushl %fp24"); \
+  asm("pushl %fp25"); \
+  asm("pushl %fp26"); \
+  asm("pushl %fp27"); \
+  asm("pushl %fp28"); \
+  asm("pushl %fp29"); \
+  asm("pushl %fp30"); \
+  asm("pushl %fp31"); \
+}
+*/
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      \
+{ asm ("popad"); }
diff --git a/gdb/xm-umax.h b/gdb/xm-umax.h
new file mode 100644 (file)
index 0000000..873e808
--- /dev/null
@@ -0,0 +1,64 @@
+/* Definitions to make GDB run on an encore under umax 4.2
+   Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+#define HAVE_WAIT_STRUCT
+
+/* Offset of registers within u area.  */
+#define U_REGS_OFFSET 0
+
+/* Do implement the attach and detach commands...  */
+#define ATTACH_DETACH
+
+/* Doesn't have siginterupt.  */
+#define NO_SIGINTERRUPT
+
+/* called from register_addr() -- blockend not used for now */
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+{                                                                      \
+  switch (regno) {                                                     \
+  case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:      \
+       addr = PU_R0 - (regno * sizeof (int)); break;                   \
+  case SP_REGNUM:                                                      \
+       addr = PU_SP; break;                                            \
+  case PC_REGNUM:                                                      \
+       addr = PU_PC; break;                                            \
+  case FP_REGNUM:                                                      \
+       addr = PU_FP; break;                                            \
+  case PS_REGNUM:                                                      \
+       addr = PU_PSL; break;                                           \
+  case FPS_REGNUM:                                                     \
+       addr = PU_FSR; break;                                           \
+  case FP0_REGNUM + 0: case FP0_REGNUM + 1:                            \
+  case FP0_REGNUM + 2: case FP0_REGNUM + 3:                            \
+  case FP0_REGNUM + 4: case FP0_REGNUM + 5:                            \
+  case FP0_REGNUM + 6: case FP0_REGNUM + 7:                            \
+       addr = PU_F0 + (regno - FP0_REGNUM) * sizeof (float); break;    \
+  case LP0_REGNUM + 0: case LP0_REGNUM + 1:                            \
+  case LP0_REGNUM + 2: case LP0_REGNUM + 3:                            \
+       addr = PU_F0 + (regno - LP0_REGNUM) * sizeof (double); break;   \
+  default:                                                             \
+       printf ("bad argument to REGISTER_U_ADDR %d\n", regno);         \
+       abort ();                                                       \
+  }                                                                    \
+}
+
+/* Compensate for lack of `vprintf' function.  */
+#define MISSING_VPRINTF
diff --git a/gdb/xm-vax.h b/gdb/xm-vax.h
new file mode 100644 (file)
index 0000000..1bc6aa4
--- /dev/null
@@ -0,0 +1,90 @@
+/* Definitions to make GDB run on a vax under 4.2bsd.
+   Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDB is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDB; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* Get rid of any system-imposed stack limit if possible.  */
+
+#define SET_STACK_LIMIT_HUGE
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
+
+#define REGISTER_U_ADDR(addr, blockend, regno)         \
+{ addr = blockend - 0110 + regno * 4;                  \
+  if (regno == PC_REGNUM) addr = blockend - 8;         \
+  if (regno == PS_REGNUM) addr = blockend - 4;         \
+  if (regno == FP_REGNUM) addr = blockend - 0120;      \
+  if (regno == AP_REGNUM) addr = blockend - 0124;      \
+  if (regno == SP_REGNUM) addr = blockend - 20; }
+
+/* Interface definitions for kernel debugger KDB.  */
+
+/* Map machine fault codes into signal numbers.
+   First subtract 0, divide by 4, then index in a table.
+   Faults for which the entry in this table is 0
+   are not handled by KDB; the program's own trap handler
+   gets to handle then.  */
+
+#define FAULT_CODE_ORIGIN 0
+#define FAULT_CODE_UNITS 4
+#define FAULT_TABLE    \
+{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+  0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+  0, 0, 0, 0, 0, 0, 0, 0}
+
+/* Start running with a stack stretching from BEG to END.
+   BEG and END should be symbols meaningful to the assembler.
+   This is used only for kdb.  */
+
+#define INIT_STACK(beg, end)  \
+{ asm (".globl end");         \
+  asm ("movl $ end, sp");      \
+  asm ("clrl fp"); }
+
+/* Push the frame pointer register on the stack.  */
+#define PUSH_FRAME_PTR        \
+  asm ("pushl fp");
+
+/* Copy the top-of-stack to the frame pointer register.  */
+#define POP_FRAME_PTR  \
+  asm ("movl (sp), fp");
+
+/* After KDB is entered by a fault, push all registers
+   that GDB thinks about (all NUM_REGS of them),
+   so that they appear in order of ascending GDB register number.
+   The fault code will be on the stack beyond the last register.  */
+
+#define PUSH_REGISTERS        \
+{ asm ("pushl 8(sp)");        \
+  asm ("pushl 8(sp)");        \
+  asm ("pushal 0x14(sp)");    \
+  asm ("pushr $037777"); }
+
+/* Assuming the registers (including processor status) have been
+   pushed on the stack in order of ascending GDB register number,
+   restore them and return to the address in the saved PC register.  */
+
+#define POP_REGISTERS      \
+{ asm ("popr $037777");    \
+  asm ("subl2 $8,(sp)");   \
+  asm ("movl (sp),sp");    \
+  asm ("rei"); }
diff --git a/include/a.out.hp.h b/include/a.out.hp.h
new file mode 100755 (executable)
index 0000000..87e7219
--- /dev/null
@@ -0,0 +1,79 @@
+/* Special version of <a.out.h> for use under hp-ux.
+   Copyright (C) 1988 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* The `exec' structure and overall layout must be close to HP's when
+   we are running on an HP system, otherwise we will not be able to
+   execute the resulting file. */
+
+/* Allow this file to be included twice. */
+#ifndef __GNU_EXEC_MACROS__
+
+struct exec
+{
+  unsigned short a_machtype;   /* machine type */
+  unsigned short a_magic;      /* magic number */
+  unsigned long a_spare1;
+  unsigned long a_spare2;
+  unsigned long a_text;                /* length of text, in bytes */
+  unsigned long a_data;                /* length of data, in bytes */
+  unsigned long a_bss;         /* length of uninitialized data area for file, in bytes */
+  unsigned long a_trsize;      /* length of relocation info for text, in bytes */
+  unsigned long a_drsize;      /* length of relocation info for data, in bytes */
+  unsigned long a_spare3;      /* HP = pascal interface size */
+  unsigned long a_spare4;      /* HP = symbol table size */
+  unsigned long a_spare5;      /* HP = debug name table size */
+  unsigned long a_entry;       /* start address */
+  unsigned long a_spare6;      /* HP = source line table size */
+  unsigned long a_spare7;      /* HP = value table size */
+  unsigned long a_syms;                /* length of symbol table data in file, in bytes */
+  unsigned long a_spare8;
+};
+
+/* Tell a.out.gnu.h not to define `struct exec'.  */
+#define __STRUCT_EXEC_OVERRIDE__
+
+#include "../a.out.gnu.h"
+
+#undef N_MAGIC
+#undef N_MACHTYPE
+#undef N_FLAGS
+#undef N_SET_INFO
+#undef N_SET_MAGIC
+#undef N_SET_MACHTYPE
+#undef N_SET_FLAGS
+
+#define N_MAGIC(exec) ((exec) . a_magic)
+#define N_MACHTYPE(exec) ((exec) . a_machtype)
+#define N_SET_MAGIC(exec, magic) (((exec) . a_magic) = (magic))
+#define N_SET_MACHTYPE(exec, machtype) (((exec) . a_machtype) = (machtype))
+
+#undef N_BADMAG
+#define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x)))
+
+#define _N_BADMACH(x)                                                  \
+(((N_MACHTYPE (x)) != HP9000S200_ID) &&                                        \
+ ((N_MACHTYPE (x)) != HP98x6_ID))
+
+#define HP98x6_ID 0x20A
+#define HP9000S200_ID 0x20C
+
+#undef _N_HDROFF
+#define _N_HDROFF(x) (SEGMENT_SIZE - (sizeof (struct exec)))
+
+#define SEGMENT_SIZE 0x1000
+
+#endif /* __GNU_EXEC_MACROS__ */
diff --git a/readline/ChangeLog b/readline/ChangeLog
new file mode 100644 (file)
index 0000000..5136177
--- /dev/null
@@ -0,0 +1,82 @@
+Sun Mar 11 04:32:03 1990  Brian Fox  (bfox at gnuwest.fsf.org)
+
+       * Signals are now supposedly handled inside of SYSV compilation.
+
+Wed Jan 17 19:24:09 1990  Brian Fox  (bfox at sbphy.ucsb.edu)
+
+       * history.c: history_expand (); fixed overwriting memory error,
+       added needed argument to call to get_history_event ().
+
+Thu Jan 11 10:54:04 1990  Brian Fox  (bfox at sbphy.ucsb.edu)
+
+       * readline.c, readline.h: added rl_show_star to control the
+       display of an asterisk on modified history lines.
+
+Thu Jan  4 10:38:05 1990  Brian Fox  (bfox at sbphy.ucsb.edu)
+
+       * readline.c: start_insert ().  Only use IC if we don't have an im
+       capability.
+
+Fri Sep  8 09:00:45 1989  Brian Fox  (bfox at aurel)
+
+       * readline.c: rl_prep_terminal ().  Only turn on 8th bit
+         as meta-bit iff the terminal is not using parity.
+
+Sun Sep  3 08:57:40 1989  Brian Fox  (bfox at aurel)
+
+       * readline.c: start_insert ().  Uses multiple
+         insertion call in cases where that makes sense.
+
+         rl_insert ().  Read type-ahead buffer for additional
+         keys that are bound to rl_insert, and insert them
+         all at once.  Make insertion of single keys given
+         with an argument much more efficient.
+
+Tue Aug  8 18:13:57 1989  Brian Fox  (bfox at aurel)
+
+       * readline.c: Changed handling of EOF.  readline () returns
+        (char *)EOF or consed string.  The EOF character is read from the
+        tty, or if the tty doesn't have one, defaults to C-d.
+
+       * readline.c: Added support for event driven programs.
+         rl_event_hook is the address of a function you want called
+         while Readline is waiting for input.
+
+       * readline.c: Cleanup time.  Functions without type declarations
+         do not use return with a value.
+
+       * history.c: history_expand () has new variable which is the
+         characters to ignore immediately following history_expansion_char.
+
+Sun Jul 16 08:14:00 1989  Brian Fox  (bfox at aurel)
+
+       * rl_prep_terminal ()
+         BSD version turns off C-s, C-q, C-y, C-v.
+
+       * readline.c -- rl_prep_terminal ()
+         SYSV version hacks readline_echoing_p.
+         BSD version turns on passing of the 8th bit for the duration
+         of reading the line.
+
+Tue Jul 11 06:25:01 1989  Brian Fox  (bfox at aurel)
+
+       * readline.c: new variable rl_tilde_expander.
+         If non-null, this contains the address of a function to call if
+         the standard meaning for expanding a tilde fails.  The function is
+         called with the text sans tilde (as in "foo"), and returns a
+         malloc()'ed string which is the expansion, or a NULL pointer if
+         there is no expansion. 
+
+       * readline.h - new file chardefs.h
+         Separates things that only readline.c needs from the standard
+         header file publishing interesting things about readline.
+
+       * readline.c:
+         readline_default_bindings () now looks at terminal chararacters
+         and binds those as well.
+
+Wed Jun 28 20:20:51 1989  Brian Fox  (bfox at aurel)
+
+       * Made readline and history into independent libraries.
+
+
diff --git a/readline/history.texinfo b/readline/history.texinfo
new file mode 100755 (executable)
index 0000000..1e619e1
--- /dev/null
@@ -0,0 +1,194 @@
+\input texinfo.tex
+@setfilename history.info
+
+@ifinfo
+This file documents the GNU History library.
+
+Copyright (C) 1988 Free Software Foundation, Inc.
+Authored by Brian Fox.
+
+Permission is granted to make and distribute verbatim copies of this manual
+provided the copyright notice and this permission notice are preserved on
+all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+GNU Copyright statement is available to the distributee, and provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@node Top, Introduction, , (DIR)
+
+This document describes the GNU History library, a programming tool that
+provides a consistent user interface for recalling lines of previously
+typed input.
+
+@menu
+* Introduction::       What is the GNU History library for?
+* Interactive Use::    What it feels like using History as a user.
+* Programming::                How to use History in your programs.
+@end menu
+
+@node Introduction, Interactive Use, , Top
+@unnumbered Introduction
+
+Many programs read input from the user a line at a time.  The GNU history
+library is able to keep track of those lines, associate arbitrary data with
+each line, and utilize information from previous lines in making up new
+ones.
+
+The programmer using the History library has available to him functions for
+remembering lines on a history stack, associating arbitrary data with a
+line, removing lines from the stack, searching through the stack for a
+line containing an arbitrary text string, and referencing any line on the
+stack directly.  In addition, a history @dfn{expansion} function is
+available which provides for a consistent user interface across many
+different programs.
+
+The end-user using programs written with the History library has the
+benifit of a consistent user interface, with a set of well-known commands
+for manipulating the text of previous lines and using that text in new
+commands.  The basic history manipulation commands are similar to the
+history substitution used by Csh.
+
+If the programmer desires, he can use the Readline library, which includes
+history manipulation by default, and has the added advantage of Emacs style
+command line editing.
+
+@node Interactive Use, Programming, Introduction, Top
+@chapter Interactive Use
+
+@section History Expansion
+@cindex expansion
+
+The History library provides a history expansion feature that is similar to
+the history expansion in Csh.  The following text describes what syntax
+features are available.
+
+History expansion takes place in two parts.  The first is to determine
+which line from the previous history should be used during substitution.
+The second is to select portions of that line for inclusion into the
+current one.  The line selected from the previous history is called the
+@dfn{event}, and the portions of that line that are acted upon are called
+@dfn{words}.  The line is broken into words in the same fashion that the
+Bash shell does, so that several English (or Unix) words surrounded by
+quotes are considered as one word.
+
+@menu
+* Event Designators::  How to specify which history line to use.
+* Word Designators::   Specifying which words are of interest.
+* Modifiers::          Modifying the results of susbstitution.
+@end menu
+
+@node Event Designators, Word Designators, , Interactive Use
+@subsection Event Designators
+@cindex event designators
+
+An event designator is a reference to a command line entry in the history
+list.
+
+@table @var
+
+@item !
+Start a history subsititution, except when followed by a @key{SPC},
+@key{TAB}, @key{RET}, @key{=} or @key{(}.
+
+@item !!
+Refer to the previous command.  This is a synonym for @code{!-1}.
+
+@item !n
+Refer to command line @var{n}.
+
+@item !-n
+Refer to the current command line minus @var{n}.
+
+@item !string
+Refer to the most recent command starting with @var{string}.
+
+@item !?string[?]
+Refer to the most recent command containing @var{string}.
+
+@end table
+
+@node Word Designators, Modifiers, Event Designators, Interactive Use
+@subsection Word Designators
+
+A @key{:} separates the event specification from the word designator.  It
+can be omitted if the word designator begins with a @key{^}, @key{$},
+@key{*} or @key{%}.  Words are numbered from the beginning of the line,
+with the first word being denoted by a 0 (zero).
+
+@table @asis
+
+@item @var{0} (zero)
+The zero'th word.  For many applications, this is the command word.
+
+@item n
+The @var{n}'th word.
+
+@item @var{^}
+The first argument.  that is, word 1.
+
+@item @var{$}
+The last argument.
+
+@item @var{%}
+The word matched by the most recent @code{?string?} search.
+
+@item @var{x}-@var{y}
+A range of words; @code{-@var{y}} is equivalent to @code{0-@var{y}}.
+
+@item @var{*}
+All of the words, excepting the zero'th.  This is a synonym for @samp{1-$}.
+It is not an error to use @samp{*} if there is just one word in the event.
+The empty string is returned in that case.
+
+@end table
+
+@node Modifiers, , Word Designators, Interactive Use
+@subsection Modifiers
+
+After the optional word designator, you can add a sequence of one or more
+of the following modifiers, each preceded by a @key{:}.
+
+@table @code
+
+@item #
+The entire command line typed so far.  This means the current command,
+not the previous command, so it really isn't a word designator, and doesn't
+belong in this section.
+
+@item h
+Remove a trailing pathname component, leaving only the head.
+
+@item r
+Remove a trailing suffix of the form ".xxx", leaving the basename (root).
+
+@item e
+Remove all but the suffix (end).
+
+@item t
+Remove all leading  pathname  components (before the last slash), leaving
+the tail.
+
+@item p
+Print the new command but do not execute it.  This takes effect
+immediately, so it should be the last specifier on the line.
+
+@end table
+
+@node Programming, , Interactive Use, Top
+@chapter Programming
+
+@bye
diff --git a/readline/readline.texinfo b/readline/readline.texinfo
new file mode 100755 (executable)
index 0000000..36fe7a9
--- /dev/null
@@ -0,0 +1,434 @@
+\input texinfo    @c -*-texinfo-*-
+@comment %**start of header (This is for running Texinfo on a region.)
+@setfilename readline.info
+@settitle Line Editing Commands
+@comment %**end of header (This is for running Texinfo on a region.)
+@synindex fn vr
+
+@iftex
+@comment finalout
+@end iftex
+
+@ifinfo
+This document describes the GNU Readline Library, a utility for aiding
+in the consitency of user interface across discrete programs that need
+to provide a command line interface.
+
+Copyright (C) 1988 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+pare preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@setchapternewpage odd
+@titlepage
+@sp 11
+@center @titlefont{GNU Readline Library}
+@sp 2
+@center by Brian Fox
+@sp 2
+@center Version 1.0
+@sp 2
+@center February 1989
+
+@comment   Include the Distribution inside the titlepage environment so
+@c that headings are turned off. 
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1989 Free Software Foundation, Inc.
+
+@sp 2
+This document describes the GNU Readline Library, a utility for aiding
+in the consistency of user interface across discrete programs that need
+to provide a command line interface.
+@sp 2
+
+Published by the Free Software Foundation @*
+675 Massachusetts Avenue, @*
+Cambridge, MA 02139 USA
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+
+@end titlepage
+
+@node Top, Readline Top, ,(DIR)
+@chapter GNU Readline Library
+
+@ifinfo
+This document describes the GNU Readline Library, a utility for aiding
+in the consistency of user interface across discrete programs that need
+to provide a command line interface.
+@end ifinfo
+
+@menu
+* Readline Top::       GNU Readline User's Manual
+* Readline Technical:: GNU Readline Programmer's Manual
+@end menu
+@include inc-readline.texinfo
+@node Readline Technical, , Top, Top
+@chapter Readline Programmer's Manual
+
+This manual describes the interface between the GNU Readline Library and
+user programs.  If you are a programmer, and you wish to include the
+features found in GNU Readline in your own programs, such as completion,
+line editing, and interactive history manipulation, this documentation
+is for you.
+
+@menu
+* Default Behaviour::  Using the default behaviour of Readline.
+* Custom Functions::   Adding your own functions to Readline.
+* Custom Completers::  Supplanting or supplementing Readline's
+                       completion functions.
+* Variable Index::     Index of externally tweakable variables.
+@end menu
+
+@node Default Behaviour, Custom Functions, Readline Technical, Readline Technical
+@section Default Behaviour
+
+Many programs provide a command line interface, such as @code{mail},
+@code{ftp}, and @code{sh}.  For such programs, the default behaviour of
+Readline is sufficient.  This section describes how to use Readline in
+the simplest way possible, perhaps to replace calls in your code to
+@code{gets ()}.
+
+@findex readline ()
+@cindex readline, function
+The function @code{readline} prints a prompt and then reads and returns
+a single line of text from the user.  The line which @code{readline ()}
+returns is allocated with @code{malloc ()}; you should @code{free ()}
+the line when you are done with it.  The declaration in ANSI C is
+
+@example
+@code{char *readline (char *@var{prompt});}
+@end example
+or, preferably,
+@example
+@code{#include <readline/readline.h>}
+@end example
+
+So, one might say
+@example
+@code{char *line = readline ("Enter a line: ");}
+@end example
+in order to read a line of text from the user.
+
+The line which is returned has the final newline removed, so only the
+text of the line remains.
+
+If readline encounters an EOF while reading the line, and the line is
+empty at that point, then @code{(char *)NULL} is returned.  Otherwise,
+the line is ended just as if a newline was typed.
+
+If you want the user to be able to get at the line later, (with
+@key{C-p} for example), you must call @code{add_history ()} to save the
+line away in a @dfn{history} list of such lines.
+
+@example
+@code{add_history (line)};
+@end example
+
+If you use @code{add_history ()}, you should also
+@code{#include <readline/history.h>}
+For full details on the GNU History Library, see the associated manual.
+
+It is polite to avoid saving empty lines on the history list, since
+no one has a burning need to reuse a blank line.  Here is a function
+which usefully replaces the standard @code{gets ()} library function:
+
+@example
+#include <readline/readline.h>
+#include <readline/history.h>
+
+/* A static variable for holding the line. */
+static char *my_gets_line = (char *)NULL;
+
+/* Read a string, and return a pointer to it.  Returns NULL on EOF. */
+char *
+my_gets ()
+@{
+  /* If the buffer has already been allocated, return the memory
+     to the free pool. */
+  if (my_gets_line != (char *)NULL)
+    free (my_gets_line);
+
+  /* Get a line from the user. */
+  my_gets_line = readline ("");
+
+  /* If the line has any text in it, save it on the history. */
+  if (my_get_line && *my_gets_line)
+    add_history (my_gets_line);
+
+  return (my_gets_line);
+@}
+@end example
+
+The above code gives the user the default behaviour of @key{TAB}
+completion: completion on file names.  If you do not want readline to
+complete on filenames, you can change the binding of the @key{TAB} key
+with @code{rl_bind_key ()}.
+
+@findex rl_bind_key ()
+
+@example
+@code{int rl_bind_key (int @var{key}, (int (*)())@var{function});}
+@end example
+
+@code{rl_bind_key ()} takes 2 arguments; @var{key} is the character that
+you want to bind, and @var{function} is the address of the function to
+run when @var{key} is pressed.  Binding @key{TAB} to @code{rl_insert ()}
+makes @key{TAB} just insert itself.
+
+@code{rl_bind_key ()} returns non-zero if @var{key} is not a valid
+ASCII character code (between 0 and 255).
+
+@example
+@code{rl_bind_key ('\t', rl_insert);}
+@end example
+
+@node Custom Functions, Custom Completers, Default Behaviour, Readline Technical
+@section Custom Functions
+
+Readline provides a great many functions for manipulating the text of
+the line.  But it isn't possible to anticipate the needs of all
+programs.  This section describes the various functions and variables
+defined in within the Readline library which allow a user program to add
+customized functionality to Readline.
+
+@menu
+* The Function Type::  C declarations to make code readable.
+* Function Naming::    How to give a function you write a name.
+* Keymaps::            Making keymaps.
+* Binding Keys::       Changing Keymaps.
+* Function Writing::   Variables and calling conventions.
+* Allowing Undoing::   How to make your functions undoable.
+@end menu
+
+@node The Function Type, Function Naming, Custom Functions, Custom Functions
+For the sake of readabilty, we declare a new type of object, called
+@dfn{Function}.  `Function' is a C language function which returns an
+@code{int}.  The type declaration for `Function' is:
+
+@code{typedef int Function ();}
+
+The reason for declaring this new type is to make it easier to discuss
+pointers to C functions.  Let us say we had a variable called @var{func}
+which was a pointer to a function.  Instead of the classic C declaration
+
+@code{int (*)()func;}
+
+we have
+
+@code{Function *func;}
+
+@node Function Naming, Keymaps, The Function Type, Custom Functions
+@subsection Naming a Function
+
+The user can dynamically change the bindings of keys while using
+Readline.  This is done by representing the function with a descriptive
+name.  The user is able to type the descriptive name when referring to
+the function.  Thus, in an init file, one might find
+
+@example
+Meta-Rubout:   backward-kill-word
+@end example
+
+This binds @key{Meta-Rubout} to the function @emph{descriptively} named
+@code{backward-kill-word}.  You, as a programmer, should bind the
+functions you write to descriptive names as well.  Here is how to do
+that.
+
+@defun rl_add_defun (char *name, Function *function, int key)
+Add @var{name} to the list of named functions.  Make @var{function} be
+the function that gets called.  If @var{key} is not -1, then bind it to
+@var{function} using @code{rl_bind_key ()}.
+@end defun
+
+Using this function alone is sufficient for most applications.  It is
+the recommended way to add a few functions to the default functions that
+Readline has built in already.  If you need to do more or different
+things than adding a function to Readline, you may need to use the
+underlying functions described below.
+
+@node Keymaps, Binding Keys, Function Naming, Custom Functions
+@subsection Selecting a Keymap
+
+Key bindings take place on a @dfn{keymap}.  The keymap is the
+association between the keys that the user types and the functions that
+get run.  You can make your own keymaps, copy existing keymaps, and tell
+Readline which keymap to use.
+
+@defun rl_make_bare_keymap ()
+Returns a new, empty keymap.  The space for the keymap is allocated with
+@code{malloc ()}; you should @code{free ()} it when you are done.
+@end defun
+
+@defun rl_copy_keymap (Keymap map)
+Return a new keymap which is a copy of @var{map}.
+@end defun
+
+@defun rl_make_keymap ()
+Return a new keymap with the printing characters bound to rl_insert,
+the lowercase Meta characters bound to run their equivalents, and
+the Meta digits bound to produce numeric arguments.
+@end defun
+
+@node Binding Keys, Function Writing, Keymaps, Custom Functions
+@subsection Binding Keys
+
+You associate keys with functions through the keymap.  Here are
+the functions for doing that.
+
+@defun rl_bind_key (int key, Function *function)
+Binds @var{key} to @var{function} in the currently selected keymap.
+Returns non-zero in the case of an invalid @var{key}.
+@end defun
+
+@defun rl_bind_key_in_map (int key, Function *function, Keymap map)
+Bind @var{key} to @var{function} in @var{map}.  Returns non-zero in the case
+of an invalid @var{key}.
+@end defun
+
+@defun rl_unbind_key (int key)
+Make @var{key} do nothing in the currently selected keymap.
+Returns non-zero in case of error.
+@end defun
+
+@defun rl_unbind_key_in_map (int key, Keymap map)
+Make @var{key} be bound to the null function in @var{map}.
+Returns non-zero in case of error.
+@end defun
+
+@node Function Writing, Allowing Undoing, Binding Keys, Custom Functions
+@subsection Writing a New Function
+
+In order to write new functions for Readline, you need to know the
+calling conventions for keyboard invoked functions, and the names of the
+variables that describe the current state of the line gathered so far.
+
+@defvar char *rl_line_buffer
+This is the line gathered so far.  You are welcome to modify the
+contents of this, but see Undoing, below.
+@end defvar
+
+@defvar int rl_point
+The offset of the current cursor position in @var{rl_line_buffer}.
+@end defvar
+
+@defvar int rl_end
+The number of characters present in @code{rl_line_buffer}.  When
+@code{rl_point} is at the end of the line, then @code{rl_point} and
+@code{rl_end} are equal.
+@end defvar
+
+The calling sequence for a command @code{foo} looks like
+
+@example
+@code{foo (count, key)}
+@end example
+
+where @var{count} is the numeric argument (or 1 if defaulted) and
+@var{key} is the key that invoked this function.
+
+It is completely up to the function as to what should be done with the
+numeric argument; some functions use it as a repeat count, other
+functions as a flag, and some choose to ignore it.  In general, if a
+function uses the numeric argument as a repeat count, it should be able
+to do something useful with a negative argument as well as a positive
+argument.  At the very least, it should be aware that it can be passed a
+negative argument.
+
+@node Allowing Undoing, , Function Writing, Custom Functions
+@subsection Allowing Undoing
+
+Supporting the undo command is a painless thing to do, and makes your
+function much more useful to the end user.  It is certainly easy to try
+something if you know you can undo it.  I could use an undo function for
+the stock market.
+
+If your function simply inserts text once, or deletes text once, and it
+calls @code{rl_insert_text ()} or @code{rl_delete_text ()} to do it, then
+undoing is already done for you automatically, and you can safely skip
+this section.
+
+If you do multiple insertions or multiple deletions, or any combination
+of these operations, you will want to group them together into one
+operation.  This can be done with @code{rl_begin_undo_group ()} and 
+@code{rl_end_undo_group ()}.
+
+@defun rl_begin_undo_group ()
+Begins saving undo information in a group construct.  The undo
+information usually comes from calls to @code{rl_insert_text ()} and
+@code{rl_delete_text ()}, but they could be direct calls to
+@code{rl_add_undo ()}.
+@end defun
+
+@defun rl_end_undo_group ()
+Closes the current undo group started with @code{rl_begin_undo_group
+()}.  There should be exactly one call to @code{rl_end_undo_group ()}
+for every call to @code{rl_begin_undo_group ()}.
+@end defun
+
+Finally, if you neither insert nor delete text, but directly modify the
+existing text (e.g. change its case), you call @code{rl_modifying ()}
+once, just before you modify the text.  You must supply the indices of
+the text range that you are going to modify.
+
+@defun rl_modifying (int start, int end)
+Tell Readline to save the text between @var{start} and @var{end} as a
+single undo unit.  It is assumed that subsequent to this call you will
+modify that range of text in some way.
+@end defun
+
+@subsection An Example
+
+Let us say that we are actually going to put an example here.
+
+@node Custom Completers, Variable Index, Custom Functions, Readline Technical
+
+Typically, a program that reads commands from the user has a way of
+disambiguating between commands and data.  If your program is one of
+these, then it can provide completion for either commands, or data, or
+both commands and data.  The following sections describe how your
+program and Readline cooperate to provide this service to end users.
+
+@menu
+@end menu
+
+@node Variable Index, , Custom Completers, Readline Technical
+@appendix Variable Index
+@printindex vr
+@contents
+
+@bye
+