/* Convex stuff for GDB.
- Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1996 Free Software Foundation, Inc.
This file is part of GDB.
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. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "command.h"
#include <sys/thread.h>
#include <sys/proc.h>
#include <sys/file.h>
-#include <sys/stat.h>
+#include "gdb_stat.h"
#include <sys/mman.h>
#include "gdbcmd.h"
(*exec_file_display_hook) (filename);
}
+#if 0
/* Read data from SOFF exec or core file.
Return 0 on success, EIO if address out of bounds. */
read zeros if reading, or do nothing if writing. */
else
{
- bzero (myaddr, i);
+ memset (myaddr, '\0', i);
returnval = EIO;
}
}
return returnval;
}
-
+#endif
/* Here from info files command to print an address map. */
if ((name[0] == 'v' || name[0] == 'V')
&& (((name[1] & -8) == '0' && name[2] == '\0')
- || !strcmp (name, "vl")
- || !strcmp (name, "vs")
- || !strcmp (name, "vm")))
+ || STREQ (name, "vl")
+ || STREQ (name, "vs")
+ || STREQ (name, "vm")))
return 1;
else return 0;
}
char *name = var->name;
value val;
struct type *type;
+ struct type *range_type;
long len = *read_vector_register (VL_REGNUM);
if (len <= 0 || len > 128) len = 128;
- if (!strcmp (name, "vl"))
+ if (STREQ (name, "vl"))
{
val = value_from_longest (builtin_type_int,
(LONGEST) *read_vector_register_1 (VL_REGNUM));
}
- else if (!strcmp (name, "vs"))
+ else if (STREQ (name, "vs"))
{
val = value_from_longest (builtin_type_int,
(LONGEST) *read_vector_register_1 (VS_REGNUM));
}
- else if (!strcmp (name, "vm"))
+ else if (STREQ (name, "vm"))
{
long vm[4];
long i, *p;
- bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);
- type = create_array_type ((struct type *) NULL, builtin_type_int,
- builtin_type_int, 0, len - 1);
+ memcpy (vm, read_vector_register_1 (VM_REGNUM), sizeof vm);
+ range_type =
+ create_range_type ((struct type *) NULL, builtin_type_int, 0, len - 1);
+ type =
+ create_array_type ((struct type *) NULL, builtin_type_int, range_type);
val = allocate_value (type);
p = (long *) VALUE_CONTENTS (val);
for (i = 0; i < len; i++)
}
else if (name[0] == 'V')
{
- type = create_array_type ((struct type *) NULL, builtin_type_long_long,
- builtin_type_int, 0, len - 1);
+ range_type =
+ create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
+ type =
+ create_array_type ((struct type *) NULL, builtin_type_long_long,
+ range_type);
val = allocate_value (type);
- bcopy (read_vector_register_1 (name[1] - '0'),
- VALUE_CONTENTS (val), TYPE_LENGTH (type));
+ memcpy (VALUE_CONTENTS (val),
+ read_vector_register_1 (name[1] - '0'),
+ TYPE_LENGTH (type));
}
else if (name[0] == 'v')
{
long *p1, *p2;
- type = create_array_type ((struct type *) NULL, builtin_type_long,
- builtin_type_int, 0, len - 1);
+ range_type =
+ create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
+ type =
+ create_array_type ((struct type *) NULL, builtin_type_long,
+ range_type);
val = allocate_value (type);
p1 = read_vector_register_1 (name[1] - '0');
p2 = (long *) VALUE_CONTENTS (val);
char *name = var->name;
long long newval = value_as_long (val);
- if (!strcmp (name, "vl"))
+ if (STREQ (name, "vl"))
write_vector_register (VL_REGNUM, 0, newval);
- else if (!strcmp (name, "vs"))
+ else if (STREQ (name, "vs"))
write_vector_register (VS_REGNUM, 0, newval);
else if (name[0] == 'c' || name[0] == 'C')
write_comm_register (atoi (&name[1]), newval);
- else if (!strcmp (name, "vm"))
+ else if (STREQ (name, "vm"))
error ("can't assign to $vm");
else
{
&& ((lv & 0xf0000000) == 0x80000000
|| ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
{
- fprintf_filtered (stream, "%#x", lv);
+ print_longest (stream, "x", 0, val);
return;
}
case 10:
- fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
+ print_longest (stream, TYPE_UNSIGNED (type) ? "u" : "d", 0, val);
return;
case 8:
- if (TYPE_LENGTH (type) <= sizeof lv)
- fprintf_filtered (stream, "%#o", lv);
- else
- fprintf_filtered (stream, "%#llo", val);
+ print_longest (stream, "o", 0, val);
return;
case 16:
- if (TYPE_LENGTH (type) <= sizeof lv)
- fprintf_filtered (stream, "%#x", lv);
- else
- fprintf_filtered (stream, "%#llx", val);
+ print_longest (stream, "x", 0, val);
return;
}
}
sequential = !sequential;
printf_filtered ("%s\n", sequential ? "off" : "on");
}
- else if (!strcmp (arg, "on"))
+ else if (STREQ (arg, "on"))
sequential = 0;
- else if (!strcmp (arg, "off"))
+ else if (STREQ (arg, "off"))
sequential = 1;
else error ("valid args are `on', to allow instructions to overlap, or\n\
`off', to prevent it and thereby pinpoint exceptions.");
if (!strncmp (arg, "fixed", strlen (arg)))
parallel = 2;
- else if (!strcmp (arg, "on"))
+ else if (STREQ (arg, "on"))
parallel = 1;
- else if (!strcmp (arg, "off"))
+ else if (STREQ (arg, "off"))
parallel = 0;
else error ("valid args are `on', to allow multiple threads, or\n\
`fixed', to force multiple threads, or\n\
ioctl (inferior_fd, PIXRDCREGS, &ps);
}
+ /* FIXME: stop_signal is from target.h but stop_sigcode is a
+ convex-specific thing. */
printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
inferior_thread, stop_signal, stop_sigcode,
subsig_name (stop_signal, stop_sigcode));
stop_pc = read_pc ();
flush_cached_frames ();
- set_current_frame (create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, selected_frame_level, -1);
}
}
}
\f
+#include "symtab.h"
+
+/* reg (fmt_field, inst_field) --
+ the {first,second,third} operand of instruction as fmt_field = [ijk]
+ gets the value of the field from the [ijk] position of the instruction */
+
+#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
+
+/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
+
+#define lit(i) op[fmt->i]
+
+/* aj[j] -- name for A register j */
+
+#define aj ((char (*)[3])(op[A]))
+\f
+union inst {
+ struct {
+ unsigned : 7;
+ unsigned i : 3;
+ unsigned j : 3;
+ unsigned k : 3;
+ unsigned : 16;
+ unsigned : 32;
+ } f0;
+ struct {
+ unsigned : 8;
+ unsigned indir : 1;
+ unsigned len : 1;
+ unsigned j : 3;
+ unsigned k : 3;
+ unsigned : 16;
+ unsigned : 32;
+ } f1;
+ unsigned char byte[8];
+ unsigned short half[4];
+ char signed_byte[8];
+ short signed_half[4];
+};
+
+struct opform {
+ int mask; /* opcode mask */
+ int shift; /* opcode align */
+ struct formstr *formstr[3]; /* ST, E0, E1 */
+};
+
+struct formstr {
+ unsigned lop:8, rop:5; /* opcode */
+ unsigned fmt:5; /* inst format */
+ unsigned i:5, j:5, k:2; /* operand formats */
+};
+
+#include "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,
+};
+\f
+/* 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;
+}
+
+\f
+void
_initialize_convex_dep ()
{
add_com ("alias", class_support, alias_command,