diff options
author | John Gilmore <gnu@cygnus> | 1990-09-05 17:54:31 +0000 |
---|---|---|
committer | John Gilmore <gnu@cygnus> | 1990-09-05 17:54:31 +0000 |
commit | 831c851165e112139af1265f294e198401814c1f (patch) | |
tree | 5f155fecb9b690be9c428e822d519c2710fefd47 /gdb/ns32k-pinsn.c | |
parent | 7a67dd45ca1c191a0220697a3ec9fa92993caf8c (diff) | |
download | gdb-831c851165e112139af1265f294e198401814c1f.zip gdb-831c851165e112139af1265f294e198401814c1f.tar.gz gdb-831c851165e112139af1265f294e198401814c1f.tar.bz2 |
Initial revision
Diffstat (limited to 'gdb/ns32k-pinsn.c')
-rw-r--r-- | gdb/ns32k-pinsn.c | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/gdb/ns32k-pinsn.c b/gdb/ns32k-pinsn.c deleted file mode 100644 index 655c899..0000000 --- a/gdb/ns32k-pinsn.c +++ /dev/null @@ -1,522 +0,0 @@ -/* 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 "opcode.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; - } -} - -/* 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) - - -/* 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; -} - -/* 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 */ -} |