]> Git Repo - binutils.git/blob - gdb/convex-tdep.c
Change wierd to weird
[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           memset (myaddr, '\0', 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           || STREQ (name, "vl")
320           || STREQ (name, "vs") 
321           || STREQ (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   struct type *range_type;
336   long len = *read_vector_register (VL_REGNUM);
337   if (len <= 0 || len > 128) len = 128;
338
339   if (STREQ (name, "vl"))
340     {
341       val = value_from_longest (builtin_type_int,
342                              (LONGEST) *read_vector_register_1 (VL_REGNUM));
343     }
344   else if (STREQ (name, "vs"))
345     {
346       val = value_from_longest (builtin_type_int,
347                              (LONGEST) *read_vector_register_1 (VS_REGNUM));
348     }
349   else if (STREQ (name, "vm"))
350     {
351       long vm[4];
352       long i, *p;
353       memcpy (vm, read_vector_register_1 (VM_REGNUM), sizeof vm);
354       range_type =
355         create_range_type ((struct type *) NULL, builtin_type_int, 0, len - 1);
356       type =
357         create_array_type ((struct type *) NULL, builtin_type_int, range_type);
358       val = allocate_value (type);
359       p = (long *) VALUE_CONTENTS (val);
360       for (i = 0; i < len; i++) 
361         *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
362     }
363   else if (name[0] == 'V')
364     {
365       range_type =
366         create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
367       type =
368         create_array_type ((struct type *) NULL, builtin_type_long_long,
369                            range_type);
370       val = allocate_value (type);
371       memcpy (VALUE_CONTENTS (val),
372              read_vector_register_1 (name[1] - '0'),
373              TYPE_LENGTH (type));
374     }
375   else if (name[0] == 'v')
376     {
377       long *p1, *p2;
378       range_type =
379         create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
380       type =
381         create_array_type ((struct type *) NULL, builtin_type_long,
382                            range_type);
383       val = allocate_value (type);
384       p1 = read_vector_register_1 (name[1] - '0');
385       p2 = (long *) VALUE_CONTENTS (val);
386       while (--len >= 0) {p1++; *p2++ = *p1++;}
387     }
388
389   else if (name[0] == 'c')
390     val = value_from_longest (builtin_type_int,
391                            read_comm_register (atoi (&name[1])));
392   else if (name[0] == 'C')
393     val = value_from_longest (builtin_type_long_long,
394                            read_comm_register (atoi (&name[1])));
395
396   VALUE_LVAL (val) = lval_internalvar;
397   VALUE_INTERNALVAR (val) = var;
398   return val;
399 }
400
401 /* Handle a new value assigned to a trapped internal variable */
402
403 void
404 set_trapped_internalvar (var, val, bitpos, bitsize, offset)
405      struct internalvar *var;
406      value val;
407      int bitpos, bitsize, offset;
408
409   char *name = var->name;
410   long long newval = value_as_long (val);
411
412   if (STREQ (name, "vl")) 
413     write_vector_register (VL_REGNUM, 0, newval);
414   else if (STREQ (name, "vs"))
415     write_vector_register (VS_REGNUM, 0, newval);
416   else if (name[0] == 'c' || name[0] == 'C')
417     write_comm_register (atoi (&name[1]), newval);
418   else if (STREQ (name, "vm"))
419     error ("can't assign to $vm");
420   else
421     {
422       offset /= bitsize / 8;
423       write_vector_register (name[1] - '0', offset, newval);
424     }
425 }
426
427 /* Print an integer value when no format was specified.  gdb normally
428    prints these values in decimal, but the the leading 0x80000000 of
429    pointers produces intolerable 10-digit negative numbers.
430    If it looks like an address, print it in hex instead.  */
431
432 decout (stream, type, val)
433      FILE *stream;
434      struct type *type;
435      LONGEST val;
436 {
437   long lv = val;
438
439   switch (output_radix)
440     {
441     case 0:
442       if ((lv == val || (unsigned) lv == val)
443           && ((lv & 0xf0000000) == 0x80000000
444               || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
445         {
446           fprintf_filtered (stream, "%#x", lv);
447           return;
448         }
449
450     case 10:
451       fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
452       return;
453
454     case 8:
455       if (TYPE_LENGTH (type) <= sizeof lv)
456         fprintf_filtered (stream, "%#o", lv);
457       else
458         fprintf_filtered (stream, "%#llo", val);
459       return;
460
461     case 16:
462       if (TYPE_LENGTH (type) <= sizeof lv)
463         fprintf_filtered (stream, "%#x", lv);
464       else
465         fprintf_filtered (stream, "%#llx", val);
466       return;
467     }
468 }
469
470 /* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
471    This command is mostly obsolete now that the print command allows
472    formats to apply to aggregates, but is still handy occasionally.  */
473
474 static void
475 set_base_command (arg)
476     char *arg;
477 {
478   int new_radix;
479
480   if (!arg)
481     output_radix = 0;
482   else
483     {
484       new_radix = atoi (arg);
485       if (new_radix != 10 && new_radix != 16 && new_radix != 8) 
486         error ("base must be 8, 10 or 16, or null");
487       else output_radix = new_radix;
488     }
489 }
490
491 /* Turn pipelining on or off in the inferior. */
492
493 static void
494 set_pipelining_command (arg)
495     char *arg;
496 {
497   if (!arg)
498     {
499       sequential = !sequential;
500       printf_filtered ("%s\n", sequential ? "off" : "on");
501     }
502   else if (STREQ (arg, "on"))
503     sequential = 0;
504   else if (STREQ (arg, "off"))
505     sequential = 1;
506   else error ("valid args are `on', to allow instructions to overlap, or\n\
507 `off', to prevent it and thereby pinpoint exceptions.");
508 }
509
510 /* Enable, disable, or force parallel execution in the inferior.  */
511
512 static void
513 set_parallel_command (arg)
514      char *arg;
515 {
516   struct rlimit rl;
517   int prevparallel = parallel;
518
519   if (!strncmp (arg, "fixed", strlen (arg)))
520     parallel = 2;  
521   else if (STREQ (arg, "on"))
522     parallel = 1;
523   else if (STREQ (arg, "off"))
524     parallel = 0;
525   else error ("valid args are `on', to allow multiple threads, or\n\
526 `fixed', to force multiple threads, or\n\
527 `off', to run with one thread only.");
528
529   if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
530     printf_filtered ("will take effect at next run.\n");
531
532   getrlimit (RLIMIT_CONCUR, &rl);
533   rl.rlim_cur = parallel ? rl.rlim_max : 1;
534   setrlimit (RLIMIT_CONCUR, &rl);
535
536   if (inferior_pid)
537     set_fixed_scheduling (inferior_pid, parallel == 2);
538 }
539
540 /* Add a new name for an existing command.  */
541
542 static void 
543 alias_command (arg)
544     char *arg;
545 {
546     static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
547     char *newname = arg;
548     struct cmd_list_element *new, *old;
549
550     if (!arg)
551       error_no_arg ("newname oldname");
552         
553     new = lookup_cmd (&arg, cmdlist, "", -1);
554     if (new && !strncmp (newname, new->name, strlen (new->name)))
555       {
556         newname = new->name;
557         if (!(*arg == '-' 
558               || (*arg >= 'a' && *arg <= 'z')
559               || (*arg >= 'A' && *arg <= 'Z')
560               || (*arg >= '0' && *arg <= '9')))
561           error (aliaserr);
562       }
563     else
564       {
565         arg = newname;
566         while (*arg == '-' 
567                || (*arg >= 'a' && *arg <= 'z')
568                || (*arg >= 'A' && *arg <= 'Z')
569                || (*arg >= '0' && *arg <= '9'))
570           arg++;
571         if (*arg != ' ' && *arg != '\t')
572           error (aliaserr);
573         *arg = '\0';
574         arg++;
575       }
576
577     old = lookup_cmd (&arg, cmdlist, "", 0);
578
579     if (*arg != '\0')
580       error (aliaserr);
581
582     if (new && !strncmp (newname, new->name, strlen (new->name)))
583       {
584         char *tem;
585         if (new->class == (int) class_user || new->class == (int) class_alias)
586           tem = "Redefine command \"%s\"? ";
587         else
588           tem = "Really redefine built-in command \"%s\"? ";
589         if (!query (tem, new->name))
590           error ("Command \"%s\" not redefined.", new->name);
591       }
592
593     add_com (newname, class_alias, old->function, old->doc);
594 }
595
596
597
598 /* Print the current thread number, and any threads with signals in the
599    queue.  */
600
601 thread_info ()
602 {
603   struct threadpid *p;
604
605   if (have_inferior_p ())
606     {
607       ps.pi_buffer = (char *) &comm_registers;
608       ps.pi_nbytes = sizeof comm_registers;
609       ps.pi_offset = 0;
610       ps.pi_thread = inferior_thread;
611       ioctl (inferior_fd, PIXRDCREGS, &ps);
612     }
613
614   printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
615                    inferior_thread, stop_signal, stop_sigcode,
616                    subsig_name (stop_signal, stop_sigcode));
617   
618   for (p = signal_stack; p->pid; p--)
619     printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
620                      p->thread, p->signo, p->subsig,
621                      subsig_name (p->signo, p->subsig));
622                 
623   if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
624     printf_filtered ("New thread start pc %#x\n",
625                      (long) (comm_registers.crreg.pcpsw >> 32));
626 }
627
628 /* Return string describing a signal.subcode number */
629
630 static char *
631 subsig_name (signo, subcode)
632      int signo, subcode;
633 {
634   static char *subsig4[] = {
635     "error exit", "privileged instruction", "unknown",
636     "unknown", "undefined opcode",
637     0};
638   static char *subsig5[] = {0,
639     "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
640     "join trap", "idle trap", "last thread", "wfork trap",
641     "process breakpoint", "trap instruction",
642     0};
643   static char *subsig8[] = {0,
644     "int overflow", "int divide check", "float overflow",
645     "float divide check", "float underflow", "reserved operand",
646     "sqrt error", "exp error", "ln error", "sin error", "cos error",
647     0};
648   static char *subsig10[] = {0,
649     "invalid inward ring address", "invalid outward ring call",
650     "invalid inward ring return", "invalid syscall gate",
651     "invalid rtn frame length", "invalid comm reg address",
652     "invalid trap gate",
653     0};
654   static char *subsig11[] = {0,
655     "read access denied", "write access denied", "execute access denied",
656     "segment descriptor fault", "page table fault", "data reference fault",
657     "i/o access denied", "levt pte invalid",
658     0};
659
660   static char **subsig_list[] = 
661     {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
662
663   int i;
664   char *p;
665
666   if ((p = strsignal (signo)) == NULL)
667     p = "unknown";
668   if (signo >= (sizeof subsig_list / sizeof *subsig_list)
669       || !subsig_list[signo])
670     return p;
671   for (i = 1; subsig_list[signo][i]; i++)
672     if (i == subcode)
673       return subsig_list[signo][subcode];
674   return p;
675 }
676
677
678 /* Print a compact display of thread status, essentially x/i $pc
679    for all active threads.  */
680
681 static void
682 threadstat ()
683 {
684   int t;
685
686   for (t = 0; t < n_threads; t++)
687     if (thread_state[t] == PI_TALIVE)
688       {
689         printf_filtered ("%d%c %08x%c %d.%d ", t,
690                          (t == inferior_thread ? '*' : ' '), thread_pc[t],
691                          (thread_is_in_kernel[t] ? '#' : ' '),
692                          thread_signal[t], thread_sigcode[t]);
693         print_insn (thread_pc[t], stdout);
694         printf_filtered ("\n");
695       }
696 }
697
698 /* Change the current thread to ARG.  */
699
700 set_thread_command (arg)
701      char *arg;
702 {
703     int thread;
704
705     if (!arg)
706       {
707         threadstat ();
708         return;
709       }
710
711     thread = parse_and_eval_address (arg);
712
713     if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
714       error ("no such thread.");
715
716     select_thread (thread);
717
718     stop_pc = read_pc ();
719     flush_cached_frames ();
720     set_current_frame (create_new_frame (read_register (FP_REGNUM),
721                                          read_pc ()));
722     select_frame (get_current_frame (), 0);
723     print_stack_frame (selected_frame, selected_frame_level, -1);
724 }
725
726 /* Here on CONT command; gdb's dispatch address is changed to come here.
727    Set global variable ALL_CONTINUE to tell resume() that it should
728    start up all threads, and that a thread switch will not blow gdb's
729    mind.  */
730
731 static void
732 convex_cont_command (proc_count_exp, from_tty)
733      char *proc_count_exp;
734      int from_tty;
735 {
736   all_continue = 1;
737   cont_command (proc_count_exp, from_tty);
738 }
739
740 /* Here on 1CONT command.  Resume only the current thread.  */
741
742 one_cont_command (proc_count_exp, from_tty)
743      char *proc_count_exp;
744      int from_tty;
745 {
746   cont_command (proc_count_exp, from_tty);
747 }
748
749 /* Print the contents and lock bits of all communication registers,
750    or just register ARG if ARG is a communication register,
751    or the 3-word resource structure in memory at address ARG.  */
752
753 comm_registers_info (arg)
754     char *arg;
755 {
756   int i, regnum;
757
758   if (arg)
759     {
760              if (sscanf (arg, "$c%d", &regnum) == 1) {
761         ;
762       } else if (sscanf (arg, "$C%d", &regnum) == 1) {
763         ;
764       } else {
765         regnum = parse_and_eval_address (arg);
766         if (regnum > 0)
767           regnum &= ~0x8000;
768       }
769
770       if (regnum >= 64)
771         error ("%s: invalid register name.", arg);
772
773       /* if we got a (user) address, examine the resource struct there */
774
775       if (regnum < 0)
776         {
777           static int buf[3];
778           read_memory (regnum, buf, sizeof buf);
779           printf_filtered ("%08x  %08x%08x%s\n", regnum, buf[1], buf[2],
780                            buf[0] & 0xff ? " locked" : "");
781           return;
782         }
783     }
784
785   ps.pi_buffer = (char *) &comm_registers;
786   ps.pi_nbytes = sizeof comm_registers;
787   ps.pi_offset = 0;
788   ps.pi_thread = inferior_thread;
789   ioctl (inferior_fd, PIXRDCREGS, &ps);
790
791   for (i = 0; i < 64; i++)
792     if (!arg || i == regnum)
793       printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
794                        comm_registers.crreg.r4[i],
795                        (iscrlbit (comm_registers.crctl.lbits.cc, i)
796                         ? " locked" : ""));
797 }
798
799 /* Print the psw */
800
801 static void 
802 psw_info (arg)
803     char *arg;
804 {
805   struct pswbit
806     {
807       int bit;
808       int pos;
809       char *text;
810     };
811
812   static struct pswbit pswbit[] =
813     {
814       { 0x80000000, -1, "A carry" }, 
815       { 0x40000000, -1, "A integer overflow" }, 
816       { 0x20000000, -1, "A zero divide" }, 
817       { 0x10000000, -1, "Integer overflow enable" }, 
818       { 0x08000000, -1, "Trace" }, 
819       { 0x06000000, 25, "Frame length" }, 
820       { 0x01000000, -1, "Sequential" }, 
821       { 0x00800000, -1, "S carry" }, 
822       { 0x00400000, -1, "S integer overflow" }, 
823       { 0x00200000, -1, "S zero divide" }, 
824       { 0x00100000, -1, "Zero divide enable" }, 
825       { 0x00080000, -1, "Floating underflow" }, 
826       { 0x00040000, -1, "Floating overflow" }, 
827       { 0x00020000, -1, "Floating reserved operand" }, 
828       { 0x00010000, -1, "Floating zero divide" }, 
829       { 0x00008000, -1, "Floating error enable" }, 
830       { 0x00004000, -1, "Floating underflow enable" }, 
831       { 0x00002000, -1, "IEEE" }, 
832       { 0x00001000, -1, "Sequential stores" }, 
833       { 0x00000800, -1, "Intrinsic error" }, 
834       { 0x00000400, -1, "Intrinsic error enable" }, 
835       { 0x00000200, -1, "Trace thread creates" }, 
836       { 0x00000100, -1, "Thread init trap" }, 
837       { 0x000000e0,  5, "Reserved" },
838       { 0x0000001f,  0, "Intrinsic error code" },
839       {0, 0, 0},
840     };
841
842   long psw;
843   struct pswbit *p;
844
845   if (arg)
846     psw = parse_and_eval_address (arg);
847   else
848     psw = read_register (PS_REGNUM);
849
850   for (p = pswbit; p->bit; p++)
851     {
852       if (p->pos < 0)
853         printf_filtered ("%08x  %s  %s\n", p->bit,
854                          (psw & p->bit) ? "yes" : "no ", p->text);
855       else
856         printf_filtered ("%08x %3d   %s\n", p->bit,
857                          (psw & p->bit) >> p->pos, p->text);
858     }
859 }
860 \f
861 _initialize_convex_dep ()
862 {
863   add_com ("alias", class_support, alias_command,
864            "Add a new name for an existing command.");
865
866   add_cmd ("base", class_vars, set_base_command,
867            "Change the integer output radix to 8, 10 or 16\n\
868 or use just `set base' with no args to return to the ad-hoc default,\n\
869 which is 16 for integers that look like addresses, 10 otherwise.",
870            &setlist);
871
872   add_cmd ("pipeline", class_run, set_pipelining_command,
873            "Enable or disable overlapped execution of instructions.\n\
874 With `set pipe off', exceptions are reported with\n\
875 $pc pointing at the instruction after the faulting one.\n\
876 The default is `set pipe on', which runs faster.",
877            &setlist);
878
879   add_cmd ("parallel", class_run, set_parallel_command,
880            "Enable or disable multi-threaded execution of parallel code.\n\
881 `set parallel off' means run the program on a single CPU.\n\
882 `set parallel fixed' means run the program with all CPUs assigned to it.\n\
883 `set parallel on' means run the program on any CPUs that are available.",
884            &setlist);
885
886   add_com ("1cont", class_run, one_cont_command,
887            "Continue the program, activating only the current thread.\n\
888 Args are the same as the `cont' command.");
889
890   add_com ("thread", class_run, set_thread_command,
891            "Change the current thread, the one under scrutiny and control.\n\
892 With no arg, show the active threads, the current one marked with *.");
893
894   add_info ("threads", thread_info,
895             "List status of active threads.");
896
897   add_info ("comm-registers", comm_registers_info,
898             "List communication registers and their contents.\n\
899 A communication register name as argument means describe only that register.\n\
900 An address as argument means describe the resource structure at that address.\n\
901 `Locked' means that the register has been sent to but not yet received from.");
902
903   add_info ("psw", psw_info, 
904             "Display $ps, the processor status word, bit by bit.\n\
905 An argument means display that value's interpretation as a psw.");
906
907   add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
908 32-bit registers  $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
909 64-bit registers  $S0-7 $V0-7 $C0-63\n\
910 \n\
911 info threads        display info on stopped threads waiting to signal\n\
912 thread              display list of active threads\n\
913 thread N            select thread N (its registers, stack, memory, etc.)\n\
914 step, next, etc     step selected thread only\n\
915 1cont               continue selected thread only\n\
916 cont                continue all threads\n\
917 info comm-registers display contents of comm register(s) or a resource struct\n\
918 info psw            display processor status word $ps\n\
919 set base N          change integer radix used by `print' without a format\n\
920 set pipeline off    exceptions are precise, $pc points after the faulting insn\n\
921 set pipeline on     normal mode, $pc is somewhere ahead of faulting insn\n\
922 set parallel off    program runs on a single CPU\n\
923 set parallel fixed  all CPUs are assigned to the program\n\
924 set parallel on     normal mode, parallel execution on random available CPUs\n\
925 ",
926            &cmdlist);
927
928 }
This page took 0.077938 seconds and 4 git commands to generate.