8c86ae8fc9f1e2fb2f736cdd2b363633c3492486
[deliverable/binutils-gdb.git] / gdb / convex-tdep.c
1 /* Convex stuff for GDB.
2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21 #include "defs.h"
22 #include "command.h"
23 #include "symtab.h"
24 #include "value.h"
25 #include "frame.h"
26 #include "inferior.h"
27 #include "wait.h"
28
29 #include <signal.h>
30 #include <fcntl.h>
31
32 #include "gdbcore.h"
33 #include <sys/param.h>
34 #include <sys/dir.h>
35 #include <sys/user.h>
36 #include <sys/ioctl.h>
37 #include <sys/pcntl.h>
38 #include <sys/thread.h>
39 #include <sys/proc.h>
40 #include <sys/file.h>
41 #include <sys/stat.h>
42 #include <sys/mman.h>
43
44 #include "gdbcmd.h"
45
46 exec_file_command (filename, from_tty)
47 char *filename;
48 int from_tty;
49 {
50 int val;
51 int n;
52 struct stat st_exec;
53
54 /* Eliminate all traces of old exec file.
55 Mark text segment as empty. */
56
57 if (execfile)
58 free (execfile);
59 execfile = 0;
60 data_start = 0;
61 data_end = 0;
62 text_start = 0;
63 text_end = 0;
64 exec_data_start = 0;
65 exec_data_end = 0;
66 if (execchan >= 0)
67 close (execchan);
68 execchan = -1;
69
70 n_exec = 0;
71
72 /* Now open and digest the file the user requested, if any. */
73
74 if (filename)
75 {
76 filename = tilde_expand (filename);
77 make_cleanup (free, filename);
78
79 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
80 &execfile);
81 if (execchan < 0)
82 perror_with_name (filename);
83
84 if (myread (execchan, &filehdr, sizeof filehdr) < 0)
85 perror_with_name (filename);
86
87 if (! IS_SOFF_MAGIC (filehdr.h_magic))
88 error ("%s: not an executable file.", filename);
89
90 if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)
91 perror_with_name (filename);
92
93 /* Read through the section headers.
94 For text, data, etc, record an entry in the exec file map.
95 Record text_start and text_end. */
96
97 lseek (execchan, (long) filehdr.h_scnptr, 0);
98
99 for (n = 0; n < filehdr.h_nscns; n++)
100 {
101 if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)
102 perror_with_name (filename);
103
104 if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
105 && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
106 {
107 exec_map[n_exec].mem_addr = scnhdr.s_vaddr;
108 exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
109 exec_map[n_exec].file_addr = scnhdr.s_scnptr;
110 exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;
111 n_exec++;
112
113 if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)
114 {
115 text_start = scnhdr.s_vaddr;
116 text_end = scnhdr.s_vaddr + scnhdr.s_size;
117 }
118 }
119 }
120
121 fstat (execchan, &st_exec);
122 exec_mtime = st_exec.st_mtime;
123
124 validate_files ();
125 }
126 else if (from_tty)
127 printf_filtered ("No exec file now.\n");
128
129 /* Tell display code (if any) about the changed file name. */
130 if (exec_file_display_hook)
131 (*exec_file_display_hook) (filename);
132 }
133
134 /* Read data from SOFF exec or core file.
135 Return 0 on success, EIO if address out of bounds. */
136
137 int
138 xfer_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 {
227 bzero (myaddr, i);
228 returnval = EIO;
229 }
230
231 memaddr += i;
232 myaddr += i;
233 len -= i;
234 }
235 return returnval;
236 }
237
238
239 /* Here from info files command to print an address map. */
240
241 print_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
287 static 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
307 int
308 is_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')
320 || !strcmp (name, "vl")
321 || !strcmp (name, "vs")
322 || !strcmp (name, "vm")))
323 return 1;
324 else return 0;
325 }
326
327 /* Return the value of trapped internal variable VAR */
328
329 value
330 value_of_trapped_internalvar (var)
331 struct internalvar *var;
332 {
333 char *name = var->name;
334 value val;
335 struct type *type;
336 long len = *read_vector_register (VL_REGNUM);
337 if (len <= 0 || len > 128) len = 128;
338
339 if (!strcmp (name, "vl"))
340 {
341 val = value_from_longest (builtin_type_int,
342 (LONGEST) *read_vector_register_1 (VL_REGNUM));
343 }
344 else if (!strcmp (name, "vs"))
345 {
346 val = value_from_longest (builtin_type_int,
347 (LONGEST) *read_vector_register_1 (VS_REGNUM));
348 }
349 else if (!strcmp (name, "vm"))
350 {
351 long vm[4];
352 long i, *p;
353 bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);
354 type = vector_type (builtin_type_int, len);
355 val = allocate_value (type);
356 p = (long *) VALUE_CONTENTS (val);
357 for (i = 0; i < len; i++)
358 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
359 }
360 else if (name[0] == 'V')
361 {
362 type = vector_type (builtin_type_long_long, len);
363 val = allocate_value (type);
364 bcopy (read_vector_register_1 (name[1] - '0'),
365 VALUE_CONTENTS (val), TYPE_LENGTH (type));
366 }
367 else if (name[0] == 'v')
368 {
369 long *p1, *p2;
370 type = vector_type (builtin_type_long, len);
371 val = allocate_value (type);
372 p1 = read_vector_register_1 (name[1] - '0');
373 p2 = (long *) VALUE_CONTENTS (val);
374 while (--len >= 0) {p1++; *p2++ = *p1++;}
375 }
376
377 else if (name[0] == 'c')
378 val = value_from_longest (builtin_type_int,
379 read_comm_register (atoi (&name[1])));
380 else if (name[0] == 'C')
381 val = value_from_longest (builtin_type_long_long,
382 read_comm_register (atoi (&name[1])));
383
384 VALUE_LVAL (val) = lval_internalvar;
385 VALUE_INTERNALVAR (val) = var;
386 return val;
387 }
388
389 /* Construct the type for a vector register's value --
390 array[LENGTH] of ELEMENT_TYPE. */
391
392 static struct type *
393 vector_type (element_type, length)
394 struct type *element_type;
395 long length;
396 {
397 struct type *type = (struct type *) xmalloc (sizeof (struct type));
398 bzero (type, sizeof type);
399 TYPE_CODE (type) = TYPE_CODE_ARRAY;
400 TYPE_TARGET_TYPE (type) = element_type;
401 TYPE_LENGTH (type) = length * TYPE_LENGTH (TYPE_TARGET_TYPE (type));
402 return type;
403 }
404
405 /* Handle a new value assigned to a trapped internal variable */
406
407 void
408 set_trapped_internalvar (var, val, bitpos, bitsize, offset)
409 struct internalvar *var;
410 value val;
411 int bitpos, bitsize, offset;
412 {
413 char *name = var->name;
414 long long newval = value_as_long (val);
415
416 if (!strcmp (name, "vl"))
417 write_vector_register (VL_REGNUM, 0, newval);
418 else if (!strcmp (name, "vs"))
419 write_vector_register (VS_REGNUM, 0, newval);
420 else if (name[0] == 'c' || name[0] == 'C')
421 write_comm_register (atoi (&name[1]), newval);
422 else if (!strcmp (name, "vm"))
423 error ("can't assign to $vm");
424 else
425 {
426 offset /= bitsize / 8;
427 write_vector_register (name[1] - '0', offset, newval);
428 }
429 }
430
431 /* Print an integer value when no format was specified. gdb normally
432 prints these values in decimal, but the the leading 0x80000000 of
433 pointers produces intolerable 10-digit negative numbers.
434 If it looks like an address, print it in hex instead. */
435
436 decout (stream, type, val)
437 FILE *stream;
438 struct type *type;
439 LONGEST val;
440 {
441 long lv = val;
442
443 switch (output_radix)
444 {
445 case 0:
446 if ((lv == val || (unsigned) lv == val)
447 && ((lv & 0xf0000000) == 0x80000000
448 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
449 {
450 fprintf_filtered (stream, "%#x", lv);
451 return;
452 }
453
454 case 10:
455 fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
456 return;
457
458 case 8:
459 if (TYPE_LENGTH (type) <= sizeof lv)
460 fprintf_filtered (stream, "%#o", lv);
461 else
462 fprintf_filtered (stream, "%#llo", val);
463 return;
464
465 case 16:
466 if (TYPE_LENGTH (type) <= sizeof lv)
467 fprintf_filtered (stream, "%#x", lv);
468 else
469 fprintf_filtered (stream, "%#llx", val);
470 return;
471 }
472 }
473
474 /* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
475 This command is mostly obsolete now that the print command allows
476 formats to apply to aggregates, but is still handy occasionally. */
477
478 static void
479 set_base_command (arg)
480 char *arg;
481 {
482 int new_radix;
483
484 if (!arg)
485 output_radix = 0;
486 else
487 {
488 new_radix = atoi (arg);
489 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
490 error ("base must be 8, 10 or 16, or null");
491 else output_radix = new_radix;
492 }
493 }
494
495 /* Turn pipelining on or off in the inferior. */
496
497 static void
498 set_pipelining_command (arg)
499 char *arg;
500 {
501 if (!arg)
502 {
503 sequential = !sequential;
504 printf_filtered ("%s\n", sequential ? "off" : "on");
505 }
506 else if (!strcmp (arg, "on"))
507 sequential = 0;
508 else if (!strcmp (arg, "off"))
509 sequential = 1;
510 else error ("valid args are `on', to allow instructions to overlap, or\n\
511 `off', to prevent it and thereby pinpoint exceptions.");
512 }
513
514 /* Enable, disable, or force parallel execution in the inferior. */
515
516 static void
517 set_parallel_command (arg)
518 char *arg;
519 {
520 struct rlimit rl;
521 int prevparallel = parallel;
522
523 if (!strncmp (arg, "fixed", strlen (arg)))
524 parallel = 2;
525 else if (!strcmp (arg, "on"))
526 parallel = 1;
527 else if (!strcmp (arg, "off"))
528 parallel = 0;
529 else error ("valid args are `on', to allow multiple threads, or\n\
530 `fixed', to force multiple threads, or\n\
531 `off', to run with one thread only.");
532
533 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
534 printf_filtered ("will take effect at next run.\n");
535
536 getrlimit (RLIMIT_CONCUR, &rl);
537 rl.rlim_cur = parallel ? rl.rlim_max : 1;
538 setrlimit (RLIMIT_CONCUR, &rl);
539
540 if (inferior_pid)
541 set_fixed_scheduling (inferior_pid, parallel == 2);
542 }
543
544 /* Add a new name for an existing command. */
545
546 static void
547 alias_command (arg)
548 char *arg;
549 {
550 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
551 char *newname = arg;
552 struct cmd_list_element *new, *old;
553
554 if (!arg)
555 error_no_arg ("newname oldname");
556
557 new = lookup_cmd (&arg, cmdlist, "", -1);
558 if (new && !strncmp (newname, new->name, strlen (new->name)))
559 {
560 newname = new->name;
561 if (!(*arg == '-'
562 || (*arg >= 'a' && *arg <= 'z')
563 || (*arg >= 'A' && *arg <= 'Z')
564 || (*arg >= '0' && *arg <= '9')))
565 error (aliaserr);
566 }
567 else
568 {
569 arg = newname;
570 while (*arg == '-'
571 || (*arg >= 'a' && *arg <= 'z')
572 || (*arg >= 'A' && *arg <= 'Z')
573 || (*arg >= '0' && *arg <= '9'))
574 arg++;
575 if (*arg != ' ' && *arg != '\t')
576 error (aliaserr);
577 *arg = '\0';
578 arg++;
579 }
580
581 old = lookup_cmd (&arg, cmdlist, "", 0);
582
583 if (*arg != '\0')
584 error (aliaserr);
585
586 if (new && !strncmp (newname, new->name, strlen (new->name)))
587 {
588 char *tem;
589 if (new->class == (int) class_user || new->class == (int) class_alias)
590 tem = "Redefine command \"%s\"? ";
591 else
592 tem = "Really redefine built-in command \"%s\"? ";
593 if (!query (tem, new->name))
594 error ("Command \"%s\" not redefined.", new->name);
595 }
596
597 add_com (newname, class_alias, old->function, old->doc);
598 }
599
600
601
602 /* Print the current thread number, and any threads with signals in the
603 queue. */
604
605 thread_info ()
606 {
607 struct threadpid *p;
608
609 if (have_inferior_p ())
610 {
611 ps.pi_buffer = (char *) &comm_registers;
612 ps.pi_nbytes = sizeof comm_registers;
613 ps.pi_offset = 0;
614 ps.pi_thread = inferior_thread;
615 ioctl (inferior_fd, PIXRDCREGS, &ps);
616 }
617
618 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
619 inferior_thread, stop_signal, stop_sigcode,
620 subsig_name (stop_signal, stop_sigcode));
621
622 for (p = signal_stack; p->pid; p--)
623 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
624 p->thread, p->signo, p->subsig,
625 subsig_name (p->signo, p->subsig));
626
627 if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
628 printf_filtered ("New thread start pc %#x\n",
629 (long) (comm_registers.crreg.pcpsw >> 32));
630 }
631
632 /* Return string describing a signal.subcode number */
633
634 static char *
635 subsig_name (signo, subcode)
636 int signo, subcode;
637 {
638 static char *subsig4[] = {
639 "error exit", "privileged instruction", "unknown",
640 "unknown", "undefined opcode",
641 0};
642 static char *subsig5[] = {0,
643 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
644 "join trap", "idle trap", "last thread", "wfork trap",
645 "process breakpoint", "trap instruction",
646 0};
647 static char *subsig8[] = {0,
648 "int overflow", "int divide check", "float overflow",
649 "float divide check", "float underflow", "reserved operand",
650 "sqrt error", "exp error", "ln error", "sin error", "cos error",
651 0};
652 static char *subsig10[] = {0,
653 "invalid inward ring address", "invalid outward ring call",
654 "invalid inward ring return", "invalid syscall gate",
655 "invalid rtn frame length", "invalid comm reg address",
656 "invalid trap gate",
657 0};
658 static char *subsig11[] = {0,
659 "read access denied", "write access denied", "execute access denied",
660 "segment descriptor fault", "page table fault", "data reference fault",
661 "i/o access denied", "levt pte invalid",
662 0};
663
664 static char **subsig_list[] =
665 {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
666
667 int i;
668 char *p = signo < NSIG ? sys_siglist[signo] : "unknown";
669
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
683 static void
684 threadstat ()
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
702 set_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);
725 print_stack_frame (selected_frame, selected_frame_level, -1);
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
733 static void
734 convex_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
744 one_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
755 comm_registers_info (arg)
756 char *arg;
757 {
758 int i, regnum;
759
760 if (arg)
761 {
762 if (sscanf (arg, "$c%d", &regnum) == 1) {
763 ;
764 } else if (sscanf (arg, "$C%d", &regnum) == 1) {
765 ;
766 } else {
767 regnum = parse_and_eval_address (arg);
768 if (regnum > 0)
769 regnum &= ~0x8000;
770 }
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
803 static void
804 psw_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
863 _initialize_convex_dep ()
864 {
865 add_com ("alias", class_support, alias_command,
866 "Add a new name for an existing command.");
867
868 add_cmd ("base", class_vars, set_base_command,
869 "Change the integer output radix to 8, 10 or 16\n\
870 or use just `set base' with no args to return to the ad-hoc default,\n\
871 which is 16 for integers that look like addresses, 10 otherwise.",
872 &setlist);
873
874 add_cmd ("pipeline", class_run, set_pipelining_command,
875 "Enable or disable overlapped execution of instructions.\n\
876 With `set pipe off', exceptions are reported with\n\
877 $pc pointing at the instruction after the faulting one.\n\
878 The default is `set pipe on', which runs faster.",
879 &setlist);
880
881 add_cmd ("parallel", class_run, set_parallel_command,
882 "Enable or disable multi-threaded execution of parallel code.\n\
883 `set parallel off' means run the program on a single CPU.\n\
884 `set parallel fixed' means run the program with all CPUs assigned to it.\n\
885 `set parallel on' means run the program on any CPUs that are available.",
886 &setlist);
887
888 add_com ("1cont", class_run, one_cont_command,
889 "Continue the program, activating only the current thread.\n\
890 Args are the same as the `cont' command.");
891
892 add_com ("thread", class_run, set_thread_command,
893 "Change the current thread, the one under scrutiny and control.\n\
894 With no arg, show the active threads, the current one marked with *.");
895
896 add_info ("threads", thread_info,
897 "List status of active threads.");
898
899 add_info ("comm-registers", comm_registers_info,
900 "List communication registers and their contents.\n\
901 A communication register name as argument means describe only that register.\n\
902 An address as argument means describe the resource structure at that address.\n\
903 `Locked' means that the register has been sent to but not yet received from.");
904
905 add_info ("psw", psw_info,
906 "Display $ps, the processor status word, bit by bit.\n\
907 An argument means display that value's interpretation as a psw.");
908
909 add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
910 32-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
911 64-bit registers $S0-7 $V0-7 $C0-63\n\
912 \n\
913 info threads display info on stopped threads waiting to signal\n\
914 thread display list of active threads\n\
915 thread N select thread N (its registers, stack, memory, etc.)\n\
916 step, next, etc step selected thread only\n\
917 1cont continue selected thread only\n\
918 cont continue all threads\n\
919 info comm-registers display contents of comm register(s) or a resource struct\n\
920 info psw display processor status word $ps\n\
921 set base N change integer radix used by `print' without a format\n\
922 set pipeline off exceptions are precise, $pc points after the faulting insn\n\
923 set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
924 set parallel off program runs on a single CPU\n\
925 set parallel fixed all CPUs are assigned to the program\n\
926 set parallel on normal mode, parallel execution on random available CPUs\n\
927 ",
928 &cmdlist);
929
930 }
This page took 0.048288 seconds and 4 git commands to generate.