]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/convex-tdep.c
* mpw-config.in: Generate Mac include for elf/dwarf2.h.
[thirdparty/binutils-gdb.git] / gdb / convex-tdep.c
CommitLineData
dd3b648e 1/* Convex stuff for GDB.
e1a623e7 2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB.
5
99a7de40 6This program is free software; you can redistribute it and/or modify
dd3b648e 7it under the terms of the GNU General Public License as published by
99a7de40
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
dd3b648e 10
99a7de40 11This program is distributed in the hope that it will be useful,
dd3b648e
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
99a7de40 17along with this program; if not, write to the Free Software
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
dd3b648e 19
dd3b648e 20#include "defs.h"
dd3b648e
RP
21#include "command.h"
22#include "symtab.h"
23#include "value.h"
24#include "frame.h"
25#include "inferior.h"
26#include "wait.h"
27
28#include <signal.h>
29#include <fcntl.h>
30
31#include "gdbcore.h"
32#include <sys/param.h>
33#include <sys/dir.h>
34#include <sys/user.h>
35#include <sys/ioctl.h>
36#include <sys/pcntl.h>
37#include <sys/thread.h>
38#include <sys/proc.h>
39#include <sys/file.h>
2b576293 40#include "gdb_stat.h"
dd3b648e
RP
41#include <sys/mman.h>
42
43#include "gdbcmd.h"
44
45exec_file_command (filename, from_tty)
46 char *filename;
47 int from_tty;
48{
49 int val;
50 int n;
51 struct stat st_exec;
52
53 /* Eliminate all traces of old exec file.
54 Mark text segment as empty. */
55
56 if (execfile)
57 free (execfile);
58 execfile = 0;
59 data_start = 0;
60 data_end = 0;
61 text_start = 0;
62 text_end = 0;
63 exec_data_start = 0;
64 exec_data_end = 0;
65 if (execchan >= 0)
66 close (execchan);
67 execchan = -1;
68
69 n_exec = 0;
70
71 /* Now open and digest the file the user requested, if any. */
72
73 if (filename)
74 {
75 filename = tilde_expand (filename);
76 make_cleanup (free, filename);
77
78 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
79 &execfile);
80 if (execchan < 0)
81 perror_with_name (filename);
82
83 if (myread (execchan, &filehdr, sizeof filehdr) < 0)
84 perror_with_name (filename);
85
86 if (! IS_SOFF_MAGIC (filehdr.h_magic))
87 error ("%s: not an executable file.", filename);
88
89 if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)
90 perror_with_name (filename);
91
92 /* Read through the section headers.
93 For text, data, etc, record an entry in the exec file map.
94 Record text_start and text_end. */
95
96 lseek (execchan, (long) filehdr.h_scnptr, 0);
97
98 for (n = 0; n < filehdr.h_nscns; n++)
99 {
100 if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)
101 perror_with_name (filename);
102
103 if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
104 && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
105 {
106 exec_map[n_exec].mem_addr = scnhdr.s_vaddr;
107 exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
108 exec_map[n_exec].file_addr = scnhdr.s_scnptr;
109 exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;
110 n_exec++;
111
112 if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)
113 {
114 text_start = scnhdr.s_vaddr;
115 text_end = scnhdr.s_vaddr + scnhdr.s_size;
116 }
117 }
118 }
119
120 fstat (execchan, &st_exec);
121 exec_mtime = st_exec.st_mtime;
122
123 validate_files ();
124 }
125 else if (from_tty)
126 printf_filtered ("No exec file now.\n");
127
128 /* Tell display code (if any) about the changed file name. */
129 if (exec_file_display_hook)
130 (*exec_file_display_hook) (filename);
131}
132
0d2d8412 133#if 0
dd3b648e
RP
134/* Read data from SOFF exec or core file.
135 Return 0 on success, EIO if address out of bounds. */
136
137int
138xfer_core_file (memaddr, myaddr, len)
139 CORE_ADDR memaddr;
140 char *myaddr;
141 int len;
142{
143 register int i;
144 register int n;
145 register int val;
146 int xferchan;
147 char **xferfile;
148 int fileptr;
149 int returnval = 0;
150
151 while (len > 0)
152 {
153 xferfile = 0;
154 xferchan = 0;
155
156 /* Determine which file the next bunch of addresses reside in,
157 and where in the file. Set the file's read/write pointer
158 to point at the proper place for the desired address
159 and set xferfile and xferchan for the correct file.
160 If desired address is nonexistent, leave them zero.
161 i is set to the number of bytes that can be handled
162 along with the next address. */
163
164 i = len;
165
166 for (n = 0; n < n_core; n++)
167 {
168 if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end
169 && (core_map[n].thread == -1
170 || core_map[n].thread == inferior_thread))
171 {
172 i = min (len, core_map[n].mem_end - memaddr);
173 fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;
174 if (core_map[n].file_addr)
175 {
176 xferfile = &corefile;
177 xferchan = corechan;
178 }
179 break;
180 }
181 else if (core_map[n].mem_addr >= memaddr
182 && core_map[n].mem_addr < memaddr + i)
183 i = core_map[n].mem_addr - memaddr;
184 }
185
186 if (!xferfile)
187 for (n = 0; n < n_exec; n++)
188 {
189 if (memaddr >= exec_map[n].mem_addr
190 && memaddr < exec_map[n].mem_end)
191 {
192 i = min (len, exec_map[n].mem_end - memaddr);
193 fileptr = exec_map[n].file_addr + memaddr
194 - exec_map[n].mem_addr;
195 if (exec_map[n].file_addr)
196 {
197 xferfile = &execfile;
198 xferchan = execchan;
199 }
200 break;
201 }
202 else if (exec_map[n].mem_addr >= memaddr
203 && exec_map[n].mem_addr < memaddr + i)
204 i = exec_map[n].mem_addr - memaddr;
205 }
206
207 /* Now we know which file to use.
208 Set up its pointer and transfer the data. */
209 if (xferfile)
210 {
211 if (*xferfile == 0)
212 if (xferfile == &execfile)
213 error ("No program file to examine.");
214 else
215 error ("No core dump file or running program to examine.");
216 val = lseek (xferchan, fileptr, 0);
217 if (val < 0)
218 perror_with_name (*xferfile);
219 val = myread (xferchan, myaddr, i);
220 if (val < 0)
221 perror_with_name (*xferfile);
222 }
223 /* If this address is for nonexistent memory,
224 read zeros if reading, or do nothing if writing. */
225 else
226 {
4ed97c9a 227 memset (myaddr, '\0', i);
dd3b648e
RP
228 returnval = EIO;
229 }
230
231 memaddr += i;
232 myaddr += i;
233 len -= i;
234 }
235 return returnval;
236}
0d2d8412 237#endif
dd3b648e
RP
238
239/* Here from info files command to print an address map. */
240
241print_maps ()
242{
243 struct pmap ptrs[200];
244 int n;
245
246 /* ID strings for core and executable file sections */
247
248 static char *idstr[] =
249 {
250 "0", "text", "data", "tdata", "bss", "tbss",
251 "common", "ttext", "ctx", "tctx", "10", "11", "12",
252 };
253
254 for (n = 0; n < n_core; n++)
255 {
256 core_map[n].which = 0;
257 ptrs[n] = core_map[n];
258 }
259 for (n = 0; n < n_exec; n++)
260 {
261 exec_map[n].which = 1;
262 ptrs[n_core+n] = exec_map[n];
263 }
264
265 qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);
266
267 for (n = 0; n < n_core + n_exec; n++)
268 {
269 struct pmap *p = &ptrs[n];
270 if (n > 0)
271 {
272 if (p->mem_addr < ptrs[n-1].mem_end)
273 p->mem_addr = ptrs[n-1].mem_end;
274 if (p->mem_addr >= p->mem_end)
275 continue;
276 }
277 printf_filtered ("%08x .. %08x %-6s %s\n",
278 p->mem_addr, p->mem_end, idstr[p->type],
279 p->which ? execfile : corefile);
280 }
281}
282
283/* Compare routine to put file sections in order.
284 Sort into increasing order on address, and put core file sections
285 before exec file sections if both files contain the same addresses. */
286
287static ptr_cmp (a, b)
288 struct pmap *a, *b;
289{
290 if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;
291 return a->which - b->which;
292}
293\f
294/* Trapped internal variables are used to handle special registers.
295 A trapped i.v. calls a hook here every time it is dereferenced,
296 to provide a new value for the variable, and it calls a hook here
297 when a new value is assigned, to do something with the value.
298
299 The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
300 The communication registers are $cN, $CN (N in 0..63).
301 They not handled as regular registers because it's expensive to
302 read them, and their size varies, and they have too many names. */
303
304
305/* Return 1 if NAME is a trapped internal variable, else 0. */
306
307int
308is_trapped_internalvar (name)
309 char *name;
310{
311 if ((name[0] == 'c' || name[0] == 'C')
312 && name[1] >= '0' && name[1] <= '9'
313 && (name[2] == '\0'
314 || (name[2] >= '0' && name[2] <= '9'
315 && name[3] == '\0' && name[1] != '0'))
316 && atoi (&name[1]) < 64) return 1;
317
318 if ((name[0] == 'v' || name[0] == 'V')
319 && (((name[1] & -8) == '0' && name[2] == '\0')
2e4964ad
FF
320 || STREQ (name, "vl")
321 || STREQ (name, "vs")
322 || STREQ (name, "vm")))
dd3b648e
RP
323 return 1;
324 else return 0;
325}
326
327/* Return the value of trapped internal variable VAR */
328
329value
330value_of_trapped_internalvar (var)
331 struct internalvar *var;
332{
333 char *name = var->name;
334 value val;
335 struct type *type;
a8a69e63 336 struct type *range_type;
dd3b648e
RP
337 long len = *read_vector_register (VL_REGNUM);
338 if (len <= 0 || len > 128) len = 128;
339
2e4964ad 340 if (STREQ (name, "vl"))
dd3b648e 341 {
06b6c733 342 val = value_from_longest (builtin_type_int,
dd3b648e
RP
343 (LONGEST) *read_vector_register_1 (VL_REGNUM));
344 }
2e4964ad 345 else if (STREQ (name, "vs"))
dd3b648e 346 {
06b6c733 347 val = value_from_longest (builtin_type_int,
dd3b648e
RP
348 (LONGEST) *read_vector_register_1 (VS_REGNUM));
349 }
2e4964ad 350 else if (STREQ (name, "vm"))
dd3b648e
RP
351 {
352 long vm[4];
353 long i, *p;
ade40d31 354 memcpy (vm, read_vector_register_1 (VM_REGNUM), sizeof vm);
a8a69e63
FF
355 range_type =
356 create_range_type ((struct type *) NULL, builtin_type_int, 0, len - 1);
357 type =
358 create_array_type ((struct type *) NULL, builtin_type_int, range_type);
dd3b648e
RP
359 val = allocate_value (type);
360 p = (long *) VALUE_CONTENTS (val);
361 for (i = 0; i < len; i++)
362 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
363 }
364 else if (name[0] == 'V')
365 {
a8a69e63
FF
366 range_type =
367 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
368 type =
369 create_array_type ((struct type *) NULL, builtin_type_long_long,
370 range_type);
dd3b648e 371 val = allocate_value (type);
ade40d31
RP
372 memcpy (VALUE_CONTENTS (val),
373 read_vector_register_1 (name[1] - '0'),
374 TYPE_LENGTH (type));
dd3b648e
RP
375 }
376 else if (name[0] == 'v')
377 {
378 long *p1, *p2;
a8a69e63
FF
379 range_type =
380 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
381 type =
382 create_array_type ((struct type *) NULL, builtin_type_long,
383 range_type);
dd3b648e
RP
384 val = allocate_value (type);
385 p1 = read_vector_register_1 (name[1] - '0');
386 p2 = (long *) VALUE_CONTENTS (val);
387 while (--len >= 0) {p1++; *p2++ = *p1++;}
388 }
389
390 else if (name[0] == 'c')
06b6c733 391 val = value_from_longest (builtin_type_int,
dd3b648e
RP
392 read_comm_register (atoi (&name[1])));
393 else if (name[0] == 'C')
06b6c733 394 val = value_from_longest (builtin_type_long_long,
dd3b648e
RP
395 read_comm_register (atoi (&name[1])));
396
397 VALUE_LVAL (val) = lval_internalvar;
398 VALUE_INTERNALVAR (val) = var;
399 return val;
400}
401
dd3b648e
RP
402/* Handle a new value assigned to a trapped internal variable */
403
404void
405set_trapped_internalvar (var, val, bitpos, bitsize, offset)
406 struct internalvar *var;
407 value val;
408 int bitpos, bitsize, offset;
409{
410 char *name = var->name;
411 long long newval = value_as_long (val);
412
2e4964ad 413 if (STREQ (name, "vl"))
dd3b648e 414 write_vector_register (VL_REGNUM, 0, newval);
2e4964ad 415 else if (STREQ (name, "vs"))
dd3b648e
RP
416 write_vector_register (VS_REGNUM, 0, newval);
417 else if (name[0] == 'c' || name[0] == 'C')
418 write_comm_register (atoi (&name[1]), newval);
2e4964ad 419 else if (STREQ (name, "vm"))
dd3b648e
RP
420 error ("can't assign to $vm");
421 else
422 {
423 offset /= bitsize / 8;
424 write_vector_register (name[1] - '0', offset, newval);
425 }
426}
427
428/* Print an integer value when no format was specified. gdb normally
429 prints these values in decimal, but the the leading 0x80000000 of
430 pointers produces intolerable 10-digit negative numbers.
431 If it looks like an address, print it in hex instead. */
432
433decout (stream, type, val)
434 FILE *stream;
435 struct type *type;
436 LONGEST val;
437{
438 long lv = val;
439
440 switch (output_radix)
441 {
442 case 0:
443 if ((lv == val || (unsigned) lv == val)
444 && ((lv & 0xf0000000) == 0x80000000
445 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
446 {
447 fprintf_filtered (stream, "%#x", lv);
448 return;
449 }
450
451 case 10:
452 fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
453 return;
454
455 case 8:
456 if (TYPE_LENGTH (type) <= sizeof lv)
457 fprintf_filtered (stream, "%#o", lv);
458 else
459 fprintf_filtered (stream, "%#llo", val);
460 return;
461
462 case 16:
463 if (TYPE_LENGTH (type) <= sizeof lv)
464 fprintf_filtered (stream, "%#x", lv);
465 else
466 fprintf_filtered (stream, "%#llx", val);
467 return;
468 }
469}
470
471/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
472 This command is mostly obsolete now that the print command allows
473 formats to apply to aggregates, but is still handy occasionally. */
474
475static void
476set_base_command (arg)
477 char *arg;
478{
479 int new_radix;
480
481 if (!arg)
482 output_radix = 0;
483 else
484 {
485 new_radix = atoi (arg);
486 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
487 error ("base must be 8, 10 or 16, or null");
488 else output_radix = new_radix;
489 }
490}
491
492/* Turn pipelining on or off in the inferior. */
493
494static void
495set_pipelining_command (arg)
496 char *arg;
497{
498 if (!arg)
499 {
500 sequential = !sequential;
501 printf_filtered ("%s\n", sequential ? "off" : "on");
502 }
2e4964ad 503 else if (STREQ (arg, "on"))
dd3b648e 504 sequential = 0;
2e4964ad 505 else if (STREQ (arg, "off"))
dd3b648e
RP
506 sequential = 1;
507 else error ("valid args are `on', to allow instructions to overlap, or\n\
508`off', to prevent it and thereby pinpoint exceptions.");
509}
510
511/* Enable, disable, or force parallel execution in the inferior. */
512
513static void
514set_parallel_command (arg)
515 char *arg;
516{
517 struct rlimit rl;
518 int prevparallel = parallel;
519
520 if (!strncmp (arg, "fixed", strlen (arg)))
521 parallel = 2;
2e4964ad 522 else if (STREQ (arg, "on"))
dd3b648e 523 parallel = 1;
2e4964ad 524 else if (STREQ (arg, "off"))
dd3b648e
RP
525 parallel = 0;
526 else error ("valid args are `on', to allow multiple threads, or\n\
527`fixed', to force multiple threads, or\n\
528`off', to run with one thread only.");
529
530 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
531 printf_filtered ("will take effect at next run.\n");
532
533 getrlimit (RLIMIT_CONCUR, &rl);
534 rl.rlim_cur = parallel ? rl.rlim_max : 1;
535 setrlimit (RLIMIT_CONCUR, &rl);
536
537 if (inferior_pid)
538 set_fixed_scheduling (inferior_pid, parallel == 2);
539}
540
541/* Add a new name for an existing command. */
542
543static void
544alias_command (arg)
545 char *arg;
546{
547 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
548 char *newname = arg;
549 struct cmd_list_element *new, *old;
550
551 if (!arg)
552 error_no_arg ("newname oldname");
553
554 new = lookup_cmd (&arg, cmdlist, "", -1);
555 if (new && !strncmp (newname, new->name, strlen (new->name)))
556 {
557 newname = new->name;
558 if (!(*arg == '-'
559 || (*arg >= 'a' && *arg <= 'z')
560 || (*arg >= 'A' && *arg <= 'Z')
561 || (*arg >= '0' && *arg <= '9')))
562 error (aliaserr);
563 }
564 else
565 {
566 arg = newname;
567 while (*arg == '-'
568 || (*arg >= 'a' && *arg <= 'z')
569 || (*arg >= 'A' && *arg <= 'Z')
570 || (*arg >= '0' && *arg <= '9'))
571 arg++;
572 if (*arg != ' ' && *arg != '\t')
573 error (aliaserr);
574 *arg = '\0';
575 arg++;
576 }
577
578 old = lookup_cmd (&arg, cmdlist, "", 0);
579
580 if (*arg != '\0')
581 error (aliaserr);
582
583 if (new && !strncmp (newname, new->name, strlen (new->name)))
584 {
585 char *tem;
586 if (new->class == (int) class_user || new->class == (int) class_alias)
587 tem = "Redefine command \"%s\"? ";
588 else
589 tem = "Really redefine built-in command \"%s\"? ";
590 if (!query (tem, new->name))
591 error ("Command \"%s\" not redefined.", new->name);
592 }
593
594 add_com (newname, class_alias, old->function, old->doc);
595}
596
597
598
599/* Print the current thread number, and any threads with signals in the
600 queue. */
601
602thread_info ()
603{
604 struct threadpid *p;
605
606 if (have_inferior_p ())
607 {
608 ps.pi_buffer = (char *) &comm_registers;
609 ps.pi_nbytes = sizeof comm_registers;
610 ps.pi_offset = 0;
611 ps.pi_thread = inferior_thread;
612 ioctl (inferior_fd, PIXRDCREGS, &ps);
613 }
614
67ac9759
JK
615 /* FIXME: stop_signal is from target.h but stop_sigcode is a
616 convex-specific thing. */
dd3b648e
RP
617 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
618 inferior_thread, stop_signal, stop_sigcode,
619 subsig_name (stop_signal, stop_sigcode));
620
621 for (p = signal_stack; p->pid; p--)
622 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
623 p->thread, p->signo, p->subsig,
624 subsig_name (p->signo, p->subsig));
625
626 if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
627 printf_filtered ("New thread start pc %#x\n",
628 (long) (comm_registers.crreg.pcpsw >> 32));
629}
630
631/* Return string describing a signal.subcode number */
632
633static char *
634subsig_name (signo, subcode)
635 int signo, subcode;
636{
637 static char *subsig4[] = {
638 "error exit", "privileged instruction", "unknown",
639 "unknown", "undefined opcode",
640 0};
641 static char *subsig5[] = {0,
642 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
643 "join trap", "idle trap", "last thread", "wfork trap",
644 "process breakpoint", "trap instruction",
645 0};
646 static char *subsig8[] = {0,
647 "int overflow", "int divide check", "float overflow",
648 "float divide check", "float underflow", "reserved operand",
649 "sqrt error", "exp error", "ln error", "sin error", "cos error",
650 0};
651 static char *subsig10[] = {0,
652 "invalid inward ring address", "invalid outward ring call",
653 "invalid inward ring return", "invalid syscall gate",
654 "invalid rtn frame length", "invalid comm reg address",
655 "invalid trap gate",
656 0};
657 static char *subsig11[] = {0,
658 "read access denied", "write access denied", "execute access denied",
659 "segment descriptor fault", "page table fault", "data reference fault",
660 "i/o access denied", "levt pte invalid",
661 0};
662
663 static char **subsig_list[] =
664 {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
665
666 int i;
4ace50a5 667 char *p;
dd3b648e 668
4ace50a5
FF
669 if ((p = strsignal (signo)) == NULL)
670 p = "unknown";
dd3b648e
RP
671 if (signo >= (sizeof subsig_list / sizeof *subsig_list)
672 || !subsig_list[signo])
673 return p;
674 for (i = 1; subsig_list[signo][i]; i++)
675 if (i == subcode)
676 return subsig_list[signo][subcode];
677 return p;
678}
679
680
681/* Print a compact display of thread status, essentially x/i $pc
682 for all active threads. */
683
684static void
685threadstat ()
686{
687 int t;
688
689 for (t = 0; t < n_threads; t++)
690 if (thread_state[t] == PI_TALIVE)
691 {
692 printf_filtered ("%d%c %08x%c %d.%d ", t,
693 (t == inferior_thread ? '*' : ' '), thread_pc[t],
694 (thread_is_in_kernel[t] ? '#' : ' '),
695 thread_signal[t], thread_sigcode[t]);
696 print_insn (thread_pc[t], stdout);
697 printf_filtered ("\n");
698 }
699}
700
701/* Change the current thread to ARG. */
702
703set_thread_command (arg)
704 char *arg;
705{
706 int thread;
707
708 if (!arg)
709 {
710 threadstat ();
711 return;
712 }
713
714 thread = parse_and_eval_address (arg);
715
716 if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
717 error ("no such thread.");
718
719 select_thread (thread);
720
721 stop_pc = read_pc ();
722 flush_cached_frames ();
dd3b648e 723 select_frame (get_current_frame (), 0);
cadbb07a 724 print_stack_frame (selected_frame, selected_frame_level, -1);
dd3b648e
RP
725}
726
727/* Here on CONT command; gdb's dispatch address is changed to come here.
728 Set global variable ALL_CONTINUE to tell resume() that it should
729 start up all threads, and that a thread switch will not blow gdb's
730 mind. */
731
732static void
733convex_cont_command (proc_count_exp, from_tty)
734 char *proc_count_exp;
735 int from_tty;
736{
737 all_continue = 1;
738 cont_command (proc_count_exp, from_tty);
739}
740
741/* Here on 1CONT command. Resume only the current thread. */
742
743one_cont_command (proc_count_exp, from_tty)
744 char *proc_count_exp;
745 int from_tty;
746{
747 cont_command (proc_count_exp, from_tty);
748}
749
750/* Print the contents and lock bits of all communication registers,
751 or just register ARG if ARG is a communication register,
752 or the 3-word resource structure in memory at address ARG. */
753
754comm_registers_info (arg)
755 char *arg;
756{
757 int i, regnum;
758
759 if (arg)
760 {
e1a623e7 761 if (sscanf (arg, "$c%d", &regnum) == 1) {
dd3b648e 762 ;
e1a623e7 763 } else if (sscanf (arg, "$C%d", &regnum) == 1) {
dd3b648e 764 ;
e1a623e7 765 } else {
dd3b648e 766 regnum = parse_and_eval_address (arg);
e1a623e7
JG
767 if (regnum > 0)
768 regnum &= ~0x8000;
769 }
dd3b648e
RP
770
771 if (regnum >= 64)
772 error ("%s: invalid register name.", arg);
773
774 /* if we got a (user) address, examine the resource struct there */
775
776 if (regnum < 0)
777 {
778 static int buf[3];
779 read_memory (regnum, buf, sizeof buf);
780 printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2],
781 buf[0] & 0xff ? " locked" : "");
782 return;
783 }
784 }
785
786 ps.pi_buffer = (char *) &comm_registers;
787 ps.pi_nbytes = sizeof comm_registers;
788 ps.pi_offset = 0;
789 ps.pi_thread = inferior_thread;
790 ioctl (inferior_fd, PIXRDCREGS, &ps);
791
792 for (i = 0; i < 64; i++)
793 if (!arg || i == regnum)
794 printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
795 comm_registers.crreg.r4[i],
796 (iscrlbit (comm_registers.crctl.lbits.cc, i)
797 ? " locked" : ""));
798}
799
800/* Print the psw */
801
802static void
803psw_info (arg)
804 char *arg;
805{
806 struct pswbit
807 {
808 int bit;
809 int pos;
810 char *text;
811 };
812
813 static struct pswbit pswbit[] =
814 {
815 { 0x80000000, -1, "A carry" },
816 { 0x40000000, -1, "A integer overflow" },
817 { 0x20000000, -1, "A zero divide" },
818 { 0x10000000, -1, "Integer overflow enable" },
819 { 0x08000000, -1, "Trace" },
820 { 0x06000000, 25, "Frame length" },
821 { 0x01000000, -1, "Sequential" },
822 { 0x00800000, -1, "S carry" },
823 { 0x00400000, -1, "S integer overflow" },
824 { 0x00200000, -1, "S zero divide" },
825 { 0x00100000, -1, "Zero divide enable" },
826 { 0x00080000, -1, "Floating underflow" },
827 { 0x00040000, -1, "Floating overflow" },
828 { 0x00020000, -1, "Floating reserved operand" },
829 { 0x00010000, -1, "Floating zero divide" },
830 { 0x00008000, -1, "Floating error enable" },
831 { 0x00004000, -1, "Floating underflow enable" },
832 { 0x00002000, -1, "IEEE" },
833 { 0x00001000, -1, "Sequential stores" },
834 { 0x00000800, -1, "Intrinsic error" },
835 { 0x00000400, -1, "Intrinsic error enable" },
836 { 0x00000200, -1, "Trace thread creates" },
837 { 0x00000100, -1, "Thread init trap" },
838 { 0x000000e0, 5, "Reserved" },
839 { 0x0000001f, 0, "Intrinsic error code" },
840 {0, 0, 0},
841 };
842
843 long psw;
844 struct pswbit *p;
845
846 if (arg)
847 psw = parse_and_eval_address (arg);
848 else
849 psw = read_register (PS_REGNUM);
850
851 for (p = pswbit; p->bit; p++)
852 {
853 if (p->pos < 0)
854 printf_filtered ("%08x %s %s\n", p->bit,
855 (psw & p->bit) ? "yes" : "no ", p->text);
856 else
857 printf_filtered ("%08x %3d %s\n", p->bit,
858 (psw & p->bit) >> p->pos, p->text);
859 }
860}
18b46e7c
SS
861\f
862#include "symtab.h"
863
864/* reg (fmt_field, inst_field) --
865 the {first,second,third} operand of instruction as fmt_field = [ijk]
866 gets the value of the field from the [ijk] position of the instruction */
867
868#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
869
870/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
871
872#define lit(i) op[fmt->i]
873
874/* aj[j] -- name for A register j */
875
876#define aj ((char (*)[3])(op[A]))
877\f
878union inst {
879 struct {
880 unsigned : 7;
881 unsigned i : 3;
882 unsigned j : 3;
883 unsigned k : 3;
884 unsigned : 16;
885 unsigned : 32;
886 } f0;
887 struct {
888 unsigned : 8;
889 unsigned indir : 1;
890 unsigned len : 1;
891 unsigned j : 3;
892 unsigned k : 3;
893 unsigned : 16;
894 unsigned : 32;
895 } f1;
896 unsigned char byte[8];
897 unsigned short half[4];
898 char signed_byte[8];
899 short signed_half[4];
900};
901
902struct opform {
903 int mask; /* opcode mask */
904 int shift; /* opcode align */
905 struct formstr *formstr[3]; /* ST, E0, E1 */
906};
907
908struct formstr {
909 unsigned lop:8, rop:5; /* opcode */
910 unsigned fmt:5; /* inst format */
911 unsigned i:5, j:5, k:2; /* operand formats */
912};
913
914#include "opcode/convex.h"
915
916CONST unsigned char formdecode [] = {
917 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
918 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
919 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
920 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
921 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
922 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
923 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
924 4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,
925 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
926 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
927 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
928 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
929 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
930 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
931 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
932 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
933};
934
935CONST struct opform opdecode[] = {
936 0x7e00, 9, format0, e0_format0, e1_format0,
937 0x3f00, 8, format1, e0_format1, e1_format1,
938 0x1fc0, 6, format2, e0_format2, e1_format2,
939 0x0fc0, 6, format3, e0_format3, e1_format3,
940 0x0700, 8, format4, e0_format4, e1_format4,
941 0x03c0, 6, format5, e0_format5, e1_format5,
942 0x01f8, 3, format6, e0_format6, e1_format6,
943 0x00f8, 3, format7, e0_format7, e1_format7,
944 0x0000, 0, formatx, formatx, formatx,
945 0x0f80, 7, formatx, formatx, formatx,
946 0x0f80, 7, formatx, formatx, formatx,
947};
948\f
949/* Print the instruction at address MEMADDR in debugged memory,
950 on STREAM. Returns length of the instruction, in bytes. */
951
952int
953convex_print_insn (memaddr, stream)
954 CORE_ADDR memaddr;
955 FILE *stream;
956{
957 union inst inst;
958 struct formstr *fmt;
959 register int format, op1, pfx;
960 int l;
961
962 read_memory (memaddr, &inst, sizeof inst);
963
964 /* Remove and note prefix, if present */
965
966 pfx = inst.half[0];
967 if ((pfx & 0xfff0) == 0x7ef0)
968 {
969 pfx = ((pfx >> 3) & 1) + 1;
970 *(long long *) &inst = *(long long *) &inst.half[1];
971 }
972 else pfx = 0;
973
974 /* Split opcode into format.op1 and look up in appropriate table */
975
976 format = formdecode[inst.byte[0]];
977 op1 = (inst.half[0] & opdecode[format].mask) >> opdecode[format].shift;
978 if (format == 9)
979 {
980 if (pfx)
981 fmt = formatx;
982 else if (inst.f1.j == 0)
983 fmt = &format1a[op1];
984 else if (inst.f1.j == 1)
985 fmt = &format1b[op1];
986 else
987 fmt = formatx;
988 }
989 else
990 fmt = &opdecode[format].formstr[pfx][op1];
991
992 /* Print it */
993
994 if (fmt->fmt == xxx)
995 {
996 /* noninstruction */
997 fprintf (stream, "0x%04x", pfx ? pfx : inst.half[0]);
998 return 2;
999 }
1000
1001 if (pfx)
1002 pfx = 2;
1003
1004 fprintf (stream, "%s%s%s", lop[fmt->lop], rop[fmt->rop],
1005 &" "[strlen(lop[fmt->lop]) + strlen(rop[fmt->rop])]);
1006
1007 switch (fmt->fmt)
1008 {
1009 case rrr: /* three register */
1010 fprintf (stream, "%s,%s,%s", reg(i,i), reg(j,j), reg(k,k));
1011 return pfx + 2;
1012
1013 case rr: /* two register */
1014 fprintf (stream, "%s,%s", reg(i,j), reg(j,k));
1015 return pfx + 2;
1016
1017 case rxr: /* two register, reversed i and j fields */
1018 fprintf (stream, "%s,%s", reg(i,k), reg(j,j));
1019 return pfx + 2;
1020
1021 case r: /* one register */
1022 fprintf (stream, "%s", reg(i,k));
1023 return pfx + 2;
1024
1025 case nops: /* no operands */
1026 return pfx + 2;
1027
1028 case nr: /* short immediate, one register */
1029 fprintf (stream, "#%d,%s", inst.f0.j, reg(i,k));
1030 return pfx + 2;
1031
1032 case pcrel: /* pc relative */
1033 print_address (memaddr + 2 * inst.signed_byte[1], stream);
1034 return pfx + 2;
1035
1036 case lr: /* literal, one register */
1037 fprintf (stream, "%s,%s", lit(i), reg(j,k));
1038 return pfx + 2;
1039
1040 case rxl: /* one register, literal */
1041 fprintf (stream, "%s,%s", reg(i,k), lit(j));
1042 return pfx + 2;
1043
1044 case rlr: /* register, literal, register */
1045 fprintf (stream, "%s,%s,%s", reg(i,j), lit(j), reg(k,k));
1046 return pfx + 2;
1047
1048 case rrl: /* register, register, literal */
1049 fprintf (stream, "%s,%s,%s", reg(i,j), reg(j,k), lit(k));
1050 return pfx + 2;
1051
1052 case iml: /* immediate, literal */
1053 if (inst.f1.len)
1054 {
1055 fprintf (stream, "#%#x,%s",
1056 (inst.signed_half[1] << 16) + inst.half[2], lit(i));
1057 return pfx + 6;
1058 }
1059 else
1060 {
1061 fprintf (stream, "#%d,%s", inst.signed_half[1], lit(i));
1062 return pfx + 4;
1063 }
1064
1065 case imr: /* immediate, register */
1066 if (inst.f1.len)
1067 {
1068 fprintf (stream, "#%#x,%s",
1069 (inst.signed_half[1] << 16) + inst.half[2], reg(i,k));
1070 return pfx + 6;
1071 }
1072 else
1073 {
1074 fprintf (stream, "#%d,%s", inst.signed_half[1], reg(i,k));
1075 return pfx + 4;
1076 }
1077
1078 case a1r: /* memory, register */
1079 l = print_effa (inst, stream);
1080 fprintf (stream, ",%s", reg(i,k));
1081 return pfx + l;
1082
1083 case a1l: /* memory, literal */
1084 l = print_effa (inst, stream);
1085 fprintf (stream, ",%s", lit(i));
1086 return pfx + l;
1087
1088 case a2r: /* register, memory */
1089 fprintf (stream, "%s,", reg(i,k));
1090 return pfx + print_effa (inst, stream);
1091
1092 case a2l: /* literal, memory */
1093 fprintf (stream, "%s,", lit(i));
1094 return pfx + print_effa (inst, stream);
1095
1096 case a3: /* memory */
1097 return pfx + print_effa (inst, stream);
1098
1099 case a4: /* system call */
1100 l = 29; goto a4a5;
1101 case a5: /* trap */
1102 l = 27;
1103 a4a5:
1104 if (inst.f1.len)
1105 {
1106 unsigned int m = (inst.signed_half[1] << 16) + inst.half[2];
1107 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
1108 return pfx + 6;
1109 }
1110 else
1111 {
1112 unsigned int m = inst.signed_half[1];
1113 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
1114 return pfx + 4;
1115 }
1116 }
1117}
1118
1119
1120/* print effective address @nnn(aj), return instruction length */
1121
1122int print_effa (inst, stream)
1123 union inst inst;
1124 FILE *stream;
1125{
1126 int n, l;
1127
1128 if (inst.f1.len)
1129 {
1130 n = (inst.signed_half[1] << 16) + inst.half[2];
1131 l = 6;
1132 }
1133 else
1134 {
1135 n = inst.signed_half[1];
1136 l = 4;
1137 }
1138
1139 if (inst.f1.indir)
1140 printf ("@");
1141
1142 if (!inst.f1.j)
1143 {
1144 print_address (n, stream);
1145 return l;
1146 }
1147
1148 fprintf (stream, (n & 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",
1149 n, aj[inst.f1.j]);
1150
1151 return l;
1152}
1153
dd3b648e 1154\f
976bb0be 1155void
dd3b648e
RP
1156_initialize_convex_dep ()
1157{
1158 add_com ("alias", class_support, alias_command,
1159 "Add a new name for an existing command.");
1160
1161 add_cmd ("base", class_vars, set_base_command,
1162 "Change the integer output radix to 8, 10 or 16\n\
1163or use just `set base' with no args to return to the ad-hoc default,\n\
1164which is 16 for integers that look like addresses, 10 otherwise.",
1165 &setlist);
1166
1167 add_cmd ("pipeline", class_run, set_pipelining_command,
1168 "Enable or disable overlapped execution of instructions.\n\
1169With `set pipe off', exceptions are reported with\n\
1170$pc pointing at the instruction after the faulting one.\n\
1171The default is `set pipe on', which runs faster.",
1172 &setlist);
1173
1174 add_cmd ("parallel", class_run, set_parallel_command,
1175 "Enable or disable multi-threaded execution of parallel code.\n\
1176`set parallel off' means run the program on a single CPU.\n\
1177`set parallel fixed' means run the program with all CPUs assigned to it.\n\
1178`set parallel on' means run the program on any CPUs that are available.",
1179 &setlist);
1180
1181 add_com ("1cont", class_run, one_cont_command,
1182 "Continue the program, activating only the current thread.\n\
1183Args are the same as the `cont' command.");
1184
1185 add_com ("thread", class_run, set_thread_command,
1186 "Change the current thread, the one under scrutiny and control.\n\
1187With no arg, show the active threads, the current one marked with *.");
1188
1189 add_info ("threads", thread_info,
1190 "List status of active threads.");
1191
1192 add_info ("comm-registers", comm_registers_info,
1193 "List communication registers and their contents.\n\
1194A communication register name as argument means describe only that register.\n\
1195An address as argument means describe the resource structure at that address.\n\
1196`Locked' means that the register has been sent to but not yet received from.");
1197
1198 add_info ("psw", psw_info,
1199 "Display $ps, the processor status word, bit by bit.\n\
1200An argument means display that value's interpretation as a psw.");
1201
1202 add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
120332-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
120464-bit registers $S0-7 $V0-7 $C0-63\n\
1205\n\
1206info threads display info on stopped threads waiting to signal\n\
1207thread display list of active threads\n\
1208thread N select thread N (its registers, stack, memory, etc.)\n\
1209step, next, etc step selected thread only\n\
12101cont continue selected thread only\n\
1211cont continue all threads\n\
1212info comm-registers display contents of comm register(s) or a resource struct\n\
1213info psw display processor status word $ps\n\
1214set base N change integer radix used by `print' without a format\n\
1215set pipeline off exceptions are precise, $pc points after the faulting insn\n\
1216set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
1217set parallel off program runs on a single CPU\n\
1218set parallel fixed all CPUs are assigned to the program\n\
1219set parallel on normal mode, parallel execution on random available CPUs\n\
1220",
1221 &cmdlist);
1222
1223}