Change GDB over to GNU General Public License version 2.
[external/binutils.git] / gdb / convex-tdep.c
1 /* Convex stuff for GDB.
2    Copyright (C) 1990 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 "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
47 exec_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
138 int
139 xfer_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
242 print_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
288 static 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
308 int
309 is_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
330 value
331 value_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
393 static struct type *
394 vector_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
408 void
409 set_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
437 decout (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
479 static void
480 set_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
498 static void
499 set_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
517 static void
518 set_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
547 static void 
548 alias_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
606 thread_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
635 static char *
636 subsig_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
684 static void
685 threadstat ()
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
703 set_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
734 static void
735 convex_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
745 one_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
756 comm_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
807 static void 
808 psw_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\
874 or use just `set base' with no args to return to the ad-hoc default,\n\
875 which 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\
880 With `set pipe off', exceptions are reported with\n\
881 $pc pointing at the instruction after the faulting one.\n\
882 The 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\
894 Args 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\
898 With 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\
905 A communication register name as argument means describe only that register.\n\
906 An 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\
911 An argument means display that value's interpretation as a psw.");
912
913   add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
914 32-bit registers  $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
915 64-bit registers  $S0-7 $V0-7 $C0-63\n\
916 \n\
917 info threads        display info on stopped threads waiting to signal\n\
918 thread              display list of active threads\n\
919 thread N            select thread N (its registers, stack, memory, etc.)\n\
920 step, next, etc     step selected thread only\n\
921 1cont               continue selected thread only\n\
922 cont                continue all threads\n\
923 info comm-registers display contents of comm register(s) or a resource struct\n\
924 info psw            display processor status word $ps\n\
925 set base N          change integer radix used by `print' without a format\n\
926 set pipeline off    exceptions are precise, $pc points after the faulting insn\n\
927 set pipeline on     normal mode, $pc is somewhere ahead of faulting insn\n\
928 set parallel off    program runs on a single CPU\n\
929 set parallel fixed  all CPUs are assigned to the program\n\
930 set parallel on     normal mode, parallel execution on random available CPUs\n\
931 ",
932            &cmdlist);
933
934 }