* inftarg.c (child_create_inferior, child_attach,
[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 {
226 bzero (myaddr, i);
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')
319 || !strcmp (name, "vl")
320 || !strcmp (name, "vs")
321 || !strcmp (name, "vm")))
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;
335 long len = *read_vector_register (VL_REGNUM);
336 if (len <= 0 || len > 128) len = 128;
337
338 if (!strcmp (name, "vl"))
339 {
06b6c733 340 val = value_from_longest (builtin_type_int,
dd3b648e
RP
341 (LONGEST) *read_vector_register_1 (VL_REGNUM));
342 }
343 else if (!strcmp (name, "vs"))
344 {
06b6c733 345 val = value_from_longest (builtin_type_int,
dd3b648e
RP
346 (LONGEST) *read_vector_register_1 (VS_REGNUM));
347 }
348 else if (!strcmp (name, "vm"))
349 {
350 long vm[4];
351 long i, *p;
352 bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);
353 type = vector_type (builtin_type_int, len);
354 val = allocate_value (type);
355 p = (long *) VALUE_CONTENTS (val);
356 for (i = 0; i < len; i++)
357 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
358 }
359 else if (name[0] == 'V')
360 {
361 type = vector_type (builtin_type_long_long, len);
362 val = allocate_value (type);
363 bcopy (read_vector_register_1 (name[1] - '0'),
364 VALUE_CONTENTS (val), TYPE_LENGTH (type));
365 }
366 else if (name[0] == 'v')
367 {
368 long *p1, *p2;
369 type = vector_type (builtin_type_long, len);
370 val = allocate_value (type);
371 p1 = read_vector_register_1 (name[1] - '0');
372 p2 = (long *) VALUE_CONTENTS (val);
373 while (--len >= 0) {p1++; *p2++ = *p1++;}
374 }
375
376 else if (name[0] == 'c')
06b6c733 377 val = value_from_longest (builtin_type_int,
dd3b648e
RP
378 read_comm_register (atoi (&name[1])));
379 else if (name[0] == 'C')
06b6c733 380 val = value_from_longest (builtin_type_long_long,
dd3b648e
RP
381 read_comm_register (atoi (&name[1])));
382
383 VALUE_LVAL (val) = lval_internalvar;
384 VALUE_INTERNALVAR (val) = var;
385 return val;
386}
387
388/* Construct the type for a vector register's value --
389 array[LENGTH] of ELEMENT_TYPE. */
390
391static struct type *
392vector_type (element_type, length)
393 struct type *element_type;
394 long length;
395{
396 struct type *type = (struct type *) xmalloc (sizeof (struct type));
397 bzero (type, sizeof type);
398 TYPE_CODE (type) = TYPE_CODE_ARRAY;
399 TYPE_TARGET_TYPE (type) = element_type;
400 TYPE_LENGTH (type) = length * TYPE_LENGTH (TYPE_TARGET_TYPE (type));
401 return type;
402}
403
404/* Handle a new value assigned to a trapped internal variable */
405
406void
407set_trapped_internalvar (var, val, bitpos, bitsize, offset)
408 struct internalvar *var;
409 value val;
410 int bitpos, bitsize, offset;
411{
412 char *name = var->name;
413 long long newval = value_as_long (val);
414
415 if (!strcmp (name, "vl"))
416 write_vector_register (VL_REGNUM, 0, newval);
417 else if (!strcmp (name, "vs"))
418 write_vector_register (VS_REGNUM, 0, newval);
419 else if (name[0] == 'c' || name[0] == 'C')
420 write_comm_register (atoi (&name[1]), newval);
421 else if (!strcmp (name, "vm"))
422 error ("can't assign to $vm");
423 else
424 {
425 offset /= bitsize / 8;
426 write_vector_register (name[1] - '0', offset, newval);
427 }
428}
429
430/* Print an integer value when no format was specified. gdb normally
431 prints these values in decimal, but the the leading 0x80000000 of
432 pointers produces intolerable 10-digit negative numbers.
433 If it looks like an address, print it in hex instead. */
434
435decout (stream, type, val)
436 FILE *stream;
437 struct type *type;
438 LONGEST val;
439{
440 long lv = val;
441
442 switch (output_radix)
443 {
444 case 0:
445 if ((lv == val || (unsigned) lv == val)
446 && ((lv & 0xf0000000) == 0x80000000
447 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
448 {
449 fprintf_filtered (stream, "%#x", lv);
450 return;
451 }
452
453 case 10:
454 fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
455 return;
456
457 case 8:
458 if (TYPE_LENGTH (type) <= sizeof lv)
459 fprintf_filtered (stream, "%#o", lv);
460 else
461 fprintf_filtered (stream, "%#llo", val);
462 return;
463
464 case 16:
465 if (TYPE_LENGTH (type) <= sizeof lv)
466 fprintf_filtered (stream, "%#x", lv);
467 else
468 fprintf_filtered (stream, "%#llx", val);
469 return;
470 }
471}
472
473/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
474 This command is mostly obsolete now that the print command allows
475 formats to apply to aggregates, but is still handy occasionally. */
476
477static void
478set_base_command (arg)
479 char *arg;
480{
481 int new_radix;
482
483 if (!arg)
484 output_radix = 0;
485 else
486 {
487 new_radix = atoi (arg);
488 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
489 error ("base must be 8, 10 or 16, or null");
490 else output_radix = new_radix;
491 }
492}
493
494/* Turn pipelining on or off in the inferior. */
495
496static void
497set_pipelining_command (arg)
498 char *arg;
499{
500 if (!arg)
501 {
502 sequential = !sequential;
503 printf_filtered ("%s\n", sequential ? "off" : "on");
504 }
505 else if (!strcmp (arg, "on"))
506 sequential = 0;
507 else if (!strcmp (arg, "off"))
508 sequential = 1;
509 else error ("valid args are `on', to allow instructions to overlap, or\n\
510`off', to prevent it and thereby pinpoint exceptions.");
511}
512
513/* Enable, disable, or force parallel execution in the inferior. */
514
515static void
516set_parallel_command (arg)
517 char *arg;
518{
519 struct rlimit rl;
520 int prevparallel = parallel;
521
522 if (!strncmp (arg, "fixed", strlen (arg)))
523 parallel = 2;
524 else if (!strcmp (arg, "on"))
525 parallel = 1;
526 else if (!strcmp (arg, "off"))
527 parallel = 0;
528 else error ("valid args are `on', to allow multiple threads, or\n\
529`fixed', to force multiple threads, or\n\
530`off', to run with one thread only.");
531
532 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
533 printf_filtered ("will take effect at next run.\n");
534
535 getrlimit (RLIMIT_CONCUR, &rl);
536 rl.rlim_cur = parallel ? rl.rlim_max : 1;
537 setrlimit (RLIMIT_CONCUR, &rl);
538
539 if (inferior_pid)
540 set_fixed_scheduling (inferior_pid, parallel == 2);
541}
542
543/* Add a new name for an existing command. */
544
545static void
546alias_command (arg)
547 char *arg;
548{
549 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
550 char *newname = arg;
551 struct cmd_list_element *new, *old;
552
553 if (!arg)
554 error_no_arg ("newname oldname");
555
556 new = lookup_cmd (&arg, cmdlist, "", -1);
557 if (new && !strncmp (newname, new->name, strlen (new->name)))
558 {
559 newname = new->name;
560 if (!(*arg == '-'
561 || (*arg >= 'a' && *arg <= 'z')
562 || (*arg >= 'A' && *arg <= 'Z')
563 || (*arg >= '0' && *arg <= '9')))
564 error (aliaserr);
565 }
566 else
567 {
568 arg = newname;
569 while (*arg == '-'
570 || (*arg >= 'a' && *arg <= 'z')
571 || (*arg >= 'A' && *arg <= 'Z')
572 || (*arg >= '0' && *arg <= '9'))
573 arg++;
574 if (*arg != ' ' && *arg != '\t')
575 error (aliaserr);
576 *arg = '\0';
577 arg++;
578 }
579
580 old = lookup_cmd (&arg, cmdlist, "", 0);
581
582 if (*arg != '\0')
583 error (aliaserr);
584
585 if (new && !strncmp (newname, new->name, strlen (new->name)))
586 {
587 char *tem;
588 if (new->class == (int) class_user || new->class == (int) class_alias)
589 tem = "Redefine command \"%s\"? ";
590 else
591 tem = "Really redefine built-in command \"%s\"? ";
592 if (!query (tem, new->name))
593 error ("Command \"%s\" not redefined.", new->name);
594 }
595
596 add_com (newname, class_alias, old->function, old->doc);
597}
598
599
600
601/* Print the current thread number, and any threads with signals in the
602 queue. */
603
604thread_info ()
605{
606 struct threadpid *p;
607
608 if (have_inferior_p ())
609 {
610 ps.pi_buffer = (char *) &comm_registers;
611 ps.pi_nbytes = sizeof comm_registers;
612 ps.pi_offset = 0;
613 ps.pi_thread = inferior_thread;
614 ioctl (inferior_fd, PIXRDCREGS, &ps);
615 }
616
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 ();
723 set_current_frame (create_new_frame (read_register (FP_REGNUM),
724 read_pc ()));
725 select_frame (get_current_frame (), 0);
cadbb07a 726 print_stack_frame (selected_frame, selected_frame_level, -1);
dd3b648e
RP
727}
728
729/* Here on CONT command; gdb's dispatch address is changed to come here.
730 Set global variable ALL_CONTINUE to tell resume() that it should
731 start up all threads, and that a thread switch will not blow gdb's
732 mind. */
733
734static void
735convex_cont_command (proc_count_exp, from_tty)
736 char *proc_count_exp;
737 int from_tty;
738{
739 all_continue = 1;
740 cont_command (proc_count_exp, from_tty);
741}
742
743/* Here on 1CONT command. Resume only the current thread. */
744
745one_cont_command (proc_count_exp, from_tty)
746 char *proc_count_exp;
747 int from_tty;
748{
749 cont_command (proc_count_exp, from_tty);
750}
751
752/* Print the contents and lock bits of all communication registers,
753 or just register ARG if ARG is a communication register,
754 or the 3-word resource structure in memory at address ARG. */
755
756comm_registers_info (arg)
757 char *arg;
758{
759 int i, regnum;
760
761 if (arg)
762 {
e1a623e7 763 if (sscanf (arg, "$c%d", &regnum) == 1) {
dd3b648e 764 ;
e1a623e7 765 } else if (sscanf (arg, "$C%d", &regnum) == 1) {
dd3b648e 766 ;
e1a623e7 767 } else {
dd3b648e 768 regnum = parse_and_eval_address (arg);
e1a623e7
JG
769 if (regnum > 0)
770 regnum &= ~0x8000;
771 }
dd3b648e
RP
772
773 if (regnum >= 64)
774 error ("%s: invalid register name.", arg);
775
776 /* if we got a (user) address, examine the resource struct there */
777
778 if (regnum < 0)
779 {
780 static int buf[3];
781 read_memory (regnum, buf, sizeof buf);
782 printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2],
783 buf[0] & 0xff ? " locked" : "");
784 return;
785 }
786 }
787
788 ps.pi_buffer = (char *) &comm_registers;
789 ps.pi_nbytes = sizeof comm_registers;
790 ps.pi_offset = 0;
791 ps.pi_thread = inferior_thread;
792 ioctl (inferior_fd, PIXRDCREGS, &ps);
793
794 for (i = 0; i < 64; i++)
795 if (!arg || i == regnum)
796 printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
797 comm_registers.crreg.r4[i],
798 (iscrlbit (comm_registers.crctl.lbits.cc, i)
799 ? " locked" : ""));
800}
801
802/* Print the psw */
803
804static void
805psw_info (arg)
806 char *arg;
807{
808 struct pswbit
809 {
810 int bit;
811 int pos;
812 char *text;
813 };
814
815 static struct pswbit pswbit[] =
816 {
817 { 0x80000000, -1, "A carry" },
818 { 0x40000000, -1, "A integer overflow" },
819 { 0x20000000, -1, "A zero divide" },
820 { 0x10000000, -1, "Integer overflow enable" },
821 { 0x08000000, -1, "Trace" },
822 { 0x06000000, 25, "Frame length" },
823 { 0x01000000, -1, "Sequential" },
824 { 0x00800000, -1, "S carry" },
825 { 0x00400000, -1, "S integer overflow" },
826 { 0x00200000, -1, "S zero divide" },
827 { 0x00100000, -1, "Zero divide enable" },
828 { 0x00080000, -1, "Floating underflow" },
829 { 0x00040000, -1, "Floating overflow" },
830 { 0x00020000, -1, "Floating reserved operand" },
831 { 0x00010000, -1, "Floating zero divide" },
832 { 0x00008000, -1, "Floating error enable" },
833 { 0x00004000, -1, "Floating underflow enable" },
834 { 0x00002000, -1, "IEEE" },
835 { 0x00001000, -1, "Sequential stores" },
836 { 0x00000800, -1, "Intrinsic error" },
837 { 0x00000400, -1, "Intrinsic error enable" },
838 { 0x00000200, -1, "Trace thread creates" },
839 { 0x00000100, -1, "Thread init trap" },
840 { 0x000000e0, 5, "Reserved" },
841 { 0x0000001f, 0, "Intrinsic error code" },
842 {0, 0, 0},
843 };
844
845 long psw;
846 struct pswbit *p;
847
848 if (arg)
849 psw = parse_and_eval_address (arg);
850 else
851 psw = read_register (PS_REGNUM);
852
853 for (p = pswbit; p->bit; p++)
854 {
855 if (p->pos < 0)
856 printf_filtered ("%08x %s %s\n", p->bit,
857 (psw & p->bit) ? "yes" : "no ", p->text);
858 else
859 printf_filtered ("%08x %3d %s\n", p->bit,
860 (psw & p->bit) >> p->pos, p->text);
861 }
862}
863\f
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.146487 seconds and 4 git commands to generate.