aboutsummaryrefslogtreecommitdiff
path: root/gdb/=ns32k.msg
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/=ns32k.msg')
-rw-r--r--gdb/=ns32k.msg1182
1 files changed, 1182 insertions, 0 deletions
diff --git a/gdb/=ns32k.msg b/gdb/=ns32k.msg
new file mode 100644
index 0000000..5268fc7
--- /dev/null
+++ b/gdb/=ns32k.msg
@@ -0,0 +1,1182 @@
+From uwvax!sequent!ogcvax!reed!keith@RUTGERS.EDU Thu Jul 23 21:46:44 1987
+Received: by PREP.AI.MIT.EDU; Thu, 23 Jul 87 21:44:35 EDT
+Received: by RUTGERS.EDU (5.54/1.14) with UUCP
+ id AA04584; Thu, 23 Jul 87 21:42:33 EDT
+Received: from sequent.UUCP by spool.WISC.EDU; Thu, 23 Jul 87 20:36:20 CDT
+Received: from reed.UUCP by ogcvax.OGC.EDU (5.51/OGC_4.6+)
+ id AA05332; Thu, 23 Jul 87 13:31:52 PDT
+Received: by reed.UUCP (5.51/5.17)
+ id AA23265; Thu, 23 Jul 87 11:19:20 PDT
+From: uwvax!sequent!ogcvax!reed!keith@RUTGERS.EDU (Keith Packard)
+Message-Id: <8707231819.AA23265@reed.UUCP>
+To: phr@prep.ai.mit.edu (Paul Rubin)
+Subject: Re: gdb
+In-Reply-To: Your message of Thu, 23 Jul 87 02:06:52 EDT.
+ <8707230603.AA11722@EDDIE.MIT.EDU>
+Date: Thu, 23 Jul 87 11:19:13 PDT
+Status: R
+
+
+Thanks much for the address -- the 2.1 sources that I have do not contain
+any bug reporting address. The only real bug that I found was in
+write_register_bytes in findvar.c:
+
+was:
+
+ bcopy (myaddr, &registers[regbyte], len);
+ if (have_inferior_p ())
+ store_inferior_registers (0);
+
+should be:
+
+ bcopy (myaddr, &registers[regbyte], len);
+ if (have_inferior_p ())
+ store_inferior_registers (-1);
+
+Other than that, most of the porting effort to the 32k was in removing
+references to alloca - the 32k is adamant about not using alloca -- in fact
+someone at tektronix wrote a replacement which accepted another argument
+pointing to the function entry instruction so that the stack could be maimed
+mercilessly... I just replaced them all with malloc and used free at
+judicious times. It's not perfect but it worked fine.
+
+I would upload gdb 2.3 if I could, however I am not on the arpa net. I'll
+probably end up sending GNU a tape.
+
+It's a great debugger, thanks!
+
+ keith packard
+ tektronix!reed!keith
+
+Here are the param files and instruction printer for the 32032:
+
+#!/bin/sh
+# shar: Shell Archiver
+# Run the following text with /bin/sh to create:
+# m-merlin.h
+# n32k-opcode.h
+# n32k-pinsn.c
+sed 's/^X//' << 'SHAR_EOF' > m-merlin.h
+X/* Definitions to make GDB run on a merlin under utek 2.1
+X Copyright (C) 1986, 1987 Free Software Foundation, Inc.
+X
+XGDB is distributed in the hope that it will be useful, but WITHOUT ANY
+XWARRANTY. No author or distributor accepts responsibility to anyone
+Xfor the consequences of using it or for whether it serves any
+Xparticular purpose or works at all, unless he says so in writing.
+XRefer to the GDB General Public License for full details.
+X
+XEveryone is granted permission to copy, modify and redistribute GDB,
+Xbut only under the conditions described in the GDB General Public
+XLicense. A copy of this license is supposed to have been given to you
+Xalong with GDB so you can know your rights and responsibilities. It
+Xshould be in a file named COPYING. Among other things, the copyright
+Xnotice and this notice must be preserved on all copies.
+X
+XIn other words, go ahead and share GDB, but don't try to stop
+Xanyone else from sharing it farther. Help stamp out software hoarding!
+X*/
+X
+X#ifndef ns16000
+X#define ns16000
+X#endif
+X
+X# include <machine/reg.h>
+X
+X/* Define this if the C compiler puts an underscore at the front
+X of external names before giving them to the linker. */
+X
+X#define NAMES_HAVE_UNDERSCORE
+X
+X/* Offset from address of function to start of its code.
+X Zero on most machines. */
+X
+X#define FUNCTION_START_OFFSET 0
+X
+X/* Advance PC across any function entry prologue instructions
+X to reach some "real" code. */
+X
+X#define SKIP_PROLOGUE(pc) \
+X{ register int op = read_memory_integer (pc, 1); \
+X if (op == 0x82) { op = read_memory_integer (pc+2,1); \
+X if ((op & 0x80) == 0) pc += 3; \
+X else if ((op & 0xc0) == 0x80) pc += 4; \
+X else pc += 6; \
+X } \
+X}
+X
+X/* Immediately after a function call, return the saved pc.
+X Can't always go through the frames for this because on some machines
+X the new frame is not set up until the new function executes
+X some instructions. */
+X
+X#define SAVED_PC_AFTER_CALL(frame) \
+X read_memory_integer (read_register (SP_REGNUM), 4)
+X
+X/* This is the amount to subtract from u.u_ar0
+X to get the offset in the core file of the register values. */
+X
+X#define KERNEL_U_ADDR (0xfef000)
+X
+X/* Address of end of stack space. */
+X
+X#define STACK_END_ADDR (0x800000)
+X
+X/* Stack grows downward. */
+X
+X#define INNER_THAN <
+X
+X/* Sequence of bytes for breakpoint instruction. */
+X
+X#define BREAKPOINT {0xf2}
+X
+X/* Amount PC must be decremented by after a breakpoint.
+X This is often the number of bytes in BREAKPOINT
+X but not always. */
+X
+X#define DECR_PC_AFTER_BREAK 0
+X
+X/* Nonzero if instruction at PC is a return instruction. */
+X
+X#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12)
+X
+X/* Return 1 if P points to an invalid floating point value. */
+X
+X#define INVALID_FLOAT(p) (0)
+X
+X/* Say how long (ordinary) registers are. */
+X
+X#define REGISTER_TYPE long
+X
+X/* Number of machine registers */
+X
+X#define NUM_REGS 25
+X
+X#define NUM_GENERAL_REGS 8
+X
+X/* Initializer for an array of names of registers.
+X There should be NUM_REGS strings in this initializer. */
+X
+X#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+X "pc", "sp", "fp", "ps", \
+X "fsr", \
+X "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+X "l0", "l1", "l2", "l3", "l4", \
+X }
+X
+X/* Register numbers of various important registers.
+X Note that some of these values are "real" register numbers,
+X and correspond to the general registers of the machine,
+X and some are "phony" register numbers which are too large
+X to be actual register numbers as far as the user is concerned
+X but do serve to get the desired values when passed to read_register. */
+X
+X#define AP_REGNUM FP_REGNUM
+X#define FP_REGNUM 10 /* Contains address of executing stack frame */
+X#define SP_REGNUM 9 /* Contains address of top of stack */
+X#define PC_REGNUM 8 /* Contains program counter */
+X#define PS_REGNUM 11 /* Contains processor status */
+X#define FPS_REGNUM 12 /* Floating point status register */
+X#define FP0_REGNUM 13 /* Floating point register 0 */
+X#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */
+X
+X#define REGISTER_U_ADDR(addr, blockend, regno) \
+X{ \
+X switch (regno) { \
+X case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \
+X addr = blockend + (R0 - regno) * sizeof (int); break; \
+X case PC_REGNUM: \
+X addr = blockend + PC * sizeof (int); break; \
+X case SP_REGNUM: \
+X addr = blockend + SP * sizeof (int); break; \
+X case FP_REGNUM: \
+X addr = blockend + FP * sizeof (int); break; \
+X case PS_REGNUM: \
+X addr = blockend + 12 * sizeof (int); break; \
+X case FPS_REGNUM: \
+X addr = 108; break; \
+X case FP0_REGNUM + 0: case FP0_REGNUM + 1: \
+X case FP0_REGNUM + 2: case FP0_REGNUM + 3: \
+X case FP0_REGNUM + 4: case FP0_REGNUM + 5: \
+X case FP0_REGNUM + 6: case FP0_REGNUM + 7: \
+X addr = 76 + (regno - FP0_REGNUM) * sizeof (float); break; \
+X case LP0_REGNUM + 0: case LP0_REGNUM + 1: \
+X case LP0_REGNUM + 2: case LP0_REGNUM + 3: \
+X addr = 76 + (regno - LP0_REGNUM) * sizeof (double); break; \
+X default: \
+X printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \
+X abort (); \
+X } \
+X}
+X
+X/* Total amount of space needed to store our copies of the machine's
+X register state, the array `registers'. */
+X#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double))
+X
+X/* Index within `registers' of the first byte of the space for
+X register N. */
+X
+X#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \
+X LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4)
+X
+X/* Number of bytes of storage in the actual machine representation
+X for register N. On the 32000, all regs are 4 bytes
+X except for the doubled floating registers. */
+X
+X#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+X
+X/* Number of bytes of storage in the program's representation
+X for register N. On the 32000, all regs are 4 bytes
+X except for the doubled floating registers. */
+X
+X#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
+X
+X/* Largest value REGISTER_RAW_SIZE can have. */
+X
+X#define MAX_REGISTER_RAW_SIZE 8
+X
+X/* Largest value REGISTER_VIRTUAL_SIZE can have. */
+X
+X#define MAX_REGISTER_VIRTUAL_SIZE 8
+X
+X/* Nonzero if register N requires conversion
+X from raw format to virtual format. */
+X
+X#define REGISTER_CONVERTIBLE(N) 0
+X
+X/* Convert data from raw format for register REGNUM
+X to virtual format for register REGNUM. */
+X
+X#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
+X bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+X
+X/* Convert data from virtual format for register REGNUM
+X to raw format for register REGNUM. */
+X
+X#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
+X bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
+X
+X/* Return the GDB type object for the "standard" data type
+X of data in register N. */
+X
+X#define REGISTER_VIRTUAL_TYPE(N) \
+X ((N) >= FP0_REGNUM ? \
+X (N) >= LP0_REGNUM ? \
+X builtin_type_double \
+X : builtin_type_float \
+X : builtin_type_int)
+X
+X/* Describe the pointer in each stack frame to the previous stack frame
+X (its caller). */
+X
+X/* FRAME_CHAIN takes a frame's nominal address
+X and produces the frame's chain-pointer.
+X
+X FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
+X and produces the nominal address of the caller frame.
+X
+X However, if FRAME_CHAIN_VALID returns zero,
+X it means the given frame is the outermost one and has no caller.
+X In that case, FRAME_CHAIN_COMBINE is not used. */
+X
+X/* In the case of the Merlin, the frame's nominal address is the FP value,
+X and at that address is saved previous FP value as a 4-byte word. */
+X
+X#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
+X
+X#define FRAME_CHAIN_VALID(chain, thisframe) \
+X (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
+X
+X#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
+X
+X/* Define other aspects of the stack frame. */
+X
+X#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
+X
+X/* compute base of arguments */
+X#define FRAME_ARGS_ADDRESS(fi) ((fi).frame)
+X
+X#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame)
+X
+X/* Return number of args passed to a frame.
+X Can return -1, meaning no way to tell. */
+X
+X#define FRAME_NUM_ARGS(numargs, fi) \
+X{ CORE_ADDR pc; \
+X int insn; \
+X int addr_mode; \
+X int width; \
+X \
+X pc = FRAME_SAVED_PC (fi.frame); \
+X insn = read_memory_integer (pc,2); \
+X addr_mode = (insn >> 11) & 0x1f; \
+X insn = insn & 0x7ff; \
+X if ((insn & 0x7fc) == 0x57c && \
+X addr_mode == 0x14) { /* immediate */ \
+X if (insn == 0x57c) /* adjspb */ \
+X width = 1; \
+X else if (insn == 0x57d) /* adjspw */ \
+X width = 2; \
+X else if (insn == 0x57f) /* adjspd */ \
+X width = 4; \
+X numargs = read_memory_integer (pc+2,width); \
+X if (width > 1) \
+X flip_bytes (&numargs, width); \
+X numargs = - sign_extend (numargs, width*8) / 4; \
+X } else { \
+X numargs = -1; \
+X } \
+X}
+X
+X/* Return number of bytes at start of arglist that are not really args. */
+X
+X#define FRAME_ARGS_SKIP 8
+X
+X/* Put here the code to store, into a struct frame_saved_regs,
+X the addresses of the saved registers of frame described by FRAME_INFO.
+X This includes special registers such as pc and fp saved in special
+X ways in the stack frame. sp is even more special:
+X the address we return for it IS the sp for the next frame. */
+X
+X#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+X{ \
+X int regmask,regnum; \
+X int localcount; \
+X CORE_ADDR enter_addr; \
+X CORE_ADDR next_addr; \
+X \
+X enter_addr = get_pc_function_start ((frame_info).pc); \
+X regmask = read_memory_integer (enter_addr+1, 1); \
+X localcount = n32k_localcount (enter_addr); \
+X next_addr = (frame_info).frame + localcount; \
+X for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \
+X (frame_saved_regs).regs[regnum] = (regmask & 1) ? \
+X (next_addr -= 4) : 0; \
+X (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4; \
+X (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
+X (frame_saved_regs).regs[FP_REGNUM] = (read_memory_integer \
+X ((frame_info).frame, 4)); \
+X}
+X
+X/* Things needed for making the inferior call functions. */
+X
+X/* Push an empty stack frame, to record the current PC, etc. */
+X
+X#define PUSH_DUMMY_FRAME \
+X{ register CORE_ADDR sp = read_register (SP_REGNUM);\
+X register int regnum; \
+X sp = push_word (sp, read_register (PC_REGNUM)); \
+X sp = push_word (sp, read_register (FP_REGNUM)); \
+X write_register (FP_REGNUM, sp); \
+X for (regnum = 0; regnum < 8; regnum++) \
+X sp = push_word (sp, read_register (regnum)); \
+X write_register (SP_REGNUM, sp); \
+X}
+X
+X/* Discard from the stack the innermost frame, restoring all registers. */
+X
+X#define POP_FRAME \
+X{ register CORE_ADDR fp = read_register (FP_REGNUM); \
+X register int regnum; \
+X struct frame_saved_regs fsr; \
+X struct frame_info fi; \
+X fi = get_frame_info (fp); \
+X get_frame_saved_regs (&fi, &fsr); \
+X for (regnum = 0; regnum < 8; regnum++) \
+X if (fsr.regs[regnum]) \
+X write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
+X write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
+X write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
+X write_register (SP_REGNUM, fp + 8); \
+X}
+X
+X/* This sequence of words is the instructions
+X enter 0xff,0 82 ff 00
+X jsr @0x00010203 7f ae c0 01 02 03
+X adjspd 0x69696969 7f a5 01 02 03 04
+X bpt f2
+X Note this is 16 bytes. */
+X
+X#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 }
+X
+X#define CALL_DUMMY_START_OFFSET 3
+X#define CALL_DUMMY_LENGTH 16
+X#define CALL_DUMMY_ADDR 5
+X#define CALL_DUMMY_NARGS 11
+X
+X/* Insert the specified number of args and function address
+X into a call sequence of the above form stored at DUMMYNAME. */
+X
+X#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
+X{ \
+X int flipped; \
+X flipped = fun | 0xc0000000; \
+X flip_bytes (&flipped, 4); \
+X *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \
+X flipped = - nargs * 4; \
+X flip_bytes (&flipped, 4); \
+X *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \
+X}
+X
+X#ifdef notdef
+X/* Interface definitions for kernel debugger KDB. */
+X
+X/* Map machine fault codes into signal numbers.
+X First subtract 0, divide by 4, then index in a table.
+X Faults for which the entry in this table is 0
+X are not handled by KDB; the program's own trap handler
+X gets to handle then. */
+X
+X#define FAULT_CODE_ORIGIN 0
+X#define FAULT_CODE_UNITS 4
+X#define FAULT_TABLE \
+X{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
+X 0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
+X 0, 0, 0, 0, 0, 0, 0, 0}
+X
+X/* Start running with a stack stretching from BEG to END.
+X BEG and END should be symbols meaningful to the assembler.
+X This is used only for kdb. */
+X
+X#define INIT_STACK(beg, end) \
+X{ asm (".globl end"); \
+X asm ("movl $ end, sp"); \
+X asm ("clrl fp"); }
+X
+X/* Push the frame pointer register on the stack. */
+X#define PUSH_FRAME_PTR \
+X asm ("pushl fp");
+X
+X/* Copy the top-of-stack to the frame pointer register. */
+X#define POP_FRAME_PTR \
+X asm ("movl (sp), fp");
+X
+X/* After KDB is entered by a fault, push all registers
+X that GDB thinks about (all NUM_REGS of them),
+X so that they appear in order of ascending GDB register number.
+X The fault code will be on the stack beyond the last register. */
+X
+X#define PUSH_REGISTERS \
+X{ asm ("pushl 8(sp)"); \
+X asm ("pushl 8(sp)"); \
+X asm ("pushal 0x14(sp)"); \
+X asm ("pushr $037777"); }
+X
+X/* Assuming the registers (including processor status) have been
+X pushed on the stack in order of ascending GDB register number,
+X restore them and return to the address in the saved PC register. */
+X
+X#define POP_REGISTERS \
+X{ asm ("popr $037777"); \
+X asm ("subl2 $8,(sp)"); \
+X asm ("movl (sp),sp"); \
+X asm ("rei"); }
+X#endif
+SHAR_EOF
+sed 's/^X//' << 'SHAR_EOF' > n32k-opcode.h
+X/* n32k-opcode.h */
+X
+X#ifndef n32k_opcodeT
+X#define n32k_opcodeT int
+X#endif /* no n32k_opcodeT */
+X
+Xstruct not_wot /* n32k opcode table: wot to do with this */
+X /* particular opcode */
+X{
+X int obits; /* number of opcode bits */
+X int ibits; /* number of instruction bits */
+X n32k_opcodeT code; /* op-code (may be > 8 bits!) */
+X char *args; /* how to compile said opcode */
+X};
+X
+Xstruct not /* n32k opcode text */
+X{
+X char * name; /* opcode name: lowercase string [key] */
+X struct not_wot detail; /* rest of opcode table [datum] */
+X};
+X
+X/* F : 32 bit float
+X * L : 64 bit float
+X * B : byte
+X * W : word
+X * D : double-word
+X * Q : quad-word
+X * d : displacement
+X * q : quick
+X * i : immediate (8 bits)
+X * r : register number (3 bits)
+X * p : displacement - pc relative addressing
+X*/
+Xstatic struct not
+Xnotstrs[] =
+X{
+X{ "absf", 14,24, 0x35be, "1F2F" },
+X{ "absl", 14,24, 0x34be, "1L2L" },
+X{ "absb", 14,24, 0x304e, "1B2B" },
+X{ "absw", 14,24, 0x314e, "1W2W" },
+X{ "absd", 14,24, 0x334e, "1D2D" },
+X{ "acbb", 7,16, 0x4c, "2B1q3p" },
+X{ "addf", 14,24, 0x01be, "1F2F" },
+X{ "addl", 14,24, 0x00be, "1L2L" },
+X{ "addb", 6,16, 0x00, "1B2B" },
+X{ "addw", 6,16, 0x01, "1W2W" },
+X{ "addd", 6,16, 0x03, "1D2D" },
+X{ "addcb", 6,16, 0x10, "1B2B" },
+X{ "addcw", 6,16, 0x11, "1W2W" },
+X{ "addcd", 6,16, 0x13, "1D2D" },
+X{ "addpb", 14,24, 0x3c4e, "1B2B" },
+X{ "addpw", 14,24, 0x3d4e, "1W2W" },
+X{ "addpd", 14,24, 0x3f4e, "1D2D" },
+X{ "addqb", 7,16, 0x0c, "2B1q" },
+X{ "addqw", 7,16, 0x0d, "2W1q" },
+X{ "addqd", 7,16, 0x0f, "2D1q" },
+X{ "addr", 6,16, 0x27, "1D2D" },
+X{ "adjspb", 11,16, 0x057c, "1B" },
+X{ "adjspw", 11,16, 0x057d, "1W" },
+X{ "adjspd", 11,16, 0x057f, "1D" },
+X{ "andb", 6,16, 0x28, "1B2B" },
+X{ "andw", 6,16, 0x29, "1W2W" },
+X{ "andd", 6,16, 0x2b, "1D2D" },
+X{ "ashb", 14,24, 0x044e, "1B2B" },
+X{ "ashw", 14,24, 0x054e, "1B2W" },
+X{ "ashd", 14,24, 0x074e, "1B2D" },
+X{ "beq", 8,8, 0x0a, "1p" },
+X{ "bne", 8,8, 0x1a, "1p" },
+X{ "bcs", 8,8, 0x2a, "1p" },
+X{ "bcc", 8,8, 0x3a, "1p" },
+X{ "bhi", 8,8, 0x4a, "1p" },
+X{ "bls", 8,8, 0x5a, "1p" },
+X{ "bgt", 8,8, 0x6a, "1p" },
+X{ "ble", 8,8, 0x7a, "1p" },
+X{ "bfs", 8,8, 0x8a, "1p" },
+X{ "bfc", 8,8, 0x9a, "1p" },
+X{ "blo", 8,8, 0xaa, "1p" },
+X{ "bhs", 8,8, 0xba, "1p" },
+X{ "blt", 8,8, 0xca, "1p" },
+X{ "bge", 8,8, 0xda, "1p" },
+X{ "bicb", 6,16, 0x08, "1B2B" },
+X{ "bicw", 6,16, 0x09, "1W2W" },
+X{ "bicd", 6,16, 0x0b, "1D2D" },
+X{ "bicpsrb", 11,16, 0x17c, "1B" },
+X{ "bicpsrw", 11,16, 0x17d, "1W" },
+X{ "bispsrb", 11,16, 0x37c, "1B" },
+X{ "bispsrw", 11,16, 0x37d, "1W" },
+X{ "bpt", 8,8, 0xf2, "" },
+X{ "br", 8,8, 0xea, "1p" },
+X{ "bsr", 8,8, 0x02, "1p" },
+X{ "caseb", 11,16, 0x77c, "1B" },
+X{ "casew", 11,16, 0x77d, "1W" },
+X{ "cased", 11,16, 0x77f, "1D" },
+X{ "cbitb", 14,24, 0x084e, "1B2D" },
+X{ "cbitw", 14,24, 0x094e, "1W2D" },
+X{ "cbitd", 14,24, 0x0b4e, "1D2D" },
+X{ "cbitib", 14,24, 0x0c4e, "1B2D" },
+X{ "cbitiw", 14,24, 0x0d4e, "1W2D" },
+X{ "cbitid", 14,24, 0x0f4e, "1D2D" },
+X{ "checkb", 11,24, 0x0ee, "2A3B1r" },
+X{ "checkw", 11,24, 0x1ee, "2A3B1r" },
+X{ "checkd", 11,24, 0x3ee, "2A3D1r" },
+X{ "cmpf", 14,24, 0x09be, "1F2F" },
+X{ "cmpl", 14,24, 0x08be, "1L2L" },
+X{ "cmpb", 6,16, 0x04, "1B2B" },
+X{ "cmpw", 6,16, 0x05, "1W2W" },
+X{ "cmpd", 6,16, 0x07, "1D2D" },
+X{ "cmpmb", 14,24, 0x04ce, "1D2D3d" },
+X{ "cmpmw", 14,24, 0x05ce, "1D2D3d" },
+X{ "cmpmd", 14,24, 0x07ce, "1D2D3d" },
+X{ "cmpqb", 7,16, 0x1c, "2B1q" },
+X{ "cmpqw", 7,16, 0x1d, "2W1q" },
+X{ "cmpqd", 7,16, 0x1f, "2D1q" },
+X{ "cmpsb", 16,16, 0x040e, "i" },
+X{ "cmpsw", 16,16, 0x050e, "i" },
+X{ "cmpsd", 16,16, 0x070e, "i" },
+X{ "cmpst", 16,16, 0x840e, "i" },
+X{ "comb", 14,24, 0x344e, "1B2B" },
+X{ "comw", 14,24, 0x354e, "1W2W" },
+X{ "comd", 14,24, 0x374e, "1D2D" },
+X{ "cvtp", 11,24, 0x036e, "2D3D1r" },
+X{ "cxp", 8,8, 0x22, "1p" },
+X{ "cxpd", 11,16, 0x07f, "1D" },
+X{ "deib", 14,24, 0x2cce, "1B2W" },
+X{ "deiw", 14,24, 0x2cce, "1W2D" },
+X{ "deid", 14,24, 0x2cce, "1D2Q" },
+X{ "dia", 8,8, 0xc2, "" },
+X{ "divf", 14,24, 0x21be, "1F2F" },
+X{ "divl", 14,24, 0x20be, "1L2L" },
+X{ "divb", 14,24, 0x3cce, "1B2B" },
+X{ "divw", 14,24, 0x3dce, "1W2W" },
+X{ "divd", 14,24, 0x3fce, "1D2D" },
+X{ "enter", 8,8, 0x82, "1i2d" },
+X{ "exit", 8,8, 0x92, "1i" },
+X{ "extb", 11,24, 0x02e, "2D3B1r4d" },
+X{ "extw", 11,24, 0x12e, "2D3W1r4d" },
+X{ "extd", 11,24, 0x32e, "2D3D1r4d" },
+X{ "extsb", 14,24, 0x0cce, "1D2B3i" },
+X{ "extsw", 14,24, 0x0dce, "1D2W3i" },
+X{ "extsd", 14,24, 0x0fce, "1D2D3i" },
+X{ "ffsb", 14,24, 0x046e, "1B2B" },
+X{ "ffsw", 14,24, 0x056e, "1W2B" },
+X{ "ffsd", 14,24, 0x076e, "1D2B" },
+X{ "flag", 8,8, 0xd2, "" },
+X{ "floorfb", 14,24, 0x3c3e, "1F2B" },
+X{ "floorfw", 14,24, 0x3d3e, "1F2W" },
+X{ "floorfd", 14,24, 0x3f3e, "1F2D" },
+X{ "floorlb", 14,24, 0x383e, "1L2B" },
+X{ "floorlw", 14,24, 0x393e, "1L2W" },
+X{ "floorld", 14,24, 0x3b3e, "1L2D" },
+X{ "ibitb", 14,24, 0x384e, "1B2D" },
+X{ "ibitw", 14,24, 0x394e, "1W2D" },
+X{ "ibitd", 14,24, 0x3b4e, "1D2D" },
+X{ "indexb", 11,24, 0x42e, "2B3B1r" },
+X{ "indexw", 11,24, 0x52e, "2W3W1r" },
+X{ "indexd", 11,24, 0x72e, "2D3D1r" },
+X{ "insb", 11,24, 0x0ae, "2B3B1r4d" },
+X{ "insw", 11,24, 0x1ae, "2W3W1r4d" },
+X{ "insd", 11,24, 0x3ae, "2D3D1r4d" },
+X{ "inssb", 14,24, 0x08ce, "1B2D3i" },
+X{ "inssw", 14,24, 0x09ce, "1W2D3i" },
+X{ "inssd", 14,24, 0x0bce, "1D2D3i" },
+X{ "jsr", 11,16, 0x67f, "1A" },
+X{ "jump", 11,16, 0x27f, "1A" },
+X{ "lfsr", 19,24, 0x00f3e,"1D" },
+X{ "lmr", 15,24, 0x0b1e, "2D1q" },
+X{ "lprb", 7,16, 0x6c, "2B1q" },
+X{ "lprw", 7,16, 0x6d, "2W1q" },
+X{ "lprd", 7,16, 0x6f, "2D1q" },
+X{ "lshb", 14,24, 0x144e, "1B2B" },
+X{ "lshw", 14,24, 0x154e, "1B2W" },
+X{ "lshd", 14,24, 0x174e, "1B2D" },
+X{ "meib", 14,24, 0x24ce, "1B2W" },
+X{ "meiw", 14,24, 0x25ce, "1W2D" },
+X{ "meid", 14,24, 0x27ce, "1D2Q" },
+X{ "modb", 14,24, 0x38ce, "1B2B" },
+X{ "modw", 14,24, 0x39ce, "1W2W" },
+X{ "modd", 14,24, 0x3bce, "1D2D" },
+X{ "movf", 14,24, 0x05be, "1F2F" },
+X{ "movl", 14,24, 0x04be, "1L2L" },
+X{ "movb", 6,16, 0x14, "1B2B" },
+X{ "movw", 6,16, 0x15, "1W2W" },
+X{ "movd", 6,16, 0x17, "1D2D" },
+X{ "movbf", 14,24, 0x043e, "1B2F" },
+X{ "movwf", 14,24, 0x053e, "1W2F" },
+X{ "movdf", 14,24, 0x073e, "1D2F" },
+X{ "movbl", 14,24, 0x003e, "1B2L" },
+X{ "movwl", 14,24, 0x013e, "1W2L" },
+X{ "movdl", 14,24, 0x033e, "1D2L" },
+X{ "movfl", 14,24, 0x1b3e, "1F2L" },
+X{ "movlf", 14,24, 0x163e, "1L2F" },
+X{ "movmb", 14,24, 0x00ce, "1D2D3d" },
+X{ "movmw", 14,24, 0x00de, "1D2D3d" },
+X{ "movmd", 14,24, 0x00fe, "1D2D3d" },
+X{ "movqb", 7,16, 0x5c, "2B1q" },
+X{ "movqw", 7,16, 0x5d, "2B1q" },
+X{ "movqd", 7,16, 0x5f, "2B1q" },
+X{ "movsb", 16,16, 0x000e, "i" },
+X{ "movsw", 16,16, 0x010e, "i" },
+X{ "movsd", 16,16, 0x030e, "i" },
+X{ "movst", 16,16, 0x800e, "i" },
+X{ "movsub", 14,24, 0x0cae, "1A1A" },
+X{ "movsuw", 14,24, 0x0dae, "1A1A" },
+X{ "movsud", 14,24, 0x0fae, "1A1A" },
+X{ "movusb", 14,24, 0x1cae, "1A1A" },
+X{ "movusw", 14,24, 0x1dae, "1A1A" },
+X{ "movusd", 14,24, 0x1fae, "1A1A" },
+X{ "movxbd", 14,24, 0x1cce, "1B2D" },
+X{ "movxwd", 14,24, 0x1dce, "1W2D" },
+X{ "movxbw", 14,24, 0x10ce, "1B2W" },
+X{ "movzbd", 14,24, 0x18ce, "1B2D" },
+X{ "movzwd", 14,24, 0x19ce, "1W2D" },
+X{ "movzbw", 14,24, 0x14ce, "1B2W" },
+X{ "mulf", 14,24, 0x31be, "1F2F" },
+X{ "mull", 14,24, 0x30be, "1L2L" },
+X{ "mulb", 14,24, 0x20ce, "1B2B" },
+X{ "mulw", 14,24, 0x21ce, "1W2W" },
+X{ "muld", 14,24, 0x23ce, "1D2D" },
+X{ "negf", 14,24, 0x15be, "1F2F" },
+X{ "negl", 14,24, 0x14be, "1L2L" },
+X{ "negb", 14,24, 0x204e, "1B2B" },
+X{ "negw", 14,24, 0x214e, "1W2W" },
+X{ "negd", 14,24, 0x234e, "1D2D" },
+X{ "nop", 8,8, 0xa2, "" },
+X{ "notb", 14,24, 0x244e, "1B2B" },
+X{ "notw", 14,24, 0x254e, "1W2W" },
+X{ "notd", 14,24, 0x274e, "1D2D" },
+X{ "orb", 6,16, 0x18, "1B1B" },
+X{ "orw", 6,16, 0x19, "1W1W" },
+X{ "ord", 6,16, 0x1b, "1D1D" },
+X{ "quob", 14,24, 0x30ce, "1B2B" },
+X{ "quow", 14,24, 0x31ce, "1W2W" },
+X{ "quod", 14,24, 0x33ce, "1D2D" },
+X{ "rdval", 19,24, 0x0031e,"1A" },
+X{ "remb", 14,24, 0x34ce, "1B2B" },
+X{ "remw", 14,24, 0x35ce, "1W2W" },
+X{ "remd", 14,24, 0x37ce, "1D2D" },
+X{ "restore", 8,8, 0x72, "1i" },
+X{ "ret", 8,8, 0x12, "1d" },
+X{ "reti", 8,8, 0x52, "" },
+X{ "rett", 8,8, 0x42, "" },
+X{ "rotb", 14,24, 0x004e, "1B2B" },
+X{ "rotw", 14,24, 0x014e, "1B2W" },
+X{ "rotd", 14,24, 0x034e, "1B2D" },
+X{ "roundfb", 14,24, 0x243e, "1F2B" },
+X{ "roundfw", 14,24, 0x253e, "1F2W" },
+X{ "roundfd", 14,24, 0x273e, "1F2D" },
+X{ "roundlb", 14,24, 0x203e, "1L2B" },
+X{ "roundlw", 14,24, 0x213e, "1L2W" },
+X{ "roundld", 14,24, 0x233e, "1L2D" },
+X{ "rxp", 8,8, 0x32, "1d" },
+X{ "sCONDb", 7,16, 0x3c, "2B1q" },
+X{ "sCONDw", 7,16, 0x3d, "2D1q" },
+X{ "sCONDd", 7,16, 0x3f, "2D1q" },
+X{ "save", 8,8, 0x62, "1i" },
+X{ "sbitb", 14,24, 0x184e, "1B2A" },
+X{ "sbitw", 14,24, 0x194e, "1W2A" },
+X{ "sbitd", 14,24, 0x1b4e, "1D2A" },
+X{ "sbitib", 14,24, 0x1c4e, "1B2A" },
+X{ "sbitiw", 14,24, 0x1d4e, "1W2A" },
+X{ "sbitid", 14,24, 0x1f4e, "1D2A" },
+X{ "setcfg", 15,24, 0x0b0e, "5D1q" },
+X{ "sfsr", 14,24, 0x673e, "5D1D" },
+X{ "skpsb", 16,16, 0x0c0e, "i" },
+X{ "skpsw", 16,16, 0x0d0e, "i" },
+X{ "skpsd", 16,16, 0x0f0e, "i" },
+X{ "skpst", 16,16, 0x8c0e, "i" },
+X{ "smr", 15,24, 0x0f1e, "2D1q" },
+X{ "sprb", 7,16, 0x2c, "2B1q" },
+X{ "sprw", 7,16, 0x2d, "2W1q" },
+X{ "sprd", 7,16, 0x2f, "2D1q" },
+X{ "subf", 14,24, 0x11be, "1F2F" },
+X{ "subl", 14,24, 0x10be, "1L2L" },
+X{ "subb", 6,16, 0x20, "1B2B" },
+X{ "subw", 6,16, 0x21, "1W2W" },
+X{ "subd", 6,16, 0x23, "1D2D" },
+X{ "subcb", 6,16, 0x30, "1B2B" },
+X{ "subcw", 6,16, 0x31, "1W2W" },
+X{ "subcd", 6,16, 0x33, "1D2D" },
+X{ "subpb", 14,24, 0x2c4e, "1B2B" },
+X{ "subpw", 14,24, 0x2d4e, "1W2W" },
+X{ "subpd", 14,24, 0x2f4e, "1D2D" },
+X{ "svc", 8,8, 0xe2, "2i1i" }, /* not really, but unix uses it */
+X{ "tbitb", 6,16, 0x34, "1B2A" },
+X{ "tbitw", 6,16, 0x35, "1W2A" },
+X{ "tbitd", 6,16, 0x37, "1D2A" },
+X{ "truncfb", 14,24, 0x2c3e, "1F2B" },
+X{ "truncfw", 14,24, 0x2d3e, "1F2W" },
+X{ "truncfd", 14,24, 0x2f3e, "1F2D" },
+X{ "trunclb", 14,24, 0x283e, "1L2B" },
+X{ "trunclw", 14,24, 0x293e, "1L2W" },
+X{ "truncld", 14,24, 0x2b3e, "1L2D" },
+X{ "wait", 8,8, 0xb2, "" },
+X{ "wrval", 19,24, 0x0071e,"1A" },
+X{ "xorb", 6,16, 0x38, "1B2B" },
+X{ "xorw", 6,16, 0x39, "1W2W" },
+X{ "xord", 6,16, 0x3b, "1D2D" },
+X}; /* notstrs */
+X
+X/* end: n32k.opcode.h */
+X
+X# define MAX_ARGS 4
+X# define ARG_LEN 50
+SHAR_EOF
+sed 's/^X//' << 'SHAR_EOF' > n32k-pinsn.c
+X/* Print 32000 instructions for GDB, the GNU debugger.
+X Copyright (C) 1986 Free Software Foundation, Inc.
+X
+XGDB is distributed in the hope that it will be useful, but WITHOUT ANY
+XWARRANTY. No author or distributor accepts responsibility to anyone
+Xfor the consequences of using it or for whether it serves any
+Xparticular purpose or works at all, unless he says so in writing.
+XRefer to the GDB General Public License for full details.
+X
+XEveryone is granted permission to copy, modify and redistribute GDB,
+Xbut only under the conditions described in the GDB General Public
+XLicense. A copy of this license is supposed to have been given to you
+Xalong with GDB so you can know your rights and responsibilities. It
+Xshould be in a file named COPYING. Among other things, the copyright
+Xnotice and this notice must be preserved on all copies.
+X
+XIn other words, go ahead and share GDB, but don't try to stop
+Xanyone else from sharing it farther. Help stamp out software hoarding!
+X*/
+X
+X#include <stdio.h>
+X
+X#include "defs.h"
+X#include "param.h"
+X#include "symtab.h"
+X#include "n32k-opcode.h"
+X
+X/* 32000 instructions are never longer than this. */
+X#define MAXLEN 62
+X
+X/* Number of elements in the opcode table. */
+X#define NOPCODES (sizeof notstrs / sizeof notstrs[0])
+X
+Xextern char *reg_names[];
+X
+X#define NEXT_IS_ADDR '|'
+X
+X/*
+X * extract "count" bits starting "offset" bits
+X * into buffer
+X */
+X
+Xint
+Xbit_extract (buffer, offset, count)
+Xchar *buffer;
+Xint offset;
+Xint count;
+X{
+X int result;
+X int mask;
+X int bit;
+X
+X buffer += offset >> 3;
+X offset &= 7;
+X bit = 1;
+X result = 0;
+X while (count--) {
+X if ((*buffer & (1 << offset)))
+X result |= bit;
+X if (++offset == 8) {
+X offset = 0;
+X buffer++;
+X }
+X bit <<= 1;
+X }
+X return result;
+X}
+X
+Xdouble
+Xdbit_extract (buffer, offset, count)
+X{
+X union {
+X struct {
+X int low, high;
+X } ival;
+X double dval;
+X } foo;
+X
+X foo.ival.low = bit_extract (buffer, offset, 32);
+X foo.ival.high = bit_extract (buffer, offset+32, 32);
+X return foo.dval;
+X}
+X
+Xsign_extend (value, bits)
+X{
+X value = value & ((1 << bits) - 1);
+X return (value & (1 << (bits-1))) ?
+X (value | (~((1 << bits) - 1)))
+X : value;
+X}
+X
+Xflip_bytes (ptr, count)
+Xchar *ptr;
+Xint count;
+X{
+X char tmp;
+X
+X while (count > 0) {
+X tmp = *ptr;
+X ptr[0] = ptr[count-1];
+X ptr[count-1] = tmp;
+X ptr++;
+X count -= 2;
+X }
+X}
+X
+X
+X/* Print the 32000 instruction at address MEMADDR in debugged memory,
+X on STREAM. Returns length of the instruction, in bytes. */
+X
+Xint
+Xprint_insn (memaddr, stream)
+XCORE_ADDR memaddr;
+XFILE *stream;
+X{
+X unsigned char buffer[MAXLEN];
+X register int i;
+X register unsigned char *p;
+X register char *d;
+X unsigned short first_word;
+X int gen, disp;
+X int ioffset; /* bits into instruction */
+X int aoffset; /* bits into arguments */
+X char arg_bufs[MAX_ARGS+1][ARG_LEN];
+X int argnum;
+X int maxarg;
+X
+X read_memory (memaddr, buffer, MAXLEN);
+X
+X first_word = *(unsigned short *) buffer;
+X for (i = 0; i < NOPCODES; i++) {
+X if ((first_word & ((1 << notstrs[i].detail.obits) - 1)) ==
+X notstrs[i].detail.code)
+X break;
+X }
+X
+X /* Handle undefined instructions. */
+X if (i == NOPCODES) {
+X fprintf (stream, "0%o", buffer[0]);
+X return 1;
+X }
+X
+X fprintf (stream, "%s", notstrs[i].name);
+X
+X ioffset = notstrs[i].detail.ibits;
+X aoffset = notstrs[i].detail.ibits;
+X d = notstrs[i].detail.args;
+X
+X if (*d) {
+X fputc ('\t', stream);
+X
+X maxarg = 0;
+X while (*d)
+X {
+X argnum = *d - '1';
+X d++;
+X if (argnum > maxarg && argnum < MAX_ARGS)
+X maxarg = argnum;
+X ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
+X memaddr, arg_bufs[argnum]);
+X d++;
+X }
+X for (argnum = 0; argnum <= maxarg; argnum++) {
+X CORE_ADDR addr;
+X char *ch, *index ();
+X for (ch = arg_bufs[argnum]; *ch;) {
+X if (*ch == NEXT_IS_ADDR) {
+X ++ch;
+X addr = atoi (ch);
+X print_address (addr, stream);
+X while (*ch && *ch != NEXT_IS_ADDR)
+X ++ch;
+X if (*ch)
+X ++ch;
+X } else
+X putc (*ch++, stream);
+X }
+X if (argnum < maxarg)
+X fprintf (stream, ", ");
+X }
+X }
+X return aoffset / 8;
+X}
+X
+Xprint_insn_arg (d, ioffset, aoffsetp, buffer, addr, result)
+Xchar d;
+Xint ioffset, *aoffsetp;
+Xchar *buffer;
+XCORE_ADDR addr;
+Xchar *result;
+X{
+X int addr_mode;
+X float Fvalue;
+X double Lvalue;
+X int Ivalue;
+X int disp1, disp2;
+X int index;
+X
+X switch (d) {
+X case 'F':
+X case 'L':
+X case 'B':
+X case 'W':
+X case 'D':
+X case 'A':
+X addr_mode = bit_extract (buffer, ioffset-5, 5);
+X ioffset -= 5;
+X switch (addr_mode) {
+X case 0x0: case 0x1: case 0x2: case 0x3:
+X case 0x4: case 0x5: case 0x6: case 0x7:
+X sprintf (result, "r%d", addr_mode);
+X break;
+X case 0x8: case 0x9: case 0xa: case 0xb:
+X case 0xc: case 0xd: case 0xe: case 0xf:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
+X break;
+X case 0x10:
+X case 0x11:
+X case 0x12:
+X disp1 = get_displacement (buffer, aoffsetp);
+X disp2 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "%d(%d(%s))", disp2, disp1,
+X addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
+X break;
+X case 0x13:
+X sprintf (result, "reserved");
+X break;
+X case 0x14:
+X switch (d) {
+X case 'B':
+X Ivalue = bit_extract (buffer, *aoffsetp, 8);
+X Ivalue = sign_extend (Ivalue, 8);
+X *aoffsetp += 8;
+X sprintf (result, "$%d", Ivalue);
+X break;
+X case 'W':
+X Ivalue = bit_extract (buffer, *aoffsetp, 16);
+X flip_bytes (&Ivalue, 2);
+X *aoffsetp += 16;
+X Ivalue = sign_extend (Ivalue, 16);
+X sprintf (result, "$%d", Ivalue);
+X break;
+X case 'D':
+X Ivalue = bit_extract (buffer, *aoffsetp, 32);
+X flip_bytes (&Ivalue, 4);
+X *aoffsetp += 32;
+X sprintf (result, "$%d", Ivalue);
+X break;
+X case 'A':
+X Ivalue = bit_extract (buffer, *aoffsetp, 32);
+X flip_bytes (&Ivalue, 4);
+X *aoffsetp += 32;
+X sprintf (result, "$|%d|", Ivalue);
+X break;
+X case 'F':
+X Fvalue = (float) bit_extract
+X (buffer, *aoffsetp, 32);
+X flip_bytes (&Fvalue, 4);
+X *aoffsetp += 32;
+X sprintf (result, "$%g", Fvalue);
+X break;
+X case 'L':
+X Lvalue = dbit_extract
+X (buffer, *aoffsetp, 64);
+X flip_bytes (&Lvalue, 8);
+X *aoffsetp += 64;
+X sprintf (result, "$%g", Lvalue);
+X break;
+X }
+X break;
+X case 0x15:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "@|%d|", disp1);
+X break;
+X case 0x16:
+X disp1 = get_displacement (buffer, aoffsetp);
+X disp2 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "EXT(%d) + %d", disp1, disp2);
+X break;
+X case 0x17:
+X sprintf (result, "tos");
+X break;
+X case 0x18:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "%d(fp)", disp1);
+X break;
+X case 0x19:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "%d(sp)", disp1);
+X break;
+X case 0x1a:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "%d(sb)", disp1);
+X break;
+X case 0x1b:
+X disp1 = get_displacement (buffer, aoffsetp);
+X sprintf (result, "|%d|", addr + disp1);
+X break;
+X case 0x1c:
+X case 0x1d:
+X case 0x1e:
+X case 0x1f:
+X index = bit_extract (buffer, *aoffsetp, 8);
+X *aoffsetp += 8;
+X print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr,
+X result);
+X {
+X static char *ind[] = {"b", "w", "d", "q"};
+X char *off;
+X
+X off = result + strlen (result);
+X sprintf (off, "[r%d:%s]", index & 7,
+X ind[addr_mode & 3]);
+X }
+X break;
+X }
+X break;
+X case 'q':
+X Ivalue = bit_extract (buffer, ioffset-4, 4);
+X Ivalue = sign_extend (Ivalue, 4);
+X sprintf (result, "%d", Ivalue);
+X ioffset -= 4;
+X break;
+X case 'r':
+X Ivalue = bit_extract (buffer, ioffset-3, 3);
+X sprintf (result, "r%d", Ivalue&7);
+X ioffset -= 3;
+X break;
+X case 'd':
+X sprintf (result, "%d", get_displacement (buffer, aoffsetp));
+X break;
+X case 'p':
+X sprintf (result, "%c%d%c", NEXT_IS_ADDR, addr +
+X get_displacement (buffer, aoffsetp),
+X NEXT_IS_ADDR);
+X break;
+X case 'i':
+X Ivalue = bit_extract (buffer, *aoffsetp, 8);
+X *aoffsetp += 8;
+X sprintf (result, "0x%x", Ivalue);
+X break;
+X }
+X return ioffset;
+X}
+X
+Xget_displacement (buffer, aoffsetp)
+Xchar *buffer;
+Xint *aoffsetp;
+X{
+X int Ivalue;
+X
+X Ivalue = bit_extract (buffer, *aoffsetp, 8);
+X switch (Ivalue & 0xc0) {
+X case 0x00:
+X case 0x40:
+X Ivalue = sign_extend (Ivalue, 7);
+X *aoffsetp += 8;
+X break;
+X case 0x80:
+X Ivalue = bit_extract (buffer, *aoffsetp, 16);
+X flip_bytes (&Ivalue, 2);
+X Ivalue = sign_extend (Ivalue, 14);
+X *aoffsetp += 16;
+X break;
+X case 0xc0:
+X Ivalue = bit_extract (buffer, *aoffsetp, 32);
+X flip_bytes (&Ivalue, 4);
+X Ivalue = sign_extend (Ivalue, 30);
+X *aoffsetp += 32;
+X break;
+X }
+X return Ivalue;
+X}
+X/*
+X * return the number of locals in the current frame given a pc
+X * pointing to the enter instruction
+X */
+Xn32k_localcount (enter_pc)
+XCORE_ADDR enter_pc;
+X{
+X int localtype, localcount;
+X
+X localtype = read_memory_integer (enter_pc+2, 1);
+X if ((localtype & 0x80) == 0)
+X localcount = localtype;
+X else if ((localtype & 0xc0) == 0x80)
+X localcount =
+X ((read_memory_integer (enter_pc+2, 1) & ~0xc0) << 8) |
+X ((read_memory_integer (enter_pc+3, 1)));
+X else
+X localcount =
+X ((read_memory_integer (enter_pc+2, 1) & ~0xc0) << 24) |
+X ((read_memory_integer (enter_pc+3, 1)) << 16) |
+X ((read_memory_integer (enter_pc+4, 1)) << 8 ) |
+X ((read_memory_integer (enter_pc+5, 1)));
+X return localcount;
+X}
+SHAR_EOF
+exit
+