From: idall@eleceng.adelaide.EDU.AU
Subject: gdb for ns32k.
Organization: GNUs Not Usenet
Distribution: gnu
Date: Mon, 21 Dec 1992 11:02:13 GMT

I tried to compile gdb 4.6 for the ns32k series (it is for a pc532
running mach which isn't actually supported but this bug fix applies
to any ns32k series machine). ns32k-pinsn.c would not compile because
it couldn't find ns32k-opcode.h.

Sorry this bug report is not relative to gdb 4.7, but I don't
think the problem has been fixed and I haven't got mach support
in gdb 4.7.

There is some confusion over what include file has the opcode table to
use (for ns32k-pinsn.c). There are two files include/opcode/ns32k.h
and include/opcode/ns32k-options.h. The ns32k.h is essentially the
same as the ns32k-opcode.h from gas.  Figuring that we don't want to
maintain several multiple tables of opcodes, I modified ns32k-pinsn.c
to use opcode/ns32k.h.  This required supporting a number of cases not
previously supported.

Options (for string instructions, cinv etc) and register lists (for
enter, exit, save and restore) are now interpreted properly and
printed nicely in a format acceptable to gas. Also register names
for the ns532 "processor" registers and  MMU registers are supported
(these differ from earlier processors).

The diffs for the changes I made follow. There are some changes to
ns32k.h but they arise from copying the ns32k.h from the gas
distribution and are entirely in comments or ifdef'd out code.

Ian

*** ../dist/gdb/ns32k-pinsn.c	Sat Jun 13 15:38:03 1992
--- gdb/ns32k-pinsn.c	Sun Dec 20 23:32:48 1992
***************
*** 19,25 ****
  
  #include "defs.h"
  #include "symtab.h"
! #include "ns32k-opcode.h"
  #include "gdbcore.h"
  
  /* 32000 instructions are never longer than this.  */
--- 19,25 ----
  
  #include "defs.h"
  #include "symtab.h"
! #include "opcode/ns32k.h"
  #include "gdbcore.h"
  
  /* 32000 instructions are never longer than this.  */
***************
*** 26,32 ****
  #define MAXLEN 62
  
  /* Number of elements in the opcode table.  */
! #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
  
  #define NEXT_IS_ADDR	'|'
  
--- 26,32 ----
  #define MAXLEN 62
  
  /* Number of elements in the opcode table.  */
! #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
  
  #define NEXT_IS_ADDR	'|'
  
***************
*** 115,121 ****
  /* 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
--- 115,121 ----
  /* 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) == 'Q' || (c) == 'A')
  
  /* Adressing modes.  */
  #define Adrmod_index_byte 0x1c
***************
*** 155,162 ****
  
    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.  */
--- 155,162 ----
  
    first_word = *(unsigned short *) buffer;
    for (i = 0; i < NOPCODES; i++)
!     if ((first_word & ((1 << ns32k_opcodes[i].opcode_id_size) - 1))
! 	== ns32k_opcodes[i].opcode_seed)
        break;
  
    /* Handle undefined instructions.  */
***************
*** 166,176 ****
        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)
      {
--- 166,176 ----
        return 1;
      }
  
!   fprintf (stream, "%s", ns32k_opcodes[i].name);
  
!   ioffset = ns32k_opcodes[i].opcode_size;
!   aoffset = ns32k_opcodes[i].opcode_size;
!   d = ns32k_opcodes[i].operands;
  
    if (*d)
      {
***************
*** 250,255 ****
--- 250,276 ----
    return aoffset / 8;
  }
  
+ void decode_options(char *result, int Ivalue, unsigned int bits, char *options, char prefix)
+ {
+   if (Ivalue & ~((1 << bits) - 1))
+     sprintf(result, "0x%x", Ivalue);
+   else
+     {
+       int i, need_comma = 0;
+       *result++ = '[';
+       for (i = 0; i <= (bits - 1); i++)
+ 	if (Ivalue & (1 << i))
+ 	  {
+ 	    if (need_comma)
+ 	      *result++ = ',';
+ 	    if (prefix)
+ 	      *result++ = prefix;
+ 	    *result++ = options[i];
+ 	    need_comma = 1;
+ 	  }
+       sprintf(result, "]");
+     }
+ }
  /* 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
***************
*** 277,287 ****
--- 298,312 ----
  
    switch (d)
      {
+     case 'f':
+       /* a "gen" operand but 5 bits from the end of instruction */
+       ioffset -= 5;
      case 'F':
      case 'L':
      case 'B':
      case 'W':
      case 'D':
+     case 'Q':
      case 'A':
        addr_mode = bit_extract (buffer, ioffset-5, 5);
        ioffset -= 5;
***************
*** 289,294 ****
--- 314,320 ----
  	{
  	case 0x0: case 0x1: case 0x2: case 0x3:
  	case 0x4: case 0x5: case 0x6: case 0x7:
+ 	  /* register mode R0 -- R7 */
  	  switch (d)
  	    {
  	    case 'F':
***************
*** 301,306 ****
--- 327,333 ----
  	  break;
  	case 0x8: case 0x9: case 0xa: case 0xb:
  	case 0xc: case 0xd: case 0xe: case 0xf:
+ 	  /* Register relative disp(R0 -- R7) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
  	  break;
***************
*** 307,312 ****
--- 334,340 ----
  	case 0x10:
  	case 0x11:
  	case 0x12:
+ 	  /* Memory relative disp2(disp1(FP, SP, SB)) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  disp2 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "%d(%d(%s))", disp2, disp1,
***************
*** 313,321 ****
--- 341,351 ----
  		   addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
  	  break;
  	case 0x13:
+ 	  /* reserved */
  	  sprintf (result, "reserved");
  	  break;
  	case 0x14:
+ 	  /* Immediate */
  	  switch (d)
  	    {
  	    case 'B':
***************
*** 355,387 ****
--- 385,427 ----
  	      *aoffsetp += 64;
  	      sprintf (result, "$%g", Lvalue);
  	      break;
+ 	    case 'Q':
+ 	      sprintf (result, "unimplimented");
+ 	      break;
  	    }
  	  break;
  	case 0x15:
+ 	  /* Absolute @disp */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "@|%d|", disp1);
  	  break;
  	case 0x16:
+ 	  /* External EXT(disp1) + disp2 (Mod table stuff) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  disp2 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "EXT(%d) + %d", disp1, disp2);
  	  break;
  	case 0x17:
+ 	  /* Top of stack tos */
  	  sprintf (result, "tos");
  	  break;
  	case 0x18:
+ 	  /* Memory space disp(FP) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "%d(fp)", disp1);
  	  break;
  	case 0x19:
+ 	  /* Memory space disp(SP) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "%d(sp)", disp1);
  	  break;
  	case 0x1a:
+ 	  /* Memory space disp(SB) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "%d(sb)", disp1);
  	  break;
  	case 0x1b:
+ 	  /* Memory space disp(PC) */
  	  disp1 = get_displacement (buffer, aoffsetp);
  	  sprintf (result, "|%d|", addr + disp1);
  	  break;
***************
*** 389,394 ****
--- 429,435 ----
  	case 0x1d:
  	case 0x1e:
  	case 0x1f:
+ 	  /* Scaled index basemode[R0 -- R7:B,W,D,Q] */
  	  index = bit_extract (buffer, index_offset - 8, 3);
  	  print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
  			  result, 0);
***************
*** 403,408 ****
--- 444,458 ----
  	  break;
  	}
        break;
+     case 'd':
+       sprintf (result, "%d", get_displacement (buffer, aoffsetp));
+       break;
+     case 'H':
+     case 'p':
+       sprintf (result, "%c%d%c", NEXT_IS_ADDR,
+ 	       addr + get_displacement (buffer, aoffsetp),
+ 	       NEXT_IS_ADDR);
+       break;
      case 'q':
        Ivalue = bit_extract (buffer, ioffset-4, 4);
        Ivalue = sign_extend (Ivalue, 4);
***************
*** 409,431 ****
        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;
--- 459,541 ----
        sprintf (result, "%d", Ivalue);
        ioffset -= 4;
        break;
+     case 'i':
+       Ivalue = bit_extract (buffer, *aoffsetp, 8);
+       *aoffsetp += 8;
+       sprintf (result, "0x%x", Ivalue);
+       break;
      case 'r':
        Ivalue = bit_extract (buffer, ioffset-3, 3);
        sprintf (result, "r%d", Ivalue&7);
        ioffset -= 3;
        break;
!     case 'O':
!       Ivalue = bit_extract (buffer, ioffset-9, 9);
!       decode_options(result, Ivalue, 4, "ifmc", 0);
!       ioffset -= 9;
        break;
!     case 'C':
!       Ivalue = bit_extract (buffer, ioffset-4, 4);
!       decode_options (result, Ivalue, 3, "dia", 0);
!       ioffset -= 4;
        break;
!     case 'S':
!       Ivalue = bit_extract (buffer, ioffset - 8, 8);
!       decode_options(result, Ivalue, 3, "bwu", 0);
!       ioffset -= 8;
!       break;
!     case 'U':
        Ivalue = bit_extract (buffer, *aoffsetp, 8);
+       decode_options(result, Ivalue, 8, "01234567", 'r');
        *aoffsetp += 8;
!       break;
!     case 'u':
!       Ivalue = bit_extract (buffer, *aoffsetp, 8);
!       decode_options(result, Ivalue, 8, "76543210", 'r');
!       *aoffsetp += 8;
!       break;
!     case 'M':
!       {
! #ifdef NS32532_MMU_REGS	
! 	char *mreg[] = { "", "", "", "", "", "", "", "",
! 			   "", "mcr", "msr", "tear", "ptb0", "ptb1", "ivar0", "ivar1"};
! #else
! 	char *mreg[] = {"bpr0", "bpr1", "", "", "pf0", "pf1", "", "",
! 			  "sc", "", "msr", "bcnt", "ptb0", "ptb1", "", "eia"};
! #endif
! 	int nmreg = sizeof(mreg)/sizeof(mreg[0]);
! 	Ivalue =  bit_extract (buffer, ioffset-4, 4);
! 	sprintf(result, "%s", Ivalue > nmreg? "": mreg[Ivalue]);
! 	ioffset -= 4;
!       }
!       break;
!     case 'P':
!       {
! #ifdef NS32532_CPU_REGS
! 	char *creg[] = {"us", "dcr", "bpc", "dsr", "car", "", "", "",
! 			  "fp", "sp", "sb", "usp", "cfg", "psr", "intbase", "mod"};
! #else
! 	char *creg[] = {"upsr", "", "", "", "", "", "", "",
! 			  "fp", "sp", "sb", "", "", "psr", "intbase", "mod"};
! #endif
! 	int ncreg = sizeof(creg)/sizeof(creg[0]);
! 	Ivalue =  bit_extract (buffer, ioffset-4, 4);
! 	sprintf(result, "%s", Ivalue > ncreg? "": creg[Ivalue]);
! 	ioffset -= 4;
!       }
!       break;
!     case 'g':
!       Ivalue = bit_extract (buffer, *aoffsetp + 5, 3);
!       sprintf(result, "%d", Ivalue);
!       /* Don't increment aoffset, leave it to G */
!       break;
!     case 'G':
!       Ivalue = bit_extract (buffer, *aoffsetp , 5);
!       sprintf(result, "%d", Ivalue + 1);
!       *aoffsetp += 8;
!       break;
!     default:
!       sprintf(result, "<unsupported>");
        break;
      }
    return ioffset;
*** ../dist/gdb/depend	Wed Jul 15 12:21:47 1992
--- gdb/depend	Thu Dec 17 01:50:24 1992
***************
*** 211,217 ****
  nindy-tdep.o : nindy-tdep.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
    tm.h config.status symtab.h ${srcdir}/../include/obstack.h frame.h 
  ns32k-pinsn.o : ns32k-pinsn.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
!   tm.h config.status symtab.h ${srcdir}/../include/obstack.h ns32k-opcode.h gdbcore.h ${srcdir}/../include/bfd.h 
  objfiles.o : objfiles.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
    tm.h config.status ${srcdir}/../include/bfd.h ${srcdir}/../include/obstack.h symtab.h symfile.h objfiles.h 
  parse.o : parse.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
--- 211,217 ----
  nindy-tdep.o : nindy-tdep.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
    tm.h config.status symtab.h ${srcdir}/../include/obstack.h frame.h 
  ns32k-pinsn.o : ns32k-pinsn.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
!   tm.h config.status symtab.h ${srcdir}/../include/obstack.h ${srcdir}/../include/opcode/ns32k.h gdbcore.h ${srcdir}/../include/bfd.h 
  objfiles.o : objfiles.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
    tm.h config.status ${srcdir}/../include/bfd.h ${srcdir}/../include/obstack.h symtab.h symfile.h objfiles.h 
  parse.o : parse.c defs.h ${srcdir}/../include/ansidecl.h xm.h config.status ${srcdir}/../include/fopen-same.h \
*** ../dist/include/opcode/ns32k.h	Sun Dec  1 12:52:40 1991
--- include/opcode/ns32k.h	Sun Dec 20 16:41:01 1992
***************
*** 46,52 ****
  	Q : quad-word		    "
  	A : double-word		gen-address-form ie no regs allowed
  	d : displacement
! 	b : displacement - pc relative addressing  acb
  	p : displacement - pc relative addressing  br bcond bsr cxp
  	q : quick
  	i : immediate (8 bits)
--- 46,52 ----
  	Q : quad-word		    "
  	A : double-word		gen-address-form ie no regs allowed
  	d : displacement
! 	b : displacement - pc relative addressing  acb  (no longer used)
  	p : displacement - pc relative addressing  br bcond bsr cxp
  	q : quick
  	i : immediate (8 bits)
***************
*** 91,153 ****
  				   is a plain constant */
    char default_model;		/* is a plain label */
  };
- 
- #ifdef comment
- /* This section was from the gdb version of this file. */
- 
- #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
- */
- 
- 
- #endif /* comment */
  
  static const struct ns32k_opcode ns32k_opcodes[]=
  {
--- 91,96 ----

Newsgroups: gnu.gdb.bug