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