]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/convex-tdep.c
Johns release
[thirdparty/binutils-gdb.git] / gdb / convex-tdep.c
CommitLineData
dd3b648e
RP
1/* Convex stuff for GDB.
2 Copyright (C) 1990 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6GDB is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GDB is distributed in the hope that it will be useful,
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
17along with GDB; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include <stdio.h>
21#include "defs.h"
22#include "param.h"
23#include "command.h"
24#include "symtab.h"
25#include "value.h"
26#include "frame.h"
27#include "inferior.h"
28#include "wait.h"
29
30#include <signal.h>
31#include <fcntl.h>
32
33#include "gdbcore.h"
34#include <sys/param.h>
35#include <sys/dir.h>
36#include <sys/user.h>
37#include <sys/ioctl.h>
38#include <sys/pcntl.h>
39#include <sys/thread.h>
40#include <sys/proc.h>
41#include <sys/file.h>
42#include <sys/stat.h>
43#include <sys/mman.h>
44
45#include "gdbcmd.h"
46
47exec_file_command (filename, from_tty)
48 char *filename;
49 int from_tty;
50{
51 int val;
52 int n;
53 struct stat st_exec;
54
55 /* Eliminate all traces of old exec file.
56 Mark text segment as empty. */
57
58 if (execfile)
59 free (execfile);
60 execfile = 0;
61 data_start = 0;
62 data_end = 0;
63 text_start = 0;
64 text_end = 0;
65 exec_data_start = 0;
66 exec_data_end = 0;
67 if (execchan >= 0)
68 close (execchan);
69 execchan = -1;
70
71 n_exec = 0;
72
73 /* Now open and digest the file the user requested, if any. */
74
75 if (filename)
76 {
77 filename = tilde_expand (filename);
78 make_cleanup (free, filename);
79
80 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
81 &execfile);
82 if (execchan < 0)
83 perror_with_name (filename);
84
85 if (myread (execchan, &filehdr, sizeof filehdr) < 0)
86 perror_with_name (filename);
87
88 if (! IS_SOFF_MAGIC (filehdr.h_magic))
89 error ("%s: not an executable file.", filename);
90
91 if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)
92 perror_with_name (filename);
93
94 /* Read through the section headers.
95 For text, data, etc, record an entry in the exec file map.
96 Record text_start and text_end. */
97
98 lseek (execchan, (long) filehdr.h_scnptr, 0);
99
100 for (n = 0; n < filehdr.h_nscns; n++)
101 {
102 if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)
103 perror_with_name (filename);
104
105 if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
106 && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
107 {
108 exec_map[n_exec].mem_addr = scnhdr.s_vaddr;
109 exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
110 exec_map[n_exec].file_addr = scnhdr.s_scnptr;
111 exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;
112 n_exec++;
113
114 if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)
115 {
116 text_start = scnhdr.s_vaddr;
117 text_end = scnhdr.s_vaddr + scnhdr.s_size;
118 }
119 }
120 }
121
122 fstat (execchan, &st_exec);
123 exec_mtime = st_exec.st_mtime;
124
125 validate_files ();
126 }
127 else if (from_tty)
128 printf_filtered ("No exec file now.\n");
129
130 /* Tell display code (if any) about the changed file name. */
131 if (exec_file_display_hook)
132 (*exec_file_display_hook) (filename);
133}
134
135/* Read data from SOFF exec or core file.
136 Return 0 on success, EIO if address out of bounds. */
137
138int
139xfer_core_file (memaddr, myaddr, len)
140 CORE_ADDR memaddr;
141 char *myaddr;
142 int len;
143{
144 register int i;
145 register int n;
146 register int val;
147 int xferchan;
148 char **xferfile;
149 int fileptr;
150 int returnval = 0;
151
152 while (len > 0)
153 {
154 xferfile = 0;
155 xferchan = 0;
156
157 /* Determine which file the next bunch of addresses reside in,
158 and where in the file. Set the file's read/write pointer
159 to point at the proper place for the desired address
160 and set xferfile and xferchan for the correct file.
161 If desired address is nonexistent, leave them zero.
162 i is set to the number of bytes that can be handled
163 along with the next address. */
164
165 i = len;
166
167 for (n = 0; n < n_core; n++)
168 {
169 if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end
170 && (core_map[n].thread == -1
171 || core_map[n].thread == inferior_thread))
172 {
173 i = min (len, core_map[n].mem_end - memaddr);
174 fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;
175 if (core_map[n].file_addr)
176 {
177 xferfile = &corefile;
178 xferchan = corechan;
179 }
180 break;
181 }
182 else if (core_map[n].mem_addr >= memaddr
183 && core_map[n].mem_addr < memaddr + i)
184 i = core_map[n].mem_addr - memaddr;
185 }
186
187 if (!xferfile)
188 for (n = 0; n < n_exec; n++)
189 {
190 if (memaddr >= exec_map[n].mem_addr
191 && memaddr < exec_map[n].mem_end)
192 {
193 i = min (len, exec_map[n].mem_end - memaddr);
194 fileptr = exec_map[n].file_addr + memaddr
195 - exec_map[n].mem_addr;
196 if (exec_map[n].file_addr)
197 {
198 xferfile = &execfile;
199 xferchan = execchan;
200 }
201 break;
202 }
203 else if (exec_map[n].mem_addr >= memaddr
204 && exec_map[n].mem_addr < memaddr + i)
205 i = exec_map[n].mem_addr - memaddr;
206 }
207
208 /* Now we know which file to use.
209 Set up its pointer and transfer the data. */
210 if (xferfile)
211 {
212 if (*xferfile == 0)
213 if (xferfile == &execfile)
214 error ("No program file to examine.");
215 else
216 error ("No core dump file or running program to examine.");
217 val = lseek (xferchan, fileptr, 0);
218 if (val < 0)
219 perror_with_name (*xferfile);
220 val = myread (xferchan, myaddr, i);
221 if (val < 0)
222 perror_with_name (*xferfile);
223 }
224 /* If this address is for nonexistent memory,
225 read zeros if reading, or do nothing if writing. */
226 else
227 {
228 bzero (myaddr, i);
229 returnval = EIO;
230 }
231
232 memaddr += i;
233 myaddr += i;
234 len -= i;
235 }
236 return returnval;
237}
238
239
240/* Here from info files command to print an address map. */
241
242print_maps ()
243{
244 struct pmap ptrs[200];
245 int n;
246
247 /* ID strings for core and executable file sections */
248
249 static char *idstr[] =
250 {
251 "0", "text", "data", "tdata", "bss", "tbss",
252 "common", "ttext", "ctx", "tctx", "10", "11", "12",
253 };
254
255 for (n = 0; n < n_core; n++)
256 {
257 core_map[n].which = 0;
258 ptrs[n] = core_map[n];
259 }
260 for (n = 0; n < n_exec; n++)
261 {
262 exec_map[n].which = 1;
263 ptrs[n_core+n] = exec_map[n];
264 }
265
266 qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);
267
268 for (n = 0; n < n_core + n_exec; n++)
269 {
270 struct pmap *p = &ptrs[n];
271 if (n > 0)
272 {
273 if (p->mem_addr < ptrs[n-1].mem_end)
274 p->mem_addr = ptrs[n-1].mem_end;
275 if (p->mem_addr >= p->mem_end)
276 continue;
277 }
278 printf_filtered ("%08x .. %08x %-6s %s\n",
279 p->mem_addr, p->mem_end, idstr[p->type],
280 p->which ? execfile : corefile);
281 }
282}
283
284/* Compare routine to put file sections in order.
285 Sort into increasing order on address, and put core file sections
286 before exec file sections if both files contain the same addresses. */
287
288static ptr_cmp (a, b)
289 struct pmap *a, *b;
290{
291 if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;
292 return a->which - b->which;
293}
294\f
295/* Trapped internal variables are used to handle special registers.
296 A trapped i.v. calls a hook here every time it is dereferenced,
297 to provide a new value for the variable, and it calls a hook here
298 when a new value is assigned, to do something with the value.
299
300 The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
301 The communication registers are $cN, $CN (N in 0..63).
302 They not handled as regular registers because it's expensive to
303 read them, and their size varies, and they have too many names. */
304
305
306/* Return 1 if NAME is a trapped internal variable, else 0. */
307
308int
309is_trapped_internalvar (name)
310 char *name;
311{
312 if ((name[0] == 'c' || name[0] == 'C')
313 && name[1] >= '0' && name[1] <= '9'
314 && (name[2] == '\0'
315 || (name[2] >= '0' && name[2] <= '9'
316 && name[3] == '\0' && name[1] != '0'))
317 && atoi (&name[1]) < 64) return 1;
318
319 if ((name[0] == 'v' || name[0] == 'V')
320 && (((name[1] & -8) == '0' && name[2] == '\0')
321 || !strcmp (name, "vl")
322 || !strcmp (name, "vs")
323 || !strcmp (name, "vm")))
324 return 1;
325 else return 0;
326}
327
328/* Return the value of trapped internal variable VAR */
329
330value
331value_of_trapped_internalvar (var)
332 struct internalvar *var;
333{
334 char *name = var->name;
335 value val;
336 struct type *type;
337 long len = *read_vector_register (VL_REGNUM);
338 if (len <= 0 || len > 128) len = 128;
339
340 if (!strcmp (name, "vl"))
341 {
342 val = value_from_long (builtin_type_int,
343 (LONGEST) *read_vector_register_1 (VL_REGNUM));
344 }
345 else if (!strcmp (name, "vs"))
346 {
347 val = value_from_long (builtin_type_int,
348 (LONGEST) *read_vector_register_1 (VS_REGNUM));
349 }
350 else if (!strcmp (name, "vm"))
351 {
352 long vm[4];
353 long i, *p;
354 bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);
355 type = vector_type (builtin_type_int, len);
356 val = allocate_value (type);
357 p = (long *) VALUE_CONTENTS (val);
358 for (i = 0; i < len; i++)
359 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
360 }
361 else if (name[0] == 'V')
362 {
363 type = vector_type (builtin_type_long_long, len);
364 val = allocate_value (type);
365 bcopy (read_vector_register_1 (name[1] - '0'),
366 VALUE_CONTENTS (val), TYPE_LENGTH (type));
367 }
368 else if (name[0] == 'v')
369 {
370 long *p1, *p2;
371 type = vector_type (builtin_type_long, len);
372 val = allocate_value (type);
373 p1 = read_vector_register_1 (name[1] - '0');
374 p2 = (long *) VALUE_CONTENTS (val);
375 while (--len >= 0) {p1++; *p2++ = *p1++;}
376 }
377
378 else if (name[0] == 'c')
379 val = value_from_long (builtin_type_int,
380 read_comm_register (atoi (&name[1])));
381 else if (name[0] == 'C')
382 val = value_from_long (builtin_type_long_long,
383 read_comm_register (atoi (&name[1])));
384
385 VALUE_LVAL (val) = lval_internalvar;
386 VALUE_INTERNALVAR (val) = var;
387 return val;
388}
389
390/* Construct the type for a vector register's value --
391 array[LENGTH] of ELEMENT_TYPE. */
392
393static struct type *
394vector_type (element_type, length)
395 struct type *element_type;
396 long length;
397{
398 struct type *type = (struct type *) xmalloc (sizeof (struct type));
399 bzero (type, sizeof type);
400 TYPE_CODE (type) = TYPE_CODE_ARRAY;
401 TYPE_TARGET_TYPE (type) = element_type;
402 TYPE_LENGTH (type) = length * TYPE_LENGTH (TYPE_TARGET_TYPE (type));
403 return type;
404}
405
406/* Handle a new value assigned to a trapped internal variable */
407
408void
409set_trapped_internalvar (var, val, bitpos, bitsize, offset)
410 struct internalvar *var;
411 value val;
412 int bitpos, bitsize, offset;
413{
414 char *name = var->name;
415 long long newval = value_as_long (val);
416
417 if (!strcmp (name, "vl"))
418 write_vector_register (VL_REGNUM, 0, newval);
419 else if (!strcmp (name, "vs"))
420 write_vector_register (VS_REGNUM, 0, newval);
421 else if (name[0] == 'c' || name[0] == 'C')
422 write_comm_register (atoi (&name[1]), newval);
423 else if (!strcmp (name, "vm"))
424 error ("can't assign to $vm");
425 else
426 {
427 offset /= bitsize / 8;
428 write_vector_register (name[1] - '0', offset, newval);
429 }
430}
431
432/* Print an integer value when no format was specified. gdb normally
433 prints these values in decimal, but the the leading 0x80000000 of
434 pointers produces intolerable 10-digit negative numbers.
435 If it looks like an address, print it in hex instead. */
436
437decout (stream, type, val)
438 FILE *stream;
439 struct type *type;
440 LONGEST val;
441{
442 long lv = val;
443
444 switch (output_radix)
445 {
446 case 0:
447 if ((lv == val || (unsigned) lv == val)
448 && ((lv & 0xf0000000) == 0x80000000
449 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
450 {
451 fprintf_filtered (stream, "%#x", lv);
452 return;
453 }
454
455 case 10:
456 fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
457 return;
458
459 case 8:
460 if (TYPE_LENGTH (type) <= sizeof lv)
461 fprintf_filtered (stream, "%#o", lv);
462 else
463 fprintf_filtered (stream, "%#llo", val);
464 return;
465
466 case 16:
467 if (TYPE_LENGTH (type) <= sizeof lv)
468 fprintf_filtered (stream, "%#x", lv);
469 else
470 fprintf_filtered (stream, "%#llx", val);
471 return;
472 }
473}
474
475/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
476 This command is mostly obsolete now that the print command allows
477 formats to apply to aggregates, but is still handy occasionally. */
478
479static void
480set_base_command (arg)
481 char *arg;
482{
483 int new_radix;
484
485 if (!arg)
486 output_radix = 0;
487 else
488 {
489 new_radix = atoi (arg);
490 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
491 error ("base must be 8, 10 or 16, or null");
492 else output_radix = new_radix;
493 }
494}
495
496/* Turn pipelining on or off in the inferior. */
497
498static void
499set_pipelining_command (arg)
500 char *arg;
501{
502 if (!arg)
503 {
504 sequential = !sequential;
505 printf_filtered ("%s\n", sequential ? "off" : "on");
506 }
507 else if (!strcmp (arg, "on"))
508 sequential = 0;
509 else if (!strcmp (arg, "off"))
510 sequential = 1;
511 else error ("valid args are `on', to allow instructions to overlap, or\n\
512`off', to prevent it and thereby pinpoint exceptions.");
513}
514
515/* Enable, disable, or force parallel execution in the inferior. */
516
517static void
518set_parallel_command (arg)
519 char *arg;
520{
521 struct rlimit rl;
522 int prevparallel = parallel;
523
524 if (!strncmp (arg, "fixed", strlen (arg)))
525 parallel = 2;
526 else if (!strcmp (arg, "on"))
527 parallel = 1;
528 else if (!strcmp (arg, "off"))
529 parallel = 0;
530 else error ("valid args are `on', to allow multiple threads, or\n\
531`fixed', to force multiple threads, or\n\
532`off', to run with one thread only.");
533
534 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
535 printf_filtered ("will take effect at next run.\n");
536
537 getrlimit (RLIMIT_CONCUR, &rl);
538 rl.rlim_cur = parallel ? rl.rlim_max : 1;
539 setrlimit (RLIMIT_CONCUR, &rl);
540
541 if (inferior_pid)
542 set_fixed_scheduling (inferior_pid, parallel == 2);
543}
544
545/* Add a new name for an existing command. */
546
547static void
548alias_command (arg)
549 char *arg;
550{
551 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
552 char *newname = arg;
553 struct cmd_list_element *new, *old;
554
555 if (!arg)
556 error_no_arg ("newname oldname");
557
558 new = lookup_cmd (&arg, cmdlist, "", -1);
559 if (new && !strncmp (newname, new->name, strlen (new->name)))
560 {
561 newname = new->name;
562 if (!(*arg == '-'
563 || (*arg >= 'a' && *arg <= 'z')
564 || (*arg >= 'A' && *arg <= 'Z')
565 || (*arg >= '0' && *arg <= '9')))
566 error (aliaserr);
567 }
568 else
569 {
570 arg = newname;
571 while (*arg == '-'
572 || (*arg >= 'a' && *arg <= 'z')
573 || (*arg >= 'A' && *arg <= 'Z')
574 || (*arg >= '0' && *arg <= '9'))
575 arg++;
576 if (*arg != ' ' && *arg != '\t')
577 error (aliaserr);
578 *arg = '\0';
579 arg++;
580 }
581
582 old = lookup_cmd (&arg, cmdlist, "", 0);
583
584 if (*arg != '\0')
585 error (aliaserr);
586
587 if (new && !strncmp (newname, new->name, strlen (new->name)))
588 {
589 char *tem;
590 if (new->class == (int) class_user || new->class == (int) class_alias)
591 tem = "Redefine command \"%s\"? ";
592 else
593 tem = "Really redefine built-in command \"%s\"? ";
594 if (!query (tem, new->name))
595 error ("Command \"%s\" not redefined.", new->name);
596 }
597
598 add_com (newname, class_alias, old->function, old->doc);
599}
600
601
602
603/* Print the current thread number, and any threads with signals in the
604 queue. */
605
606thread_info ()
607{
608 struct threadpid *p;
609
610 if (have_inferior_p ())
611 {
612 ps.pi_buffer = (char *) &comm_registers;
613 ps.pi_nbytes = sizeof comm_registers;
614 ps.pi_offset = 0;
615 ps.pi_thread = inferior_thread;
616 ioctl (inferior_fd, PIXRDCREGS, &ps);
617 }
618
619 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
620 inferior_thread, stop_signal, stop_sigcode,
621 subsig_name (stop_signal, stop_sigcode));
622
623 for (p = signal_stack; p->pid; p--)
624 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
625 p->thread, p->signo, p->subsig,
626 subsig_name (p->signo, p->subsig));
627
628 if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
629 printf_filtered ("New thread start pc %#x\n",
630 (long) (comm_registers.crreg.pcpsw >> 32));
631}
632
633/* Return string describing a signal.subcode number */
634
635static char *
636subsig_name (signo, subcode)
637 int signo, subcode;
638{
639 static char *subsig4[] = {
640 "error exit", "privileged instruction", "unknown",
641 "unknown", "undefined opcode",
642 0};
643 static char *subsig5[] = {0,
644 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
645 "join trap", "idle trap", "last thread", "wfork trap",
646 "process breakpoint", "trap instruction",
647 0};
648 static char *subsig8[] = {0,
649 "int overflow", "int divide check", "float overflow",
650 "float divide check", "float underflow", "reserved operand",
651 "sqrt error", "exp error", "ln error", "sin error", "cos error",
652 0};
653 static char *subsig10[] = {0,
654 "invalid inward ring address", "invalid outward ring call",
655 "invalid inward ring return", "invalid syscall gate",
656 "invalid rtn frame length", "invalid comm reg address",
657 "invalid trap gate",
658 0};
659 static char *subsig11[] = {0,
660 "read access denied", "write access denied", "execute access denied",
661 "segment descriptor fault", "page table fault", "data reference fault",
662 "i/o access denied", "levt pte invalid",
663 0};
664
665 static char **subsig_list[] =
666 {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
667
668 int i;
669 char *p = signo < NSIG ? sys_siglist[signo] : "unknown";
670
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);
726 print_sel_frame (1);
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 {
763 if (sscanf (arg, "0x%x", &regnum) == 1
764 || sscanf (arg, "%d", &regnum) == 1)
765 {
766 if (regnum > 0)
767 regnum &= ~0x8000;
768 }
769 else if (sscanf (arg, "$c%d", &regnum) == 1)
770 ;
771 else if (sscanf (arg, "$C%d", &regnum) == 1)
772 ;
773 else
774 regnum = parse_and_eval_address (arg);
775
776 if (regnum >= 64)
777 error ("%s: invalid register name.", arg);
778
779 /* if we got a (user) address, examine the resource struct there */
780
781 if (regnum < 0)
782 {
783 static int buf[3];
784 read_memory (regnum, buf, sizeof buf);
785 printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2],
786 buf[0] & 0xff ? " locked" : "");
787 return;
788 }
789 }
790
791 ps.pi_buffer = (char *) &comm_registers;
792 ps.pi_nbytes = sizeof comm_registers;
793 ps.pi_offset = 0;
794 ps.pi_thread = inferior_thread;
795 ioctl (inferior_fd, PIXRDCREGS, &ps);
796
797 for (i = 0; i < 64; i++)
798 if (!arg || i == regnum)
799 printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
800 comm_registers.crreg.r4[i],
801 (iscrlbit (comm_registers.crctl.lbits.cc, i)
802 ? " locked" : ""));
803}
804
805/* Print the psw */
806
807static void
808psw_info (arg)
809 char *arg;
810{
811 struct pswbit
812 {
813 int bit;
814 int pos;
815 char *text;
816 };
817
818 static struct pswbit pswbit[] =
819 {
820 { 0x80000000, -1, "A carry" },
821 { 0x40000000, -1, "A integer overflow" },
822 { 0x20000000, -1, "A zero divide" },
823 { 0x10000000, -1, "Integer overflow enable" },
824 { 0x08000000, -1, "Trace" },
825 { 0x06000000, 25, "Frame length" },
826 { 0x01000000, -1, "Sequential" },
827 { 0x00800000, -1, "S carry" },
828 { 0x00400000, -1, "S integer overflow" },
829 { 0x00200000, -1, "S zero divide" },
830 { 0x00100000, -1, "Zero divide enable" },
831 { 0x00080000, -1, "Floating underflow" },
832 { 0x00040000, -1, "Floating overflow" },
833 { 0x00020000, -1, "Floating reserved operand" },
834 { 0x00010000, -1, "Floating zero divide" },
835 { 0x00008000, -1, "Floating error enable" },
836 { 0x00004000, -1, "Floating underflow enable" },
837 { 0x00002000, -1, "IEEE" },
838 { 0x00001000, -1, "Sequential stores" },
839 { 0x00000800, -1, "Intrinsic error" },
840 { 0x00000400, -1, "Intrinsic error enable" },
841 { 0x00000200, -1, "Trace thread creates" },
842 { 0x00000100, -1, "Thread init trap" },
843 { 0x000000e0, 5, "Reserved" },
844 { 0x0000001f, 0, "Intrinsic error code" },
845 {0, 0, 0},
846 };
847
848 long psw;
849 struct pswbit *p;
850
851 if (arg)
852 psw = parse_and_eval_address (arg);
853 else
854 psw = read_register (PS_REGNUM);
855
856 for (p = pswbit; p->bit; p++)
857 {
858 if (p->pos < 0)
859 printf_filtered ("%08x %s %s\n", p->bit,
860 (psw & p->bit) ? "yes" : "no ", p->text);
861 else
862 printf_filtered ("%08x %3d %s\n", p->bit,
863 (psw & p->bit) >> p->pos, p->text);
864 }
865}
866\f
867_initialize_convex_dep ()
868{
869 add_com ("alias", class_support, alias_command,
870 "Add a new name for an existing command.");
871
872 add_cmd ("base", class_vars, set_base_command,
873 "Change the integer output radix to 8, 10 or 16\n\
874or use just `set base' with no args to return to the ad-hoc default,\n\
875which is 16 for integers that look like addresses, 10 otherwise.",
876 &setlist);
877
878 add_cmd ("pipeline", class_run, set_pipelining_command,
879 "Enable or disable overlapped execution of instructions.\n\
880With `set pipe off', exceptions are reported with\n\
881$pc pointing at the instruction after the faulting one.\n\
882The default is `set pipe on', which runs faster.",
883 &setlist);
884
885 add_cmd ("parallel", class_run, set_parallel_command,
886 "Enable or disable multi-threaded execution of parallel code.\n\
887`set parallel off' means run the program on a single CPU.\n\
888`set parallel fixed' means run the program with all CPUs assigned to it.\n\
889`set parallel on' means run the program on any CPUs that are available.",
890 &setlist);
891
892 add_com ("1cont", class_run, one_cont_command,
893 "Continue the program, activating only the current thread.\n\
894Args are the same as the `cont' command.");
895
896 add_com ("thread", class_run, set_thread_command,
897 "Change the current thread, the one under scrutiny and control.\n\
898With no arg, show the active threads, the current one marked with *.");
899
900 add_info ("threads", thread_info,
901 "List status of active threads.");
902
903 add_info ("comm-registers", comm_registers_info,
904 "List communication registers and their contents.\n\
905A communication register name as argument means describe only that register.\n\
906An address as argument means describe the resource structure at that address.\n\
907`Locked' means that the register has been sent to but not yet received from.");
908
909 add_info ("psw", psw_info,
910 "Display $ps, the processor status word, bit by bit.\n\
911An argument means display that value's interpretation as a psw.");
912
913 add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
91432-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
91564-bit registers $S0-7 $V0-7 $C0-63\n\
916\n\
917info threads display info on stopped threads waiting to signal\n\
918thread display list of active threads\n\
919thread N select thread N (its registers, stack, memory, etc.)\n\
920step, next, etc step selected thread only\n\
9211cont continue selected thread only\n\
922cont continue all threads\n\
923info comm-registers display contents of comm register(s) or a resource struct\n\
924info psw display processor status word $ps\n\
925set base N change integer radix used by `print' without a format\n\
926set pipeline off exceptions are precise, $pc points after the faulting insn\n\
927set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
928set parallel off program runs on a single CPU\n\
929set parallel fixed all CPUs are assigned to the program\n\
930set parallel on normal mode, parallel execution on random available CPUs\n\
931",
932 &cmdlist);
933
934}