* Makefile.in (depend): Fix dependancy generation so that it does
[external/binutils.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 "defs.h"
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
45 exec_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
136 int
137 xfer_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
240 print_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
286 static 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
306 int
307 is_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
328 value
329 value_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     {
340       val = value_from_longest (builtin_type_int,
341                              (LONGEST) *read_vector_register_1 (VL_REGNUM));
342     }
343   else if (!strcmp (name, "vs"))
344     {
345       val = value_from_longest (builtin_type_int,
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')
377     val = value_from_longest (builtin_type_int,
378                            read_comm_register (atoi (&name[1])));
379   else if (name[0] == 'C')
380     val = value_from_longest (builtin_type_long_long,
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
391 static struct type *
392 vector_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
406 void
407 set_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
435 decout (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
477 static void
478 set_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
496 static void
497 set_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
515 static void
516 set_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
545 static void 
546 alias_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
604 thread_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
633 static char *
634 subsig_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;
667   char *p = signo < NSIG ? sys_siglist[signo] : "unknown";
668
669   if (signo >= (sizeof subsig_list / sizeof *subsig_list)
670       || !subsig_list[signo])
671     return p;
672   for (i = 1; subsig_list[signo][i]; i++)
673     if (i == subcode)
674       return subsig_list[signo][subcode];
675   return p;
676 }
677
678
679 /* Print a compact display of thread status, essentially x/i $pc
680    for all active threads.  */
681
682 static void
683 threadstat ()
684 {
685   int t;
686
687   for (t = 0; t < n_threads; t++)
688     if (thread_state[t] == PI_TALIVE)
689       {
690         printf_filtered ("%d%c %08x%c %d.%d ", t,
691                          (t == inferior_thread ? '*' : ' '), thread_pc[t],
692                          (thread_is_in_kernel[t] ? '#' : ' '),
693                          thread_signal[t], thread_sigcode[t]);
694         print_insn (thread_pc[t], stdout);
695         printf_filtered ("\n");
696       }
697 }
698
699 /* Change the current thread to ARG.  */
700
701 set_thread_command (arg)
702      char *arg;
703 {
704     int thread;
705
706     if (!arg)
707       {
708         threadstat ();
709         return;
710       }
711
712     thread = parse_and_eval_address (arg);
713
714     if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
715       error ("no such thread.");
716
717     select_thread (thread);
718
719     stop_pc = read_pc ();
720     flush_cached_frames ();
721     set_current_frame (create_new_frame (read_register (FP_REGNUM),
722                                          read_pc ()));
723     select_frame (get_current_frame (), 0);
724     print_stack_frame (selected_frame, selected_frame_level, -1);
725 }
726
727 /* Here on CONT command; gdb's dispatch address is changed to come here.
728    Set global variable ALL_CONTINUE to tell resume() that it should
729    start up all threads, and that a thread switch will not blow gdb's
730    mind.  */
731
732 static void
733 convex_cont_command (proc_count_exp, from_tty)
734      char *proc_count_exp;
735      int from_tty;
736 {
737   all_continue = 1;
738   cont_command (proc_count_exp, from_tty);
739 }
740
741 /* Here on 1CONT command.  Resume only the current thread.  */
742
743 one_cont_command (proc_count_exp, from_tty)
744      char *proc_count_exp;
745      int from_tty;
746 {
747   cont_command (proc_count_exp, from_tty);
748 }
749
750 /* Print the contents and lock bits of all communication registers,
751    or just register ARG if ARG is a communication register,
752    or the 3-word resource structure in memory at address ARG.  */
753
754 comm_registers_info (arg)
755     char *arg;
756 {
757   int i, regnum;
758
759   if (arg)
760     {
761              if (sscanf (arg, "$c%d", &regnum) == 1) {
762         ;
763       } else if (sscanf (arg, "$C%d", &regnum) == 1) {
764         ;
765       } else {
766         regnum = parse_and_eval_address (arg);
767         if (regnum > 0)
768           regnum &= ~0x8000;
769       }
770
771       if (regnum >= 64)
772         error ("%s: invalid register name.", arg);
773
774       /* if we got a (user) address, examine the resource struct there */
775
776       if (regnum < 0)
777         {
778           static int buf[3];
779           read_memory (regnum, buf, sizeof buf);
780           printf_filtered ("%08x  %08x%08x%s\n", regnum, buf[1], buf[2],
781                            buf[0] & 0xff ? " locked" : "");
782           return;
783         }
784     }
785
786   ps.pi_buffer = (char *) &comm_registers;
787   ps.pi_nbytes = sizeof comm_registers;
788   ps.pi_offset = 0;
789   ps.pi_thread = inferior_thread;
790   ioctl (inferior_fd, PIXRDCREGS, &ps);
791
792   for (i = 0; i < 64; i++)
793     if (!arg || i == regnum)
794       printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
795                        comm_registers.crreg.r4[i],
796                        (iscrlbit (comm_registers.crctl.lbits.cc, i)
797                         ? " locked" : ""));
798 }
799
800 /* Print the psw */
801
802 static void 
803 psw_info (arg)
804     char *arg;
805 {
806   struct pswbit
807     {
808       int bit;
809       int pos;
810       char *text;
811     };
812
813   static struct pswbit pswbit[] =
814     {
815       { 0x80000000, -1, "A carry" }, 
816       { 0x40000000, -1, "A integer overflow" }, 
817       { 0x20000000, -1, "A zero divide" }, 
818       { 0x10000000, -1, "Integer overflow enable" }, 
819       { 0x08000000, -1, "Trace" }, 
820       { 0x06000000, 25, "Frame length" }, 
821       { 0x01000000, -1, "Sequential" }, 
822       { 0x00800000, -1, "S carry" }, 
823       { 0x00400000, -1, "S integer overflow" }, 
824       { 0x00200000, -1, "S zero divide" }, 
825       { 0x00100000, -1, "Zero divide enable" }, 
826       { 0x00080000, -1, "Floating underflow" }, 
827       { 0x00040000, -1, "Floating overflow" }, 
828       { 0x00020000, -1, "Floating reserved operand" }, 
829       { 0x00010000, -1, "Floating zero divide" }, 
830       { 0x00008000, -1, "Floating error enable" }, 
831       { 0x00004000, -1, "Floating underflow enable" }, 
832       { 0x00002000, -1, "IEEE" }, 
833       { 0x00001000, -1, "Sequential stores" }, 
834       { 0x00000800, -1, "Intrinsic error" }, 
835       { 0x00000400, -1, "Intrinsic error enable" }, 
836       { 0x00000200, -1, "Trace thread creates" }, 
837       { 0x00000100, -1, "Thread init trap" }, 
838       { 0x000000e0,  5, "Reserved" },
839       { 0x0000001f,  0, "Intrinsic error code" },
840       {0, 0, 0},
841     };
842
843   long psw;
844   struct pswbit *p;
845
846   if (arg)
847     psw = parse_and_eval_address (arg);
848   else
849     psw = read_register (PS_REGNUM);
850
851   for (p = pswbit; p->bit; p++)
852     {
853       if (p->pos < 0)
854         printf_filtered ("%08x  %s  %s\n", p->bit,
855                          (psw & p->bit) ? "yes" : "no ", p->text);
856       else
857         printf_filtered ("%08x %3d   %s\n", p->bit,
858                          (psw & p->bit) >> p->pos, p->text);
859     }
860 }
861 \f
862 _initialize_convex_dep ()
863 {
864   add_com ("alias", class_support, alias_command,
865            "Add a new name for an existing command.");
866
867   add_cmd ("base", class_vars, set_base_command,
868            "Change the integer output radix to 8, 10 or 16\n\
869 or use just `set base' with no args to return to the ad-hoc default,\n\
870 which is 16 for integers that look like addresses, 10 otherwise.",
871            &setlist);
872
873   add_cmd ("pipeline", class_run, set_pipelining_command,
874            "Enable or disable overlapped execution of instructions.\n\
875 With `set pipe off', exceptions are reported with\n\
876 $pc pointing at the instruction after the faulting one.\n\
877 The default is `set pipe on', which runs faster.",
878            &setlist);
879
880   add_cmd ("parallel", class_run, set_parallel_command,
881            "Enable or disable multi-threaded execution of parallel code.\n\
882 `set parallel off' means run the program on a single CPU.\n\
883 `set parallel fixed' means run the program with all CPUs assigned to it.\n\
884 `set parallel on' means run the program on any CPUs that are available.",
885            &setlist);
886
887   add_com ("1cont", class_run, one_cont_command,
888            "Continue the program, activating only the current thread.\n\
889 Args are the same as the `cont' command.");
890
891   add_com ("thread", class_run, set_thread_command,
892            "Change the current thread, the one under scrutiny and control.\n\
893 With no arg, show the active threads, the current one marked with *.");
894
895   add_info ("threads", thread_info,
896             "List status of active threads.");
897
898   add_info ("comm-registers", comm_registers_info,
899             "List communication registers and their contents.\n\
900 A communication register name as argument means describe only that register.\n\
901 An address as argument means describe the resource structure at that address.\n\
902 `Locked' means that the register has been sent to but not yet received from.");
903
904   add_info ("psw", psw_info, 
905             "Display $ps, the processor status word, bit by bit.\n\
906 An argument means display that value's interpretation as a psw.");
907
908   add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
909 32-bit registers  $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
910 64-bit registers  $S0-7 $V0-7 $C0-63\n\
911 \n\
912 info threads        display info on stopped threads waiting to signal\n\
913 thread              display list of active threads\n\
914 thread N            select thread N (its registers, stack, memory, etc.)\n\
915 step, next, etc     step selected thread only\n\
916 1cont               continue selected thread only\n\
917 cont                continue all threads\n\
918 info comm-registers display contents of comm register(s) or a resource struct\n\
919 info psw            display processor status word $ps\n\
920 set base N          change integer radix used by `print' without a format\n\
921 set pipeline off    exceptions are precise, $pc points after the faulting insn\n\
922 set pipeline on     normal mode, $pc is somewhere ahead of faulting insn\n\
923 set parallel off    program runs on a single CPU\n\
924 set parallel fixed  all CPUs are assigned to the program\n\
925 set parallel on     normal mode, parallel execution on random available CPUs\n\
926 ",
927            &cmdlist);
928
929 }