From: Stan Shebs Date: Tue, 17 Jan 1995 04:36:51 +0000 (+0000) Subject: General cleanup and simplication of disassembler interface. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=18b46e7c5378bb16c32827413376fa5982a4d8eb;p=binutils-gdb.git General cleanup and simplication of disassembler interface. * a29k-pinsn.c, arm-pinsn.c, convex-pinsn.c, gould-pinsn.c, hppa-pinsn.c, i386-pinsn.c, i960-pinsn.c, m68k-pinsn.c, m88k-pinsn.c, mips-pinsn.c, ns32k-pinsn.c, pyr-pinsn.c, rs6000-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c, vax-pinsn.c: Remove. * gould-tdep.c, ns32k-tdep.c, tahoe-tdep.c, vax-tdep.c: New files, had been -pinsn.c files. * Makefile.in (ALLDEPFILES): Remove removed files. (a29k-pinsn.o, arm-pinsn.o, convex-pinsn.o, gould-pinsn.o, hppa-pinsn.o, i386-pinsn.o, i960-pinsn.o, m68k-pinsn.o, m88k-pinsn.o, mips-pinsn.o, ns32k-pinsn.o, pyr-pinsn.o, rs6000-pinsn.o, sparc-pinsn.o, tahoe-pinsn.o, vax-pinsn.o): Remove compile actions. * arm-tdep.o, gould-tdep.o, ns32k-tdep.o, tahoe-tdep.o, vax-tdep.o: Add compile actions. * defs.h (tm_print_insn): New global. * a29k-tdep.c (gdb_print_insn_a29k): New function. (_initialize_a29k_tdep): Rename from _initialize_29k, set tm_print_insn. * alpha-tdep.c (print_insn): Remove. (_initialize_alpha_tdep): Set tm_print_insn. * arm-tdep.c (arm_print_insn): New function, was print_insn in arm-pinsn.c. * convex-tdep.c (convex_print_insn): New function, was print_insn in convex-pinsn.c. * h8300-tdep.c (print_insn): Remove. (gdb_print_insn_h8300): New function. (_initialize_h8300_tdep): New function. * h8500-tdep.c (print_insn): Remove. (_initialize_h8500_tdep): New function. * hppa-tdep.c (_initialize_hppa_tdep): Set tm_print_insn. * i386-tdep.c (_initialize_i386_tdep): New function. * i960-tdep.c (mem, next_insn): New functions, were in i960-pinsn.c. (_initialize_i960_tdep): Set tm_print_insn. * m68k-tdep.c (_initialize_m68k_tdep): New function. * m88k-tdep.c (_initialize_m88k_tdep): New function. * mips-tdep.c (gdb_print_insn_mips): New function. (_initialize_mips_tdep): Set tm_print_insn. * pyr-tdep.c (pyr_print_insn): New function, was print_insn in pyr-pinsn.c. * rs6000-tdep.c (_initialize_rs6000_tdep): New function. * sh-tdep.c (print_insn): Remove. (gdb_print_insn_sh): New function. (_initialize_sh_tdep): Set tm_print_insn. * sparc-tdep.c (_initialize_sparc_tdep): New function. * w65-tdep.c (print_insn): Remove. (_initialize_w65_tdep): New function. * z8k-tdep.c (print_insn): Remove. (gdb_print_insn_z8k): New function. (_initialize_z8k_tdep): Set tm_print_insn. * printcmd.c (print_insn): New function, generic disassembler. * config/*/*.mt (TDEPFILES): Remove refs to *-pinsn.o. * defs.h (query_hook, error_hook): Fix prototypes. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a0e80c26441..225758626dd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,61 @@ +Mon Jan 16 18:11:03 1995 Stan Shebs + + General cleanup and simplication of disassembler interface. + * a29k-pinsn.c, arm-pinsn.c, convex-pinsn.c, gould-pinsn.c, + hppa-pinsn.c, i386-pinsn.c, i960-pinsn.c, m68k-pinsn.c, + m88k-pinsn.c, mips-pinsn.c, ns32k-pinsn.c, pyr-pinsn.c, + rs6000-pinsn.c, sparc-pinsn.c, tahoe-pinsn.c, vax-pinsn.c: Remove. + * gould-tdep.c, ns32k-tdep.c, tahoe-tdep.c, vax-tdep.c: New files, + had been -pinsn.c files. + * Makefile.in (ALLDEPFILES): Remove removed files. + (a29k-pinsn.o, arm-pinsn.o, convex-pinsn.o, gould-pinsn.o, + hppa-pinsn.o, i386-pinsn.o, i960-pinsn.o, m68k-pinsn.o, + m88k-pinsn.o, mips-pinsn.o, ns32k-pinsn.o, pyr-pinsn.o, + rs6000-pinsn.o, sparc-pinsn.o, tahoe-pinsn.o, vax-pinsn.o): + Remove compile actions. + * arm-tdep.o, gould-tdep.o, ns32k-tdep.o, tahoe-tdep.o, + vax-tdep.o: Add compile actions. + * defs.h (tm_print_insn): New global. + * a29k-tdep.c (gdb_print_insn_a29k): New function. + (_initialize_a29k_tdep): Rename from _initialize_29k, + set tm_print_insn. + * alpha-tdep.c (print_insn): Remove. + (_initialize_alpha_tdep): Set tm_print_insn. + * arm-tdep.c (arm_print_insn): New function, was print_insn + in arm-pinsn.c. + * convex-tdep.c (convex_print_insn): New function, was print_insn + in convex-pinsn.c. + * h8300-tdep.c (print_insn): Remove. + (gdb_print_insn_h8300): New function. + (_initialize_h8300_tdep): New function. + * h8500-tdep.c (print_insn): Remove. + (_initialize_h8500_tdep): New function. + * hppa-tdep.c (_initialize_hppa_tdep): Set tm_print_insn. + * i386-tdep.c (_initialize_i386_tdep): New function. + * i960-tdep.c (mem, next_insn): New functions, were in + i960-pinsn.c. + (_initialize_i960_tdep): Set tm_print_insn. + * m68k-tdep.c (_initialize_m68k_tdep): New function. + * m88k-tdep.c (_initialize_m88k_tdep): New function. + * mips-tdep.c (gdb_print_insn_mips): New function. + (_initialize_mips_tdep): Set tm_print_insn. + * pyr-tdep.c (pyr_print_insn): New function, was print_insn + in pyr-pinsn.c. + * rs6000-tdep.c (_initialize_rs6000_tdep): New function. + * sh-tdep.c (print_insn): Remove. + (gdb_print_insn_sh): New function. + (_initialize_sh_tdep): Set tm_print_insn. + * sparc-tdep.c (_initialize_sparc_tdep): New function. + * w65-tdep.c (print_insn): Remove. + (_initialize_w65_tdep): New function. + * z8k-tdep.c (print_insn): Remove. + (gdb_print_insn_z8k): New function. + (_initialize_z8k_tdep): Set tm_print_insn. + * printcmd.c (print_insn): New function, generic disassembler. + * config/*/*.mt (TDEPFILES): Remove refs to *-pinsn.o. + + * defs.h (query_hook, error_hook): Fix prototypes. + Mon Jan 16 15:43:29 1995 Kung Hsu * Makefile.in: add new files remote-vx29k.c, config/a29k/tm-vx29k.h, diff --git a/gdb/a29k-pinsn.c b/gdb/a29k-pinsn.c index 70e8e5bd00e..e69de29bb2d 100644 --- a/gdb/a29k-pinsn.c +++ b/gdb/a29k-pinsn.c @@ -1,40 +0,0 @@ -/* Instruction printing code for the AMD 29000 - Copyright (C) 1993 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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - if (TARGET_BYTE_ORDER == BIG_ENDIAN) - return print_insn_big_a29k (memaddr, &info); - else - return print_insn_little_a29k (memaddr, &info); -} diff --git a/gdb/a29k-tdep.c b/gdb/a29k-tdep.c index ee9c4032ae7..e39adf1069e 100644 --- a/gdb/a29k-tdep.c +++ b/gdb/a29k-tdep.c @@ -1,5 +1,6 @@ /* Target-machine dependent code for the AMD 29000 - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992, 1993, 1994, 1995 + Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Jim Kingdon. This file is part of GDB. @@ -910,6 +911,17 @@ setup_arbitrary_frame (argc, argv) return frame; } +int +gdb_print_insn_a29k (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; +{ + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + return print_insn_big_a29k (memaddr, &info); + else + return print_insn_little_a29k (memaddr, &info); +} + enum a29k_processor_types processor_type = a29k_unknown; void @@ -956,10 +968,12 @@ a29k_get_processor_type () } void -_initialize_29k() +_initialize_a29k_tdep () { extern CORE_ADDR text_end; + tm_print_insn = gdb_print_insn_a29k; + /* FIXME, there should be a way to make a CORE_ADDR variable settable. */ add_show_from_set (add_set_cmd ("rstack_high_address", class_support, var_uinteger, diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 0901d60f233..08a296a6b7c 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1083,21 +1083,6 @@ alpha_store_return_value (valtype, valbuf) write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype)); } -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_alpha (memaddr, &info); -} - /* Just like reinit_frame_cache, but with the right arguments to be callable as an sfunc. */ @@ -1139,6 +1124,8 @@ _initialize_alpha_tdep () { struct cmd_list_element *c; + tm_print_insn = print_insn_alpha; + /* Let the user set the fence post for heuristic_proc_start. */ /* We really would like to have both "0" and "unlimited" work, but diff --git a/gdb/arm-pinsn.c b/gdb/arm-pinsn.c deleted file mode 100644 index 8c8b9562669..00000000000 --- a/gdb/arm-pinsn.c +++ /dev/null @@ -1,267 +0,0 @@ -/* Print Acorn Risc Machine instructions for GDB, the GNU debugger. - Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc. - -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 2 of the License, 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 -#include - -#include "symtab.h" -#include "opcode/arm.h" - -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(); - -/* 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<> 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/convex-pinsn.c b/gdb/convex-pinsn.c deleted file mode 100644 index 8ceea68006f..00000000000 --- a/gdb/convex-pinsn.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Print Convex instructions for GDB, the GNU debugger. - Copyright 1989, 1991, 1993 Free Software Foundation, Inc. - -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 2 of the License, 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 "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])) - -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 "opcode/convex.h" - -CONST 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, -}; - -CONST 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, -}; - -/* 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 index b0f799f38e4..0828d990f90 100644 --- a/gdb/convex-tdep.c +++ b/gdb/convex-tdep.c @@ -857,6 +857,299 @@ psw_info (arg) (psw & p->bit) >> p->pos, p->text); } } + +#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])) + +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 "opcode/convex.h" + +CONST 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, +}; + +CONST 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, +}; + +/* Print the instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +convex_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; +} + void _initialize_convex_dep () diff --git a/gdb/defs.h b/gdb/defs.h index 7979a2928ab..6f6e267f921 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -834,10 +834,21 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST)); #define MAINTENANCE_CMDS 1 #endif -/* Hooks for alternate command interfaces. */ - #include "dis-asm.h" /* Get defs for disassemble_info */ +extern int dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, + int len, disassemble_info *info)); + +extern void dis_asm_memory_error PARAMS ((int status, bfd_vma memaddr, + disassemble_info *info)); + +extern void dis_asm_print_address PARAMS ((bfd_vma addr, + disassemble_info *info)); + +extern int (*tm_print_insn) PARAMS ((bfd_vma, disassemble_info*)); + +/* Hooks for alternate command interfaces. */ + #ifdef __STDC__ struct target_waitstatus; struct cmd_list_element; @@ -845,10 +856,12 @@ struct cmd_list_element; extern void (*init_ui_hook) PARAMS ((void)); extern void (*command_loop_hook) PARAMS ((void)); -extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream)); -extern void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line, - int stopline, int noerror)); -extern int (*query_hook) PARAMS (()); +extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, + FILE *stream)); +extern void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, + int line, int stopline, + int noerror)); +extern int (*query_hook) PARAMS ((void)); extern void (*flush_hook) PARAMS ((FILE *stream)); extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b)); extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt)); @@ -866,7 +879,7 @@ extern int (*target_wait_hook) PARAMS ((int pid, extern void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd, int from_tty)); -extern NORETURN void (*error_hook) PARAMS (()); +extern NORETURN void (*error_hook) PARAMS ((void)); /* Inhibit window interface if non-zero. */ diff --git a/gdb/gould-pinsn.c b/gdb/gould-pinsn.c deleted file mode 100644 index 5c89f27fd79..00000000000 --- a/gdb/gould-pinsn.c +++ /dev/null @@ -1,291 +0,0 @@ -/* Print GOULD RISC instructions for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. - -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 2 of the License, 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 "symtab.h" -#include "frame.h" -#include "gdbcore.h" -#if defined GOULD_PN -#include "opcode/pn.h" -#else -#include "opcode/np1.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]) - - -/* 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. - */ -CORE_ADDR -findframe(thisframe) - struct frame_info *thisframe; -{ - register CORE_ADDR pointer; - CORE_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... - */ -CORE_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-tdep.c b/gdb/gould-tdep.c new file mode 100644 index 00000000000..06e9c48787f --- /dev/null +++ b/gdb/gould-tdep.c @@ -0,0 +1,291 @@ +/* GOULD RISC target-dependent code for GDB, the GNU debugger. + Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. + +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 2 of the License, 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 "symtab.h" +#include "frame.h" +#include "gdbcore.h" +#if defined GOULD_PN +#include "opcode/pn.h" +#else +#include "opcode/np1.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]) + + +/* Print the GOULD instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +gould_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. + */ +CORE_ADDR +findframe(thisframe) + struct frame_info *thisframe; +{ + register CORE_ADDR pointer; + CORE_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... + */ +CORE_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/h8300-tdep.c b/gdb/h8300-tdep.c index ae899599553..01f4093f2d4 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -98,12 +98,10 @@ h8300_skip_prologue (start_pc) } int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; +gdb_print_insn_h8300 (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; { - disassemble_info info; - GDB_INIT_DISASSEMBLE_INFO(info, stream); if (h8300hmode) return print_insn_h8300h (memaddr, &info); else @@ -473,3 +471,8 @@ print_register_hook (regno) } } +void +_initialize_h8300_tdep () +{ + tm_print_insn = gdb_print_insn_h8300; +} diff --git a/gdb/h8500-tdep.c b/gdb/h8500-tdep.c index ff1503b7123..83f074bc39e 100644 --- a/gdb/h8500-tdep.c +++ b/gdb/h8500-tdep.c @@ -1,5 +1,5 @@ /* Target-machine dependent code for Hitachi H8/500, for GDB. - Copyright (C) 1993, 1994 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -104,16 +104,6 @@ h8500_skip_prologue (start_pc) return start_pc; } -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; -{ - disassemble_info info; - GDB_INIT_DISASSEMBLE_INFO (info, stream); - return print_insn_h8500 (memaddr, &info); -} - /* Given a GDB frame, determine the address of the calling function's frame. This will be used to create a new GDB frame struct, and then INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. @@ -680,3 +670,8 @@ h8500_write_fp (v) write_register (PR6_REGNUM, v); } +void +_initialize_h8500_tdep () +{ + tm_print_insn = gdb_print_insn_sh; +} diff --git a/gdb/hppa-pinsn.c b/gdb/hppa-pinsn.c index cfb4c9a856f..e69de29bb2d 100644 --- a/gdb/hppa-pinsn.c +++ b/gdb/hppa-pinsn.c @@ -1,38 +0,0 @@ -/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c. - Copyright 1989, 1990, 1992 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - - return print_insn_hppa (memaddr, &info); -} diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index e780d488ec4..0cc11511666 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for the HP PA architecture, for GDB. - Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994 + Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by the Center for Software Science at the @@ -2623,6 +2623,8 @@ unwind_command (exp, from_tty) void _initialize_hppa_tdep () { + tm_print_insn = print_insn_hppa; + #ifdef MAINTENANCE_CMDS add_cmd ("unwind", class_maintenance, unwind_command, "Print unwind table entry at given address.", diff --git a/gdb/i386-pinsn.c b/gdb/i386-pinsn.c deleted file mode 100644 index c11ee49a740..00000000000 --- a/gdb/i386-pinsn.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Print i386 instructions for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_i386 (memaddr, &info); -} diff --git a/gdb/i960-pinsn.c b/gdb/i960-pinsn.c deleted file mode 100644 index ef363fa1521..00000000000 --- a/gdb/i960-pinsn.c +++ /dev/null @@ -1,182 +0,0 @@ -/* i80960 instruction disassembler for GDB. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_i960 (memaddr, &info); -} - -/****************************************/ -/* MEM format */ -/****************************************/ - -struct tabent { - char *name; - char numops; -}; - -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; - const 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; -/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table. */ -#define MEM_MIN 0x80 -#define MEM_MAX 0xcf -#define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent)) - - static struct { int opcode; char *name; char numops; } mem_init[] = { - 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, - 0, NULL, 0 - }; - - if ( mem_tab == NULL ){ - mem_tab = (struct tabent *) xmalloc( MEM_SIZ ); - memset( mem_tab, '\0', 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; - } - abort (); -} - -/* 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; - char buf[8]; - - /* Read the two (potential) words of the instruction at once, - to eliminate the overhead of two calls to read_memory (). - FIXME: Loses if the first one is readable but the second is not - (e.g. last word of the segment). */ - - read_memory (memaddr, buf, 8); - *pword1 = extract_unsigned_integer (buf, 4); - *pword2 = extract_unsigned_integer (buf + 4, 4); - - /* 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; -} diff --git a/gdb/i960-tdep.c b/gdb/i960-tdep.c index 013bf8261e4..3ea70117a2b 100644 --- a/gdb/i960-tdep.c +++ b/gdb/i960-tdep.c @@ -1,5 +1,5 @@ /* Target-machine dependent code for the Intel 960 - Copyright (C) 1991 Free Software Foundation, Inc. + Copyright 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by Intel Corporation. examine_prologue and other parts contributed by Wind River Systems. @@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "floatformat.h" #include "target.h" +static CORE_ADDR next_insn PARAMS ((CORE_ADDR memaddr, + unsigned long *pword1, + unsigned long *pword2)); + /* gdb960 is always running on a non-960 host. Check its characteristics. This routine must be called as part of gdb initialization. */ @@ -610,10 +614,156 @@ i960_fault_to_signal (fault) } } -/* Initialization stub */ +/****************************************/ +/* MEM format */ +/****************************************/ + +struct tabent { + char *name; + char numops; +}; + +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; + const 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; +/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table. */ +#define MEM_MIN 0x80 +#define MEM_MAX 0xcf +#define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent)) + + static struct { int opcode; char *name; char numops; } mem_init[] = { + 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, + 0, NULL, 0 + }; + + if ( mem_tab == NULL ){ + mem_tab = (struct tabent *) xmalloc( MEM_SIZ ); + memset( mem_tab, '\0', 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; + } + abort (); +} + +/* 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'. */ + +static CORE_ADDR +next_insn (memaddr, pword1, pword2) + unsigned long *pword1, *pword2; + CORE_ADDR memaddr; +{ + int len; + char buf[8]; + + /* Read the two (potential) words of the instruction at once, + to eliminate the overhead of two calls to read_memory (). + FIXME: Loses if the first one is readable but the second is not + (e.g. last word of the segment). */ + + read_memory (memaddr, buf, 8); + *pword1 = extract_unsigned_integer (buf, 4); + *pword2 = extract_unsigned_integer (buf + 4, 4); + + /* 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; +} void _initialize_i960_tdep () { check_host (); + + tm_print_insn = print_insn_i960; } diff --git a/gdb/m68k-pinsn.c b/gdb/m68k-pinsn.c deleted file mode 100644 index 0eeb9ef2864..00000000000 --- a/gdb/m68k-pinsn.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Print Motorola 68k instructions for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_m68k (memaddr, &info); -} diff --git a/gdb/m88k-pinsn.c b/gdb/m88k-pinsn.c index 0bf2f33a78f..e69de29bb2d 100644 --- a/gdb/m88k-pinsn.c +++ b/gdb/m88k-pinsn.c @@ -1,39 +0,0 @@ -/* Print instructions for the Motorola 88000, for GDB and GNU Binutils. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993 - Free Software Foundation, Inc. - -This file is part of GDB and the GNU Binutils. - -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 2 of the License, 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 "dis-asm.h" - -/* Print the m88k 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - - /* print_insn_m88k is in opcodes/m88k-dis.c. */ - return print_insn_m88k ((bfd_vma) memaddr, &info); -} diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c index 3c8e0e39e75..48cbe257676 100644 --- a/gdb/m88k-tdep.c +++ b/gdb/m88k-tdep.c @@ -1,5 +1,5 @@ /* Target-machine dependent code for Motorola 88000 series, for GDB. - Copyright (C) 1988, 1990, 1991, 1994 Free Software Foundation, Inc. + Copyright 1988, 1990, 1991, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -608,3 +608,9 @@ pop_frame () } reinit_frame_cache (); } + +void +_initialize_m88k_tdep () +{ + tm_print_insn = print_insn_m88k; +} diff --git a/gdb/mips-pinsn.c b/gdb/mips-pinsn.c deleted file mode 100644 index fff36d83c3f..00000000000 --- a/gdb/mips-pinsn.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Print mips instructions for GDB, the GNU debugger. - Copyright 1989, 1991, 1992, 1993 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - /* print_insn_mips is in opcodes/mips-dis.c. */ - if (TARGET_BYTE_ORDER == BIG_ENDIAN) - return print_insn_big_mips ((bfd_vma) memaddr, &info); - else - return print_insn_little_mips ((bfd_vma) memaddr, &info); -} diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 1f2d60d412b..d708b6acabc 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994 + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995 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. @@ -1311,11 +1311,24 @@ reinit_frame_cache_sfunc (args, from_tty, c) reinit_frame_cache (); } +int +gdb_print_insn_mips (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; +{ + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + return print_insn_big_mips (memaddr, info); + else + return print_insn_little_mips (memaddr, info); +} + void _initialize_mips_tdep () { struct cmd_list_element *c; + tm_print_insn = gdb_print_insn_mips; + /* Let the user turn off floating point and set the fence post for heuristic_proc_start. */ diff --git a/gdb/ns32k-pinsn.c b/gdb/ns32k-pinsn.c deleted file mode 100644 index 0732914dc70..00000000000 --- a/gdb/ns32k-pinsn.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Print NS 32000 instructions for GDB, the GNU debugger. - Copyright 1986, 1988, 1991, 1992, 1994 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - - return print_insn_ns32k (memaddr, &info); -} diff --git a/gdb/ns32k-tdep.c b/gdb/ns32k-tdep.c new file mode 100644 index 00000000000..6ba9079b902 --- /dev/null +++ b/gdb/ns32k-tdep.c @@ -0,0 +1,27 @@ +/* Print NS 32000 instructions for GDB, the GNU debugger. + Copyright 1986, 1988, 1991, 1992, 1994, 1995 + Free Software Foundation, Inc. + +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 2 of the License, 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" + +void +_initialize_ns32k_tdep () +{ + tm_print_insn = print_insn_ns32k; +} diff --git a/gdb/pyr-pinsn.c b/gdb/pyr-pinsn.c deleted file mode 100644 index 3ba23d83d77..00000000000 --- a/gdb/pyr-pinsn.c +++ /dev/null @@ -1,338 +0,0 @@ -/* Print Pyramid Technology 90x instructions for GDB, the GNU Debugger. - Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc. - -This file is part of GDB, the GNU debugger. - -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 2 of the License, 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 "symtab.h" -#include "opcode/pyr.h" -#include "gdbcore.h" - - -/* 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 can supplant the normal definitions of some - of the macros in tm-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_unfiltered ("...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_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n", - frame, 60/4, foo); - return foo; -} - -/* 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) - -/* Let's be byte-independent so we can use this as a cross-assembler. */ - -#define NEXTLONG(p) \ - (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]) - -/* 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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (cc_bit_names[i], stream); - bit_codes >>= 1; - } - - fprintf_unfiltered (stream, ",%0x", - displacement + memaddr); - return (insn_size); - } - - switch (operand_mode) { - case 0: - fprintf_unfiltered (stream, "%s,%s", - reg_names [op_1_regno], - reg_names [op_2_regno]); - break; - - case 1: - fprintf_unfiltered (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_unfiltered (stream, " $0x%0x,%s", - extra_1, - reg_names [op_2_regno]); - break; - case 3: - fprintf_unfiltered (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_unfiltered (stream, " 0x%0x(%s),%s", - extra_1, - reg_names [op_1_regno], - reg_names [op_2_regno]); - break; - - /* S1 destination mode */ - case 5: - fprintf_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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 index 70d3e8c539b..43548e8af08 100644 --- a/gdb/pyr-tdep.c +++ b/gdb/pyr-tdep.c @@ -131,3 +131,322 @@ CORE_ADDR frame_args_addr (frame) There seems to be a bug in the way the innermost frame is set up. */ return ((frame->next) ? result: frame->frame_cfp); } + +#include "symtab.h" +#include "opcode/pyr.h" +#include "gdbcore.h" + + +/* 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 can supplant the normal definitions of some + of the macros in tm-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_unfiltered ("...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_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n", + frame, 60/4, foo); + return foo; +} + +/* 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) + +/* Let's be byte-independent so we can use this as a cross-assembler. */ + +#define NEXTLONG(p) \ + (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]) + +/* Print one instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +pyr_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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (cc_bit_names[i], stream); + bit_codes >>= 1; + } + + fprintf_unfiltered (stream, ",%0x", + displacement + memaddr); + return (insn_size); + } + + switch (operand_mode) { + case 0: + fprintf_unfiltered (stream, "%s,%s", + reg_names [op_1_regno], + reg_names [op_2_regno]); + break; + + case 1: + fprintf_unfiltered (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_unfiltered (stream, " $0x%0x,%s", + extra_1, + reg_names [op_2_regno]); + break; + case 3: + fprintf_unfiltered (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_unfiltered (stream, " 0x%0x(%s),%s", + extra_1, + reg_names [op_1_regno], + reg_names [op_2_regno]); + break; + + /* S1 destination mode */ + case 5: + fprintf_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (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_unfiltered (stream, + "\t\t# unknown mode in %08x", + insn); + break; + } /* switch */ + } + + { + return insn_size; + } + abort (); +} diff --git a/gdb/rs6000-pinsn.c b/gdb/rs6000-pinsn.c index 3538cfcb20d..e69de29bb2d 100644 --- a/gdb/rs6000-pinsn.c +++ b/gdb/rs6000-pinsn.c @@ -1,42 +0,0 @@ -/* Print IBM RS/6000 instructions for GNU software. - Copyright 1991,1994 Free Software Foundation, Inc. - Original version was contributed by IBM Corporation. - Now we just use the disassembler in the opcodes directory. - -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 2 of the License, 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 "dis-asm.h" - -/* Print the rs6k instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - -#ifdef GDB_TARGET_POWERPC - return print_insn_big_powerpc ((bfd_vma) memaddr, &info); -#else - return print_insn_rs6000 ((bfd_vma) memaddr, &info); -#endif -} diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 46cf8f75c2c..dad22115f37 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994 + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -1195,3 +1195,14 @@ find_toc_address (pc) return loadinfo[toc_entry].dataorg + loadinfo[toc_entry].toc_offset; } + +void +_initialize_rs6000_tdep () +{ + /* FIXME, this should not be decided via ifdef. */ +#ifdef GDB_TARGET_POWERPC + tm_print_insn = print_insn_big_powerpc; +#else + tm_print_insn = print_insn_rs6000; +#endif +} diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 389b153273b..3f39253b5f8 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -74,22 +74,19 @@ sh_skip_prologue (start_pc) return start_pc; } -/* Disassemble an instruction */ +/* Disassemble an instruction. */ int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; +gdb_print_insn_sh (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; { - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - if (TARGET_BYTE_ORDER == BIG_ENDIAN) return print_insn_sh (memaddr, &info); else return print_insn_shl (memaddr, &info); } + /* Given a GDB frame, determine the address of the calling function's frame. This will be used to create a new GDB frame struct, and then INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. @@ -318,6 +315,9 @@ void _initialize_sh_tdep () { extern int sim_memory_size; + + tm_print_insn = gdb_print_insn_sh; + /* FIXME, there should be a way to make a CORE_ADDR variable settable. */ add_show_from_set (add_set_cmd ("memory_size", class_support, var_uinteger, diff --git a/gdb/sparc-pinsn.c b/gdb/sparc-pinsn.c deleted file mode 100644 index 5ca42dc9f40..00000000000 --- a/gdb/sparc-pinsn.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Print sparc instructions for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. - -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 2 of the License, 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 "dis-asm.h" - -/* 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; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO(info, stream); - - return print_insn_sparc (memaddr, &info); -} diff --git a/gdb/tahoe-pinsn.c b/gdb/tahoe-pinsn.c deleted file mode 100644 index 4016b3bd20c..00000000000 --- a/gdb/tahoe-pinsn.c +++ /dev/null @@ -1,234 +0,0 @@ -/* Print instructions for Tahoe target machines, for GDB. - Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc. - Contributed by the State University of New York at Buffalo, by the - Distributed Computer Systems Lab, Department of Computer Science, 1991. - -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 2 of the License, 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 "symtab.h" -#include "opcode/tahoe.h" - -/* Tahoe instructions are never longer than this. */ -#define MAXLEN 62 - -/* Number of elements in the opcode table. */ -#define NOPCODES (sizeof votstrs / sizeof votstrs[0]) - -static unsigned char *print_insn_arg (); - -/* Print the Tahoe instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_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_unfiltered (stream, "0%o", buffer[0]); - return 1; - } - - fprintf_unfiltered (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_unfiltered ('\t', stream); - - while (*d) - { - p = print_insn_arg (d, p, memaddr + (p - buffer), stream); - d += 2; - if (*d) - fprintf_unfiltered (stream, ","); - } - return p - buffer; -} -/*******************************************************************/ -static unsigned char * -print_insn_arg (d, p, addr, stream) - char *d; - register char *p; - CORE_ADDR addr; - GDB_FILE *stream; -{ - int temp1 = 0; - register int regnum = *p & 0xf; - float floatlitbuf; - - if (*d == 'b') - { - if (d[1] == 'b') - fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1); - else - { - - temp1 = *p; - temp1 <<= 8; - temp1 |= *(p + 1); - fprintf_unfiltered (stream, "0x%x", addr + temp1 + 2); - p += 2; - } - } - else - switch ((*p++ >> 4) & 0xf) - { - case 0: - case 1: - case 2: - case 3: /* Literal (short immediate byte) mode */ - if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h') - { - *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4); - fprintf_unfiltered (stream, "$%f", floatlitbuf); - } - else - fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f); - break; - - case 4: /* Indexed */ - p = (char *) print_insn_arg (d, p, addr + 1, stream); - fprintf_unfiltered (stream, "[%s]", reg_names[regnum]); - break; - - case 5: /* Register */ - fprintf_unfiltered (stream, reg_names[regnum]); - break; - - case 7: /* Autodecrement */ - fputc_unfiltered ('-', stream); - case 6: /* Register deferred */ - fprintf_unfiltered (stream, "(%s)", reg_names[regnum]); - break; - - case 9: /* Absolute Address & Autoincrement deferred */ - fputc_unfiltered ('*', stream); - if (regnum == PC_REGNUM) - { - temp1 = *p; - temp1 <<= 8; - temp1 |= *(p +1); - - fputc_unfiltered ('$', stream); - print_address (temp1, stream); - p += 4; - break; - } - case 8: /*Immediate & Autoincrement SP */ - if (regnum == 8) /*88 is Immediate Byte Mode*/ - fprintf_unfiltered (stream, "$%d", *p++); - - else if (regnum == 9) /*89 is Immediate Word Mode*/ - { - temp1 = *p; - temp1 <<= 8; - temp1 |= *(p +1); - fprintf_unfiltered (stream, "$%d", temp1); - p += 2; - } - - else if (regnum == PC_REGNUM) /*8F is Immediate Long Mode*/ - { - temp1 = *p; - temp1 <<=8; - temp1 |= *(p +1); - temp1 <<=8; - temp1 |= *(p +2); - temp1 <<= 8; - temp1 |= *(p +3); - fprintf_unfiltered (stream, "$%d", temp1); - p += 4; - } - - else /*8E is Autoincrement SP Mode*/ - fprintf_unfiltered (stream, "(%s)+", reg_names[regnum]); - break; - - case 11: /* Register + Byte Displacement Deferred Mode*/ - fputc_unfiltered ('*', stream); - case 10: /* Register + Byte Displacement Mode*/ - if (regnum == PC_REGNUM) - print_address (addr + *p + 2, stream); - else - fprintf_unfiltered (stream, "%d(%s)", *p, reg_names[regnum]); - p += 1; - break; - - case 13: /* Register + Word Displacement Deferred Mode*/ - fputc_unfiltered ('*', stream); - case 12: /* Register + Word Displacement Mode*/ - temp1 = *p; - temp1 <<= 8; - temp1 |= *(p +1); - if (regnum == PC_REGNUM) - print_address (addr + temp1 + 3, stream); - else - fprintf_unfiltered (stream, "%d(%s)", temp1, reg_names[regnum]); - p += 2; - break; - - case 15: /* Register + Long Displacement Deferred Mode*/ - fputc_unfiltered ('*', stream); - case 14: /* Register + Long Displacement Mode*/ - temp1 = *p; - temp1 <<= 8; - temp1 |= *(p +1); - temp1 <<= 8; - temp1 |= *(p +2); - temp1 <<= 8; - temp1 |= *(p +3); - if (regnum == PC_REGNUM) - print_address (addr + temp1 + 5, stream); - else - fprintf_unfiltered (stream, "%d(%s)", temp1, reg_names[regnum]); - p += 4; - } - - return (unsigned char *) p; -} - - - - - - - - - - - - - diff --git a/gdb/tahoe-tdep.c b/gdb/tahoe-tdep.c new file mode 100644 index 00000000000..18cbddb7ff6 --- /dev/null +++ b/gdb/tahoe-tdep.c @@ -0,0 +1,234 @@ +/* Print instructions for Tahoe target machines, for GDB. + Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc. + Contributed by the State University of New York at Buffalo, by the + Distributed Computer Systems Lab, Department of Computer Science, 1991. + +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 2 of the License, 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 "symtab.h" +#include "opcode/tahoe.h" + +/* Tahoe instructions are never longer than this. */ +#define MAXLEN 62 + +/* Number of elements in the opcode table. */ +#define NOPCODES (sizeof votstrs / sizeof votstrs[0]) + +static unsigned char *print_insn_arg (); + +/* Print the Tahoe instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +tahoe_print_insn (memaddr, stream) + CORE_ADDR memaddr; + GDB_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_unfiltered (stream, "0%o", buffer[0]); + return 1; + } + + fprintf_unfiltered (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_unfiltered ('\t', stream); + + while (*d) + { + p = print_insn_arg (d, p, memaddr + (p - buffer), stream); + d += 2; + if (*d) + fprintf_unfiltered (stream, ","); + } + return p - buffer; +} +/*******************************************************************/ +static unsigned char * +print_insn_arg (d, p, addr, stream) + char *d; + register char *p; + CORE_ADDR addr; + GDB_FILE *stream; +{ + int temp1 = 0; + register int regnum = *p & 0xf; + float floatlitbuf; + + if (*d == 'b') + { + if (d[1] == 'b') + fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1); + else + { + + temp1 = *p; + temp1 <<= 8; + temp1 |= *(p + 1); + fprintf_unfiltered (stream, "0x%x", addr + temp1 + 2); + p += 2; + } + } + else + switch ((*p++ >> 4) & 0xf) + { + case 0: + case 1: + case 2: + case 3: /* Literal (short immediate byte) mode */ + if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h') + { + *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4); + fprintf_unfiltered (stream, "$%f", floatlitbuf); + } + else + fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f); + break; + + case 4: /* Indexed */ + p = (char *) print_insn_arg (d, p, addr + 1, stream); + fprintf_unfiltered (stream, "[%s]", reg_names[regnum]); + break; + + case 5: /* Register */ + fprintf_unfiltered (stream, reg_names[regnum]); + break; + + case 7: /* Autodecrement */ + fputc_unfiltered ('-', stream); + case 6: /* Register deferred */ + fprintf_unfiltered (stream, "(%s)", reg_names[regnum]); + break; + + case 9: /* Absolute Address & Autoincrement deferred */ + fputc_unfiltered ('*', stream); + if (regnum == PC_REGNUM) + { + temp1 = *p; + temp1 <<= 8; + temp1 |= *(p +1); + + fputc_unfiltered ('$', stream); + print_address (temp1, stream); + p += 4; + break; + } + case 8: /*Immediate & Autoincrement SP */ + if (regnum == 8) /*88 is Immediate Byte Mode*/ + fprintf_unfiltered (stream, "$%d", *p++); + + else if (regnum == 9) /*89 is Immediate Word Mode*/ + { + temp1 = *p; + temp1 <<= 8; + temp1 |= *(p +1); + fprintf_unfiltered (stream, "$%d", temp1); + p += 2; + } + + else if (regnum == PC_REGNUM) /*8F is Immediate Long Mode*/ + { + temp1 = *p; + temp1 <<=8; + temp1 |= *(p +1); + temp1 <<=8; + temp1 |= *(p +2); + temp1 <<= 8; + temp1 |= *(p +3); + fprintf_unfiltered (stream, "$%d", temp1); + p += 4; + } + + else /*8E is Autoincrement SP Mode*/ + fprintf_unfiltered (stream, "(%s)+", reg_names[regnum]); + break; + + case 11: /* Register + Byte Displacement Deferred Mode*/ + fputc_unfiltered ('*', stream); + case 10: /* Register + Byte Displacement Mode*/ + if (regnum == PC_REGNUM) + print_address (addr + *p + 2, stream); + else + fprintf_unfiltered (stream, "%d(%s)", *p, reg_names[regnum]); + p += 1; + break; + + case 13: /* Register + Word Displacement Deferred Mode*/ + fputc_unfiltered ('*', stream); + case 12: /* Register + Word Displacement Mode*/ + temp1 = *p; + temp1 <<= 8; + temp1 |= *(p +1); + if (regnum == PC_REGNUM) + print_address (addr + temp1 + 3, stream); + else + fprintf_unfiltered (stream, "%d(%s)", temp1, reg_names[regnum]); + p += 2; + break; + + case 15: /* Register + Long Displacement Deferred Mode*/ + fputc_unfiltered ('*', stream); + case 14: /* Register + Long Displacement Mode*/ + temp1 = *p; + temp1 <<= 8; + temp1 |= *(p +1); + temp1 <<= 8; + temp1 |= *(p +2); + temp1 <<= 8; + temp1 |= *(p +3); + if (regnum == PC_REGNUM) + print_address (addr + temp1 + 5, stream); + else + fprintf_unfiltered (stream, "%d(%s)", temp1, reg_names[regnum]); + p += 4; + } + + return (unsigned char *) p; +} + + + + + + + + + + + + + diff --git a/gdb/vax-pinsn.c b/gdb/vax-pinsn.c deleted file mode 100644 index 350d90613b5..00000000000 --- a/gdb/vax-pinsn.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Print VAX instructions for GDB, the GNU debugger. - Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc. - -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 2 of the License, 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 "symtab.h" -#include "opcode/vax.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]) - -static unsigned char *print_insn_arg (); - -/* 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; - GDB_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_unfiltered (stream, "0%o", buffer[0]); - return 1; - } - - fprintf_unfiltered (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_unfiltered (' ', stream); - - while (*d) - { - p = print_insn_arg (d, p, memaddr + (p - buffer), stream); - d += 2; - if (*d) - fprintf_unfiltered (stream, ","); - } - return p - buffer; -} - -static unsigned char * -print_insn_arg (d, p, addr, stream) - char *d; - register char *p; - CORE_ADDR addr; - GDB_FILE *stream; -{ - register int regnum = *p & 0xf; - float floatlitbuf; - - if (*d == 'b') - { - if (d[1] == 'b') - fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1); - else - { - fprintf_unfiltered (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_unfiltered (stream, "$%f", floatlitbuf); - } - else - fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f); - break; - - case 4: /* Indexed */ - p = (char *) print_insn_arg (d, p, addr + 1, stream); - fprintf_unfiltered (stream, "[%s]", reg_names[regnum]); - break; - - case 5: /* Register */ - fprintf_unfiltered (stream, reg_names[regnum]); - break; - - case 7: /* Autodecrement */ - fputc_unfiltered ('-', stream); - case 6: /* Register deferred */ - fprintf_unfiltered (stream, "(%s)", reg_names[regnum]); - break; - - case 9: /* Autoincrement deferred */ - fputc_unfiltered ('@', stream); - if (regnum == PC_REGNUM) - { - fputc_unfiltered ('#', stream); - print_address (*(long *)p, stream); - p += 4; - break; - } - case 8: /* Autoincrement */ - if (regnum == PC_REGNUM) - { - fputc_unfiltered ('#', stream); - switch (d[1]) - { - case 'b': - fprintf_unfiltered (stream, "%d", *p++); - break; - - case 'w': - fprintf_unfiltered (stream, "%d", *(short *)p); - p += 2; - break; - - case 'l': - fprintf_unfiltered (stream, "%d", *(long *)p); - p += 4; - break; - - case 'q': - fprintf_unfiltered (stream, "0x%x%08x", ((long *)p)[1], ((long *)p)[0]); - p += 8; - break; - - case 'o': - fprintf_unfiltered (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_unfiltered (stream, "<>", *(int *) p); - else - fprintf_unfiltered (stream, "%f", *(float *) p); - p += 4; - break; - - case 'd': - if (INVALID_FLOAT (p, 8)) - fprintf_unfiltered (stream, "<>", - ((long *)p)[1], ((long *)p)[0]); - else - fprintf_unfiltered (stream, "%f", *(double *) p); - p += 8; - break; - - case 'g': - fprintf_unfiltered (stream, "g-float"); - p += 8; - break; - - case 'h': - fprintf_unfiltered (stream, "h-float"); - p += 16; - break; - - } - } - else - fprintf_unfiltered (stream, "(%s)+", reg_names[regnum]); - break; - - case 11: /* Byte displacement deferred */ - fputc_unfiltered ('@', stream); - case 10: /* Byte displacement */ - if (regnum == PC_REGNUM) - print_address (addr + *p + 2, stream); - else - fprintf_unfiltered (stream, "%d(%s)", *p, reg_names[regnum]); - p += 1; - break; - - case 13: /* Word displacement deferred */ - fputc_unfiltered ('@', stream); - case 12: /* Word displacement */ - if (regnum == PC_REGNUM) - print_address (addr + *(short *)p + 3, stream); - else - fprintf_unfiltered (stream, "%d(%s)", *(short *)p, reg_names[regnum]); - p += 2; - break; - - case 15: /* Long displacement deferred */ - fputc_unfiltered ('@', stream); - case 14: /* Long displacement */ - if (regnum == PC_REGNUM) - print_address (addr + *(long *)p + 5, stream); - else - fprintf_unfiltered (stream, "%d(%s)", *(long *)p, reg_names[regnum]); - p += 4; - } - - return (unsigned char *) p; -} diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c new file mode 100644 index 00000000000..ba77478506a --- /dev/null +++ b/gdb/vax-tdep.c @@ -0,0 +1,235 @@ +/* Print VAX instructions for GDB, the GNU debugger. + Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc. + +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 2 of the License, 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 "symtab.h" +#include "opcode/vax.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]) + +static unsigned char *print_insn_arg (); + +/* Print the vax instruction at address MEMADDR in debugged memory, + on STREAM. Returns length of the instruction, in bytes. */ + +int +vax_print_insn (memaddr, stream) + CORE_ADDR memaddr; + GDB_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_unfiltered (stream, "0%o", buffer[0]); + return 1; + } + + fprintf_unfiltered (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_unfiltered (' ', stream); + + while (*d) + { + p = print_insn_arg (d, p, memaddr + (p - buffer), stream); + d += 2; + if (*d) + fprintf_unfiltered (stream, ","); + } + return p - buffer; +} + +static unsigned char * +print_insn_arg (d, p, addr, stream) + char *d; + register char *p; + CORE_ADDR addr; + GDB_FILE *stream; +{ + register int regnum = *p & 0xf; + float floatlitbuf; + + if (*d == 'b') + { + if (d[1] == 'b') + fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1); + else + { + fprintf_unfiltered (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_unfiltered (stream, "$%f", floatlitbuf); + } + else + fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f); + break; + + case 4: /* Indexed */ + p = (char *) print_insn_arg (d, p, addr + 1, stream); + fprintf_unfiltered (stream, "[%s]", reg_names[regnum]); + break; + + case 5: /* Register */ + fprintf_unfiltered (stream, reg_names[regnum]); + break; + + case 7: /* Autodecrement */ + fputc_unfiltered ('-', stream); + case 6: /* Register deferred */ + fprintf_unfiltered (stream, "(%s)", reg_names[regnum]); + break; + + case 9: /* Autoincrement deferred */ + fputc_unfiltered ('@', stream); + if (regnum == PC_REGNUM) + { + fputc_unfiltered ('#', stream); + print_address (*(long *)p, stream); + p += 4; + break; + } + case 8: /* Autoincrement */ + if (regnum == PC_REGNUM) + { + fputc_unfiltered ('#', stream); + switch (d[1]) + { + case 'b': + fprintf_unfiltered (stream, "%d", *p++); + break; + + case 'w': + fprintf_unfiltered (stream, "%d", *(short *)p); + p += 2; + break; + + case 'l': + fprintf_unfiltered (stream, "%d", *(long *)p); + p += 4; + break; + + case 'q': + fprintf_unfiltered (stream, "0x%x%08x", ((long *)p)[1], ((long *)p)[0]); + p += 8; + break; + + case 'o': + fprintf_unfiltered (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_unfiltered (stream, "<>", *(int *) p); + else + fprintf_unfiltered (stream, "%f", *(float *) p); + p += 4; + break; + + case 'd': + if (INVALID_FLOAT (p, 8)) + fprintf_unfiltered (stream, "<>", + ((long *)p)[1], ((long *)p)[0]); + else + fprintf_unfiltered (stream, "%f", *(double *) p); + p += 8; + break; + + case 'g': + fprintf_unfiltered (stream, "g-float"); + p += 8; + break; + + case 'h': + fprintf_unfiltered (stream, "h-float"); + p += 16; + break; + + } + } + else + fprintf_unfiltered (stream, "(%s)+", reg_names[regnum]); + break; + + case 11: /* Byte displacement deferred */ + fputc_unfiltered ('@', stream); + case 10: /* Byte displacement */ + if (regnum == PC_REGNUM) + print_address (addr + *p + 2, stream); + else + fprintf_unfiltered (stream, "%d(%s)", *p, reg_names[regnum]); + p += 1; + break; + + case 13: /* Word displacement deferred */ + fputc_unfiltered ('@', stream); + case 12: /* Word displacement */ + if (regnum == PC_REGNUM) + print_address (addr + *(short *)p + 3, stream); + else + fprintf_unfiltered (stream, "%d(%s)", *(short *)p, reg_names[regnum]); + p += 2; + break; + + case 15: /* Long displacement deferred */ + fputc_unfiltered ('@', stream); + case 14: /* Long displacement */ + if (regnum == PC_REGNUM) + print_address (addr + *(long *)p + 5, stream); + else + fprintf_unfiltered (stream, "%d(%s)", *(long *)p, reg_names[regnum]); + p += 4; + } + + return (unsigned char *) p; +} diff --git a/gdb/w65-tdep.c b/gdb/w65-tdep.c index 0b047ec6d24..3af771f0215 100644 --- a/gdb/w65-tdep.c +++ b/gdb/w65-tdep.c @@ -65,18 +65,6 @@ w65_push_dummy_frame () abort (); } -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; -{ - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - - return print_insn_w65 ((bfd_vma) memaddr, &info); -} - /* 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 @@ -299,3 +287,9 @@ print_register_hook (regno) printf_unfiltered ("<= "); } } + +void +_initialize_w65_tdep () +{ + tm_print_insn = print_insn_w65; +} diff --git a/gdb/z8k-tdep.c b/gdb/z8k-tdep.c index 60a07bee536..de7c6a9d39a 100644 --- a/gdb/z8k-tdep.c +++ b/gdb/z8k-tdep.c @@ -205,22 +205,14 @@ z8k_push_dummy_frame () } int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - GDB_FILE *stream; +gdb_print_insn_z8k (memaddr, info) + bfd_vma memaddr; + disassemble_info *info; { - disassemble_info info; - - GDB_INIT_DISASSEMBLE_INFO (info, stream); - if (BIG) - { - return print_insn_z8001 ((bfd_vma) memaddr, &info); - } + return print_insn_z8001 (memaddr, info); else - { - return print_insn_z8002 ((bfd_vma) memaddr, &info); - } + return print_insn_z8002 (memaddr, info); } /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or @@ -443,6 +435,8 @@ set_memory (args, from_tty) void _initialize_z8ktdep () { + tm_print_insn = gdb_print_insn_z8k; + add_prefix_cmd ("memory", no_class, set_memory, "set the memory model", &setmemorylist, "set memory ", 0, &setlist);