* utils.c (query): Change syntax of query annotations to be
[deliverable/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
JG
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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>
40#include <sys/stat.h>
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
133/* Read data from SOFF exec or core file.
134 Return 0 on success, EIO if address out of bounds. */
135
136int
137xfer_core_file (memaddr, myaddr, len)
138 CORE_ADDR memaddr;
139 char *myaddr;
140 int len;
141{
142 register int i;
143 register int n;
144 register int val;
145 int xferchan;
146 char **xferfile;
147 int fileptr;
148 int returnval = 0;
149
150 while (len > 0)
151 {
152 xferfile = 0;
153 xferchan = 0;
154
155 /* Determine which file the next bunch of addresses reside in,
156 and where in the file. Set the file's read/write pointer
157 to point at the proper place for the desired address
158 and set xferfile and xferchan for the correct file.
159 If desired address is nonexistent, leave them zero.
160 i is set to the number of bytes that can be handled
161 along with the next address. */
162
163 i = len;
164
165 for (n = 0; n < n_core; n++)
166 {
167 if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end
168 && (core_map[n].thread == -1
169 || core_map[n].thread == inferior_thread))
170 {
171 i = min (len, core_map[n].mem_end - memaddr);
172 fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;
173 if (core_map[n].file_addr)
174 {
175 xferfile = &corefile;
176 xferchan = corechan;
177 }
178 break;
179 }
180 else if (core_map[n].mem_addr >= memaddr
181 && core_map[n].mem_addr < memaddr + i)
182 i = core_map[n].mem_addr - memaddr;
183 }
184
185 if (!xferfile)
186 for (n = 0; n < n_exec; n++)
187 {
188 if (memaddr >= exec_map[n].mem_addr
189 && memaddr < exec_map[n].mem_end)
190 {
191 i = min (len, exec_map[n].mem_end - memaddr);
192 fileptr = exec_map[n].file_addr + memaddr
193 - exec_map[n].mem_addr;
194 if (exec_map[n].file_addr)
195 {
196 xferfile = &execfile;
197 xferchan = execchan;
198 }
199 break;
200 }
201 else if (exec_map[n].mem_addr >= memaddr
202 && exec_map[n].mem_addr < memaddr + i)
203 i = exec_map[n].mem_addr - memaddr;
204 }
205
206 /* Now we know which file to use.
207 Set up its pointer and transfer the data. */
208 if (xferfile)
209 {
210 if (*xferfile == 0)
211 if (xferfile == &execfile)
212 error ("No program file to examine.");
213 else
214 error ("No core dump file or running program to examine.");
215 val = lseek (xferchan, fileptr, 0);
216 if (val < 0)
217 perror_with_name (*xferfile);
218 val = myread (xferchan, myaddr, i);
219 if (val < 0)
220 perror_with_name (*xferfile);
221 }
222 /* If this address is for nonexistent memory,
223 read zeros if reading, or do nothing if writing. */
224 else
225 {
4ed97c9a 226 memset (myaddr, '\0', i);
dd3b648e
RP
227 returnval = EIO;
228 }
229
230 memaddr += i;
231 myaddr += i;
232 len -= i;
233 }
234 return returnval;
235}
236
237
238/* Here from info files command to print an address map. */
239
240print_maps ()
241{
242 struct pmap ptrs[200];
243 int n;
244
245 /* ID strings for core and executable file sections */
246
247 static char *idstr[] =
248 {
249 "0", "text", "data", "tdata", "bss", "tbss",
250 "common", "ttext", "ctx", "tctx", "10", "11", "12",
251 };
252
253 for (n = 0; n < n_core; n++)
254 {
255 core_map[n].which = 0;
256 ptrs[n] = core_map[n];
257 }
258 for (n = 0; n < n_exec; n++)
259 {
260 exec_map[n].which = 1;
261 ptrs[n_core+n] = exec_map[n];
262 }
263
264 qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);
265
266 for (n = 0; n < n_core + n_exec; n++)
267 {
268 struct pmap *p = &ptrs[n];
269 if (n > 0)
270 {
271 if (p->mem_addr < ptrs[n-1].mem_end)
272 p->mem_addr = ptrs[n-1].mem_end;
273 if (p->mem_addr >= p->mem_end)
274 continue;
275 }
276 printf_filtered ("%08x .. %08x %-6s %s\n",
277 p->mem_addr, p->mem_end, idstr[p->type],
278 p->which ? execfile : corefile);
279 }
280}
281
282/* Compare routine to put file sections in order.
283 Sort into increasing order on address, and put core file sections
284 before exec file sections if both files contain the same addresses. */
285
286static ptr_cmp (a, b)
287 struct pmap *a, *b;
288{
289 if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;
290 return a->which - b->which;
291}
292\f
293/* Trapped internal variables are used to handle special registers.
294 A trapped i.v. calls a hook here every time it is dereferenced,
295 to provide a new value for the variable, and it calls a hook here
296 when a new value is assigned, to do something with the value.
297
298 The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
299 The communication registers are $cN, $CN (N in 0..63).
300 They not handled as regular registers because it's expensive to
301 read them, and their size varies, and they have too many names. */
302
303
304/* Return 1 if NAME is a trapped internal variable, else 0. */
305
306int
307is_trapped_internalvar (name)
308 char *name;
309{
310 if ((name[0] == 'c' || name[0] == 'C')
311 && name[1] >= '0' && name[1] <= '9'
312 && (name[2] == '\0'
313 || (name[2] >= '0' && name[2] <= '9'
314 && name[3] == '\0' && name[1] != '0'))
315 && atoi (&name[1]) < 64) return 1;
316
317 if ((name[0] == 'v' || name[0] == 'V')
318 && (((name[1] & -8) == '0' && name[2] == '\0')
2e4964ad
FF
319 || STREQ (name, "vl")
320 || STREQ (name, "vs")
321 || STREQ (name, "vm")))
dd3b648e
RP
322 return 1;
323 else return 0;
324}
325
326/* Return the value of trapped internal variable VAR */
327
328value
329value_of_trapped_internalvar (var)
330 struct internalvar *var;
331{
332 char *name = var->name;
333 value val;
334 struct type *type;
a8a69e63 335 struct type *range_type;
dd3b648e
RP
336 long len = *read_vector_register (VL_REGNUM);
337 if (len <= 0 || len > 128) len = 128;
338
2e4964ad 339 if (STREQ (name, "vl"))
dd3b648e 340 {
06b6c733 341 val = value_from_longest (builtin_type_int,
dd3b648e
RP
342 (LONGEST) *read_vector_register_1 (VL_REGNUM));
343 }
2e4964ad 344 else if (STREQ (name, "vs"))
dd3b648e 345 {
06b6c733 346 val = value_from_longest (builtin_type_int,
dd3b648e
RP
347 (LONGEST) *read_vector_register_1 (VS_REGNUM));
348 }
2e4964ad 349 else if (STREQ (name, "vm"))
dd3b648e
RP
350 {
351 long vm[4];
352 long i, *p;
ade40d31 353 memcpy (vm, read_vector_register_1 (VM_REGNUM), sizeof vm);
a8a69e63
FF
354 range_type =
355 create_range_type ((struct type *) NULL, builtin_type_int, 0, len - 1);
356 type =
357 create_array_type ((struct type *) NULL, builtin_type_int, range_type);
dd3b648e
RP
358 val = allocate_value (type);
359 p = (long *) VALUE_CONTENTS (val);
360 for (i = 0; i < len; i++)
361 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
362 }
363 else if (name[0] == 'V')
364 {
a8a69e63
FF
365 range_type =
366 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
367 type =
368 create_array_type ((struct type *) NULL, builtin_type_long_long,
369 range_type);
dd3b648e 370 val = allocate_value (type);
ade40d31
RP
371 memcpy (VALUE_CONTENTS (val),
372 read_vector_register_1 (name[1] - '0'),
373 TYPE_LENGTH (type));
dd3b648e
RP
374 }
375 else if (name[0] == 'v')
376 {
377 long *p1, *p2;
a8a69e63
FF
378 range_type =
379 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
380 type =
381 create_array_type ((struct type *) NULL, builtin_type_long,
382 range_type);
dd3b648e
RP
383 val = allocate_value (type);
384 p1 = read_vector_register_1 (name[1] - '0');
385 p2 = (long *) VALUE_CONTENTS (val);
386 while (--len >= 0) {p1++; *p2++ = *p1++;}
387 }
388
389 else if (name[0] == 'c')
06b6c733 390 val = value_from_longest (builtin_type_int,
dd3b648e
RP
391 read_comm_register (atoi (&name[1])));
392 else if (name[0] == 'C')
06b6c733 393 val = value_from_longest (builtin_type_long_long,
dd3b648e
RP
394 read_comm_register (atoi (&name[1])));
395
396 VALUE_LVAL (val) = lval_internalvar;
397 VALUE_INTERNALVAR (val) = var;
398 return val;
399}
400
dd3b648e
RP
401/* Handle a new value assigned to a trapped internal variable */
402
403void
404set_trapped_internalvar (var, val, bitpos, bitsize, offset)
405 struct internalvar *var;
406 value val;
407 int bitpos, bitsize, offset;
408{
409 char *name = var->name;
410 long long newval = value_as_long (val);
411
2e4964ad 412 if (STREQ (name, "vl"))
dd3b648e 413 write_vector_register (VL_REGNUM, 0, newval);
2e4964ad 414 else if (STREQ (name, "vs"))
dd3b648e
RP
415 write_vector_register (VS_REGNUM, 0, newval);
416 else if (name[0] == 'c' || name[0] == 'C')
417 write_comm_register (atoi (&name[1]), newval);
2e4964ad 418 else if (STREQ (name, "vm"))
dd3b648e
RP
419 error ("can't assign to $vm");
420 else
421 {
422 offset /= bitsize / 8;
423 write_vector_register (name[1] - '0', offset, newval);
424 }
425}
426
427/* Print an integer value when no format was specified. gdb normally
428 prints these values in decimal, but the the leading 0x80000000 of
429 pointers produces intolerable 10-digit negative numbers.
430 If it looks like an address, print it in hex instead. */
431
432decout (stream, type, val)
433 FILE *stream;
434 struct type *type;
435 LONGEST val;
436{
437 long lv = val;
438
439 switch (output_radix)
440 {
441 case 0:
442 if ((lv == val || (unsigned) lv == val)
443 && ((lv & 0xf0000000) == 0x80000000
444 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
445 {
446 fprintf_filtered (stream, "%#x", lv);
447 return;
448 }
449
450 case 10:
451 fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
452 return;
453
454 case 8:
455 if (TYPE_LENGTH (type) <= sizeof lv)
456 fprintf_filtered (stream, "%#o", lv);
457 else
458 fprintf_filtered (stream, "%#llo", val);
459 return;
460
461 case 16:
462 if (TYPE_LENGTH (type) <= sizeof lv)
463 fprintf_filtered (stream, "%#x", lv);
464 else
465 fprintf_filtered (stream, "%#llx", val);
466 return;
467 }
468}
469
470/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
471 This command is mostly obsolete now that the print command allows
472 formats to apply to aggregates, but is still handy occasionally. */
473
474static void
475set_base_command (arg)
476 char *arg;
477{
478 int new_radix;
479
480 if (!arg)
481 output_radix = 0;
482 else
483 {
484 new_radix = atoi (arg);
485 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
486 error ("base must be 8, 10 or 16, or null");
487 else output_radix = new_radix;
488 }
489}
490
491/* Turn pipelining on or off in the inferior. */
492
493static void
494set_pipelining_command (arg)
495 char *arg;
496{
497 if (!arg)
498 {
499 sequential = !sequential;
500 printf_filtered ("%s\n", sequential ? "off" : "on");
501 }
2e4964ad 502 else if (STREQ (arg, "on"))
dd3b648e 503 sequential = 0;
2e4964ad 504 else if (STREQ (arg, "off"))
dd3b648e
RP
505 sequential = 1;
506 else error ("valid args are `on', to allow instructions to overlap, or\n\
507`off', to prevent it and thereby pinpoint exceptions.");
508}
509
510/* Enable, disable, or force parallel execution in the inferior. */
511
512static void
513set_parallel_command (arg)
514 char *arg;
515{
516 struct rlimit rl;
517 int prevparallel = parallel;
518
519 if (!strncmp (arg, "fixed", strlen (arg)))
520 parallel = 2;
2e4964ad 521 else if (STREQ (arg, "on"))
dd3b648e 522 parallel = 1;
2e4964ad 523 else if (STREQ (arg, "off"))
dd3b648e
RP
524 parallel = 0;
525 else error ("valid args are `on', to allow multiple threads, or\n\
526`fixed', to force multiple threads, or\n\
527`off', to run with one thread only.");
528
529 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
530 printf_filtered ("will take effect at next run.\n");
531
532 getrlimit (RLIMIT_CONCUR, &rl);
533 rl.rlim_cur = parallel ? rl.rlim_max : 1;
534 setrlimit (RLIMIT_CONCUR, &rl);
535
536 if (inferior_pid)
537 set_fixed_scheduling (inferior_pid, parallel == 2);
538}
539
540/* Add a new name for an existing command. */
541
542static void
543alias_command (arg)
544 char *arg;
545{
546 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
547 char *newname = arg;
548 struct cmd_list_element *new, *old;
549
550 if (!arg)
551 error_no_arg ("newname oldname");
552
553 new = lookup_cmd (&arg, cmdlist, "", -1);
554 if (new && !strncmp (newname, new->name, strlen (new->name)))
555 {
556 newname = new->name;
557 if (!(*arg == '-'
558 || (*arg >= 'a' && *arg <= 'z')
559 || (*arg >= 'A' && *arg <= 'Z')
560 || (*arg >= '0' && *arg <= '9')))
561 error (aliaserr);
562 }
563 else
564 {
565 arg = newname;
566 while (*arg == '-'
567 || (*arg >= 'a' && *arg <= 'z')
568 || (*arg >= 'A' && *arg <= 'Z')
569 || (*arg >= '0' && *arg <= '9'))
570 arg++;
571 if (*arg != ' ' && *arg != '\t')
572 error (aliaserr);
573 *arg = '\0';
574 arg++;
575 }
576
577 old = lookup_cmd (&arg, cmdlist, "", 0);
578
579 if (*arg != '\0')
580 error (aliaserr);
581
582 if (new && !strncmp (newname, new->name, strlen (new->name)))
583 {
584 char *tem;
585 if (new->class == (int) class_user || new->class == (int) class_alias)
586 tem = "Redefine command \"%s\"? ";
587 else
588 tem = "Really redefine built-in command \"%s\"? ";
589 if (!query (tem, new->name))
590 error ("Command \"%s\" not redefined.", new->name);
591 }
592
593 add_com (newname, class_alias, old->function, old->doc);
594}
595
596
597
598/* Print the current thread number, and any threads with signals in the
599 queue. */
600
601thread_info ()
602{
603 struct threadpid *p;
604
605 if (have_inferior_p ())
606 {
607 ps.pi_buffer = (char *) &comm_registers;
608 ps.pi_nbytes = sizeof comm_registers;
609 ps.pi_offset = 0;
610 ps.pi_thread = inferior_thread;
611 ioctl (inferior_fd, PIXRDCREGS, &ps);
612 }
613
67ac9759
JK
614 /* FIXME: stop_signal is from target.h but stop_sigcode is a
615 convex-specific thing. */
dd3b648e
RP
616 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
617 inferior_thread, stop_signal, stop_sigcode,
618 subsig_name (stop_signal, stop_sigcode));
619
620 for (p = signal_stack; p->pid; p--)
621 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
622 p->thread, p->signo, p->subsig,
623 subsig_name (p->signo, p->subsig));
624
625 if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
626 printf_filtered ("New thread start pc %#x\n",
627 (long) (comm_registers.crreg.pcpsw >> 32));
628}
629
630/* Return string describing a signal.subcode number */
631
632static char *
633subsig_name (signo, subcode)
634 int signo, subcode;
635{
636 static char *subsig4[] = {
637 "error exit", "privileged instruction", "unknown",
638 "unknown", "undefined opcode",
639 0};
640 static char *subsig5[] = {0,
641 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
642 "join trap", "idle trap", "last thread", "wfork trap",
643 "process breakpoint", "trap instruction",
644 0};
645 static char *subsig8[] = {0,
646 "int overflow", "int divide check", "float overflow",
647 "float divide check", "float underflow", "reserved operand",
648 "sqrt error", "exp error", "ln error", "sin error", "cos error",
649 0};
650 static char *subsig10[] = {0,
651 "invalid inward ring address", "invalid outward ring call",
652 "invalid inward ring return", "invalid syscall gate",
653 "invalid rtn frame length", "invalid comm reg address",
654 "invalid trap gate",
655 0};
656 static char *subsig11[] = {0,
657 "read access denied", "write access denied", "execute access denied",
658 "segment descriptor fault", "page table fault", "data reference fault",
659 "i/o access denied", "levt pte invalid",
660 0};
661
662 static char **subsig_list[] =
663 {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
664
665 int i;
4ace50a5 666 char *p;
dd3b648e 667
4ace50a5
FF
668 if ((p = strsignal (signo)) == NULL)
669 p = "unknown";
dd3b648e
RP
670 if (signo >= (sizeof subsig_list / sizeof *subsig_list)
671 || !subsig_list[signo])
672 return p;
673 for (i = 1; subsig_list[signo][i]; i++)
674 if (i == subcode)
675 return subsig_list[signo][subcode];
676 return p;
677}
678
679
680/* Print a compact display of thread status, essentially x/i $pc
681 for all active threads. */
682
683static void
684threadstat ()
685{
686 int t;
687
688 for (t = 0; t < n_threads; t++)
689 if (thread_state[t] == PI_TALIVE)
690 {
691 printf_filtered ("%d%c %08x%c %d.%d ", t,
692 (t == inferior_thread ? '*' : ' '), thread_pc[t],
693 (thread_is_in_kernel[t] ? '#' : ' '),
694 thread_signal[t], thread_sigcode[t]);
695 print_insn (thread_pc[t], stdout);
696 printf_filtered ("\n");
697 }
698}
699
700/* Change the current thread to ARG. */
701
702set_thread_command (arg)
703 char *arg;
704{
705 int thread;
706
707 if (!arg)
708 {
709 threadstat ();
710 return;
711 }
712
713 thread = parse_and_eval_address (arg);
714
715 if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
716 error ("no such thread.");
717
718 select_thread (thread);
719
720 stop_pc = read_pc ();
721 flush_cached_frames ();
722 set_current_frame (create_new_frame (read_register (FP_REGNUM),
723 read_pc ()));
724 select_frame (get_current_frame (), 0);
cadbb07a 725 print_stack_frame (selected_frame, selected_frame_level, -1);
dd3b648e
RP
726}
727
728/* Here on CONT command; gdb's dispatch address is changed to come here.
729 Set global variable ALL_CONTINUE to tell resume() that it should
730 start up all threads, and that a thread switch will not blow gdb's
731 mind. */
732
733static void
734convex_cont_command (proc_count_exp, from_tty)
735 char *proc_count_exp;
736 int from_tty;
737{
738 all_continue = 1;
739 cont_command (proc_count_exp, from_tty);
740}
741
742/* Here on 1CONT command. Resume only the current thread. */
743
744one_cont_command (proc_count_exp, from_tty)
745 char *proc_count_exp;
746 int from_tty;
747{
748 cont_command (proc_count_exp, from_tty);
749}
750
751/* Print the contents and lock bits of all communication registers,
752 or just register ARG if ARG is a communication register,
753 or the 3-word resource structure in memory at address ARG. */
754
755comm_registers_info (arg)
756 char *arg;
757{
758 int i, regnum;
759
760 if (arg)
761 {
e1a623e7 762 if (sscanf (arg, "$c%d", &regnum) == 1) {
dd3b648e 763 ;
e1a623e7 764 } else if (sscanf (arg, "$C%d", &regnum) == 1) {
dd3b648e 765 ;
e1a623e7 766 } else {
dd3b648e 767 regnum = parse_and_eval_address (arg);
e1a623e7
JG
768 if (regnum > 0)
769 regnum &= ~0x8000;
770 }
dd3b648e
RP
771
772 if (regnum >= 64)
773 error ("%s: invalid register name.", arg);
774
775 /* if we got a (user) address, examine the resource struct there */
776
777 if (regnum < 0)
778 {
779 static int buf[3];
780 read_memory (regnum, buf, sizeof buf);
781 printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2],
782 buf[0] & 0xff ? " locked" : "");
783 return;
784 }
785 }
786
787 ps.pi_buffer = (char *) &comm_registers;
788 ps.pi_nbytes = sizeof comm_registers;
789 ps.pi_offset = 0;
790 ps.pi_thread = inferior_thread;
791 ioctl (inferior_fd, PIXRDCREGS, &ps);
792
793 for (i = 0; i < 64; i++)
794 if (!arg || i == regnum)
795 printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
796 comm_registers.crreg.r4[i],
797 (iscrlbit (comm_registers.crctl.lbits.cc, i)
798 ? " locked" : ""));
799}
800
801/* Print the psw */
802
803static void
804psw_info (arg)
805 char *arg;
806{
807 struct pswbit
808 {
809 int bit;
810 int pos;
811 char *text;
812 };
813
814 static struct pswbit pswbit[] =
815 {
816 { 0x80000000, -1, "A carry" },
817 { 0x40000000, -1, "A integer overflow" },
818 { 0x20000000, -1, "A zero divide" },
819 { 0x10000000, -1, "Integer overflow enable" },
820 { 0x08000000, -1, "Trace" },
821 { 0x06000000, 25, "Frame length" },
822 { 0x01000000, -1, "Sequential" },
823 { 0x00800000, -1, "S carry" },
824 { 0x00400000, -1, "S integer overflow" },
825 { 0x00200000, -1, "S zero divide" },
826 { 0x00100000, -1, "Zero divide enable" },
827 { 0x00080000, -1, "Floating underflow" },
828 { 0x00040000, -1, "Floating overflow" },
829 { 0x00020000, -1, "Floating reserved operand" },
830 { 0x00010000, -1, "Floating zero divide" },
831 { 0x00008000, -1, "Floating error enable" },
832 { 0x00004000, -1, "Floating underflow enable" },
833 { 0x00002000, -1, "IEEE" },
834 { 0x00001000, -1, "Sequential stores" },
835 { 0x00000800, -1, "Intrinsic error" },
836 { 0x00000400, -1, "Intrinsic error enable" },
837 { 0x00000200, -1, "Trace thread creates" },
838 { 0x00000100, -1, "Thread init trap" },
839 { 0x000000e0, 5, "Reserved" },
840 { 0x0000001f, 0, "Intrinsic error code" },
841 {0, 0, 0},
842 };
843
844 long psw;
845 struct pswbit *p;
846
847 if (arg)
848 psw = parse_and_eval_address (arg);
849 else
850 psw = read_register (PS_REGNUM);
851
852 for (p = pswbit; p->bit; p++)
853 {
854 if (p->pos < 0)
855 printf_filtered ("%08x %s %s\n", p->bit,
856 (psw & p->bit) ? "yes" : "no ", p->text);
857 else
858 printf_filtered ("%08x %3d %s\n", p->bit,
859 (psw & p->bit) >> p->pos, p->text);
860 }
861}
862\f
976bb0be 863void
dd3b648e
RP
864_initialize_convex_dep ()
865{
866 add_com ("alias", class_support, alias_command,
867 "Add a new name for an existing command.");
868
869 add_cmd ("base", class_vars, set_base_command,
870 "Change the integer output radix to 8, 10 or 16\n\
871or use just `set base' with no args to return to the ad-hoc default,\n\
872which is 16 for integers that look like addresses, 10 otherwise.",
873 &setlist);
874
875 add_cmd ("pipeline", class_run, set_pipelining_command,
876 "Enable or disable overlapped execution of instructions.\n\
877With `set pipe off', exceptions are reported with\n\
878$pc pointing at the instruction after the faulting one.\n\
879The default is `set pipe on', which runs faster.",
880 &setlist);
881
882 add_cmd ("parallel", class_run, set_parallel_command,
883 "Enable or disable multi-threaded execution of parallel code.\n\
884`set parallel off' means run the program on a single CPU.\n\
885`set parallel fixed' means run the program with all CPUs assigned to it.\n\
886`set parallel on' means run the program on any CPUs that are available.",
887 &setlist);
888
889 add_com ("1cont", class_run, one_cont_command,
890 "Continue the program, activating only the current thread.\n\
891Args are the same as the `cont' command.");
892
893 add_com ("thread", class_run, set_thread_command,
894 "Change the current thread, the one under scrutiny and control.\n\
895With no arg, show the active threads, the current one marked with *.");
896
897 add_info ("threads", thread_info,
898 "List status of active threads.");
899
900 add_info ("comm-registers", comm_registers_info,
901 "List communication registers and their contents.\n\
902A communication register name as argument means describe only that register.\n\
903An address as argument means describe the resource structure at that address.\n\
904`Locked' means that the register has been sent to but not yet received from.");
905
906 add_info ("psw", psw_info,
907 "Display $ps, the processor status word, bit by bit.\n\
908An argument means display that value's interpretation as a psw.");
909
910 add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
91132-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
91264-bit registers $S0-7 $V0-7 $C0-63\n\
913\n\
914info threads display info on stopped threads waiting to signal\n\
915thread display list of active threads\n\
916thread N select thread N (its registers, stack, memory, etc.)\n\
917step, next, etc step selected thread only\n\
9181cont continue selected thread only\n\
919cont continue all threads\n\
920info comm-registers display contents of comm register(s) or a resource struct\n\
921info psw display processor status word $ps\n\
922set base N change integer radix used by `print' without a format\n\
923set pipeline off exceptions are precise, $pc points after the faulting insn\n\
924set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
925set parallel off program runs on a single CPU\n\
926set parallel fixed all CPUs are assigned to the program\n\
927set parallel on normal mode, parallel execution on random available CPUs\n\
928",
929 &cmdlist);
930
931}
This page took 0.175888 seconds and 4 git commands to generate.