* windres.c: add verbose option
[deliverable/binutils-gdb.git] / gdb / convex-tdep.c
CommitLineData
c906108c
SS
1/* Convex stuff for GDB.
2 Copyright (C) 1990, 1991, 1996 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "gdb_stat.h"
41#include <sys/mman.h>
42
43#include "gdbcmd.h"
44
b83266a0
SS
45CORE_ADDR
46convex_skip_prologue (pc)
47 CORE_ADDR pc;
48{
49 int op, ix;
50 op = read_memory_integer (pc, 2);
51 if ((op & 0xffc7) == 0x5ac0)
52 pc += 2;
53 else if (op == 0x1580)
54 pc += 4;
55 else if (op == 0x15c0)
56 pc += 6;
57 if ((read_memory_integer (pc, 2) & 0xfff8) == 0x7c40
58 && (read_memory_integer (pc + 2, 2) & 0xfff8) == 0x1240
59 && (read_memory_integer (pc + 8, 2) & 0xfff8) == 0x7c48)
60 pc += 10;
61 if (read_memory_integer (pc, 2) == 0x1240)
62 pc += 6;
63 for (;;)
64 {
65 op = read_memory_integer (pc, 2);
66 ix = (op >> 3) & 7;
67 if (ix != 6)
68 break;
69 if ((op & 0xfcc0) == 0x3000)
70 pc += 4;
71 else if ((op & 0xfcc0) == 0x3040)
72 pc += 6;
73 else if ((op & 0xfcc0) == 0x2800)
74 pc += 4;
75 else if ((op & 0xfcc0) == 0x2840)
76 pc += 6;
77 else
78 break;
79 }
80 return pc;
81}
82
83
c906108c
SS
84exec_file_command (filename, from_tty)
85 char *filename;
86 int from_tty;
87{
88 int val;
89 int n;
90 struct stat st_exec;
91
92 /* Eliminate all traces of old exec file.
93 Mark text segment as empty. */
94
95 if (execfile)
96 free (execfile);
97 execfile = 0;
98 data_start = 0;
99 data_end = 0;
100 text_start = 0;
101 text_end = 0;
102 exec_data_start = 0;
103 exec_data_end = 0;
104 if (execchan >= 0)
105 close (execchan);
106 execchan = -1;
107
108 n_exec = 0;
109
110 /* Now open and digest the file the user requested, if any. */
111
112 if (filename)
113 {
114 filename = tilde_expand (filename);
115 make_cleanup (free, filename);
116
117 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
118 &execfile);
119 if (execchan < 0)
120 perror_with_name (filename);
121
122 if (myread (execchan, &filehdr, sizeof filehdr) < 0)
123 perror_with_name (filename);
124
125 if (! IS_SOFF_MAGIC (filehdr.h_magic))
126 error ("%s: not an executable file.", filename);
127
128 if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)
129 perror_with_name (filename);
130
131 /* Read through the section headers.
132 For text, data, etc, record an entry in the exec file map.
133 Record text_start and text_end. */
134
135 lseek (execchan, (long) filehdr.h_scnptr, 0);
136
137 for (n = 0; n < filehdr.h_nscns; n++)
138 {
139 if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)
140 perror_with_name (filename);
141
142 if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
143 && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
144 {
145 exec_map[n_exec].mem_addr = scnhdr.s_vaddr;
146 exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
147 exec_map[n_exec].file_addr = scnhdr.s_scnptr;
148 exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;
149 n_exec++;
150
151 if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)
152 {
153 text_start = scnhdr.s_vaddr;
154 text_end = scnhdr.s_vaddr + scnhdr.s_size;
155 }
156 }
157 }
158
159 fstat (execchan, &st_exec);
160 exec_mtime = st_exec.st_mtime;
161
162 validate_files ();
163 }
164 else if (from_tty)
165 printf_filtered ("No executable file now.\n");
166
167 /* Tell display code (if any) about the changed file name. */
168 if (exec_file_display_hook)
169 (*exec_file_display_hook) (filename);
170}
171
172#if 0
173/* Read data from SOFF exec or core file.
174 Return 0 on success, EIO if address out of bounds. */
175
176int
177xfer_core_file (memaddr, myaddr, len)
178 CORE_ADDR memaddr;
179 char *myaddr;
180 int len;
181{
182 register int i;
183 register int n;
184 register int val;
185 int xferchan;
186 char **xferfile;
187 int fileptr;
188 int returnval = 0;
189
190 while (len > 0)
191 {
192 xferfile = 0;
193 xferchan = 0;
194
195 /* Determine which file the next bunch of addresses reside in,
196 and where in the file. Set the file's read/write pointer
197 to point at the proper place for the desired address
198 and set xferfile and xferchan for the correct file.
199 If desired address is nonexistent, leave them zero.
200 i is set to the number of bytes that can be handled
201 along with the next address. */
202
203 i = len;
204
205 for (n = 0; n < n_core; n++)
206 {
207 if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end
208 && (core_map[n].thread == -1
209 || core_map[n].thread == inferior_thread))
210 {
211 i = min (len, core_map[n].mem_end - memaddr);
212 fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;
213 if (core_map[n].file_addr)
214 {
215 xferfile = &corefile;
216 xferchan = corechan;
217 }
218 break;
219 }
220 else if (core_map[n].mem_addr >= memaddr
221 && core_map[n].mem_addr < memaddr + i)
222 i = core_map[n].mem_addr - memaddr;
223 }
224
225 if (!xferfile)
226 for (n = 0; n < n_exec; n++)
227 {
228 if (memaddr >= exec_map[n].mem_addr
229 && memaddr < exec_map[n].mem_end)
230 {
231 i = min (len, exec_map[n].mem_end - memaddr);
232 fileptr = exec_map[n].file_addr + memaddr
233 - exec_map[n].mem_addr;
234 if (exec_map[n].file_addr)
235 {
236 xferfile = &execfile;
237 xferchan = execchan;
238 }
239 break;
240 }
241 else if (exec_map[n].mem_addr >= memaddr
242 && exec_map[n].mem_addr < memaddr + i)
243 i = exec_map[n].mem_addr - memaddr;
244 }
245
246 /* Now we know which file to use.
247 Set up its pointer and transfer the data. */
248 if (xferfile)
249 {
250 if (*xferfile == 0)
251 if (xferfile == &execfile)
252 error ("No program file to examine.");
253 else
254 error ("No core dump file or running program to examine.");
255 val = lseek (xferchan, fileptr, 0);
256 if (val < 0)
257 perror_with_name (*xferfile);
258 val = myread (xferchan, myaddr, i);
259 if (val < 0)
260 perror_with_name (*xferfile);
261 }
262 /* If this address is for nonexistent memory,
263 read zeros if reading, or do nothing if writing. */
264 else
265 {
266 memset (myaddr, '\0', i);
267 returnval = EIO;
268 }
269
270 memaddr += i;
271 myaddr += i;
272 len -= i;
273 }
274 return returnval;
275}
276#endif
277
278/* Here from info files command to print an address map. */
279
280print_maps ()
281{
282 struct pmap ptrs[200];
283 int n;
284
285 /* ID strings for core and executable file sections */
286
287 static char *idstr[] =
288 {
289 "0", "text", "data", "tdata", "bss", "tbss",
290 "common", "ttext", "ctx", "tctx", "10", "11", "12",
291 };
292
293 for (n = 0; n < n_core; n++)
294 {
295 core_map[n].which = 0;
296 ptrs[n] = core_map[n];
297 }
298 for (n = 0; n < n_exec; n++)
299 {
300 exec_map[n].which = 1;
301 ptrs[n_core+n] = exec_map[n];
302 }
303
304 qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);
305
306 for (n = 0; n < n_core + n_exec; n++)
307 {
308 struct pmap *p = &ptrs[n];
309 if (n > 0)
310 {
311 if (p->mem_addr < ptrs[n-1].mem_end)
312 p->mem_addr = ptrs[n-1].mem_end;
313 if (p->mem_addr >= p->mem_end)
314 continue;
315 }
316 printf_filtered ("%08x .. %08x %-6s %s\n",
317 p->mem_addr, p->mem_end, idstr[p->type],
318 p->which ? execfile : corefile);
319 }
320}
321
322/* Compare routine to put file sections in order.
323 Sort into increasing order on address, and put core file sections
324 before exec file sections if both files contain the same addresses. */
325
326static ptr_cmp (a, b)
327 struct pmap *a, *b;
328{
329 if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;
330 return a->which - b->which;
331}
332\f
333/* Trapped internal variables are used to handle special registers.
334 A trapped i.v. calls a hook here every time it is dereferenced,
335 to provide a new value for the variable, and it calls a hook here
336 when a new value is assigned, to do something with the value.
337
338 The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
339 The communication registers are $cN, $CN (N in 0..63).
340 They not handled as regular registers because it's expensive to
341 read them, and their size varies, and they have too many names. */
342
343
344/* Return 1 if NAME is a trapped internal variable, else 0. */
345
346int
347is_trapped_internalvar (name)
348 char *name;
349{
350 if ((name[0] == 'c' || name[0] == 'C')
351 && name[1] >= '0' && name[1] <= '9'
352 && (name[2] == '\0'
353 || (name[2] >= '0' && name[2] <= '9'
354 && name[3] == '\0' && name[1] != '0'))
355 && atoi (&name[1]) < 64) return 1;
356
357 if ((name[0] == 'v' || name[0] == 'V')
358 && (((name[1] & -8) == '0' && name[2] == '\0')
359 || STREQ (name, "vl")
360 || STREQ (name, "vs")
361 || STREQ (name, "vm")))
362 return 1;
363 else return 0;
364}
365
366/* Return the value of trapped internal variable VAR */
367
368value
369value_of_trapped_internalvar (var)
370 struct internalvar *var;
371{
372 char *name = var->name;
373 value val;
374 struct type *type;
375 struct type *range_type;
376 long len = *read_vector_register (VL_REGNUM);
377 if (len <= 0 || len > 128) len = 128;
378
379 if (STREQ (name, "vl"))
380 {
381 val = value_from_longest (builtin_type_int,
382 (LONGEST) *read_vector_register_1 (VL_REGNUM));
383 }
384 else if (STREQ (name, "vs"))
385 {
386 val = value_from_longest (builtin_type_int,
387 (LONGEST) *read_vector_register_1 (VS_REGNUM));
388 }
389 else if (STREQ (name, "vm"))
390 {
391 long vm[4];
392 long i, *p;
393 memcpy (vm, read_vector_register_1 (VM_REGNUM), sizeof vm);
394 range_type =
395 create_range_type ((struct type *) NULL, builtin_type_int, 0, len - 1);
396 type =
397 create_array_type ((struct type *) NULL, builtin_type_int, range_type);
398 val = allocate_value (type);
399 p = (long *) VALUE_CONTENTS (val);
400 for (i = 0; i < len; i++)
401 *p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));
402 }
403 else if (name[0] == 'V')
404 {
405 range_type =
406 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
407 type =
408 create_array_type ((struct type *) NULL, builtin_type_long_long,
409 range_type);
410 val = allocate_value (type);
411 memcpy (VALUE_CONTENTS (val),
412 read_vector_register_1 (name[1] - '0'),
413 TYPE_LENGTH (type));
414 }
415 else if (name[0] == 'v')
416 {
417 long *p1, *p2;
418 range_type =
419 create_range_type ((struct type *) NULL, builtin_type_int 0, len - 1);
420 type =
421 create_array_type ((struct type *) NULL, builtin_type_long,
422 range_type);
423 val = allocate_value (type);
424 p1 = read_vector_register_1 (name[1] - '0');
425 p2 = (long *) VALUE_CONTENTS (val);
426 while (--len >= 0) {p1++; *p2++ = *p1++;}
427 }
428
429 else if (name[0] == 'c')
430 val = value_from_longest (builtin_type_int,
431 read_comm_register (atoi (&name[1])));
432 else if (name[0] == 'C')
433 val = value_from_longest (builtin_type_long_long,
434 read_comm_register (atoi (&name[1])));
435
436 VALUE_LVAL (val) = lval_internalvar;
437 VALUE_INTERNALVAR (val) = var;
438 return val;
439}
440
441/* Handle a new value assigned to a trapped internal variable */
442
443void
444set_trapped_internalvar (var, val, bitpos, bitsize, offset)
445 struct internalvar *var;
446 value val;
447 int bitpos, bitsize, offset;
448{
449 char *name = var->name;
450 long long newval = value_as_long (val);
451
452 if (STREQ (name, "vl"))
453 write_vector_register (VL_REGNUM, 0, newval);
454 else if (STREQ (name, "vs"))
455 write_vector_register (VS_REGNUM, 0, newval);
456 else if (name[0] == 'c' || name[0] == 'C')
457 write_comm_register (atoi (&name[1]), newval);
458 else if (STREQ (name, "vm"))
459 error ("can't assign to $vm");
460 else
461 {
462 offset /= bitsize / 8;
463 write_vector_register (name[1] - '0', offset, newval);
464 }
465}
466
467/* Print an integer value when no format was specified. gdb normally
468 prints these values in decimal, but the the leading 0x80000000 of
469 pointers produces intolerable 10-digit negative numbers.
470 If it looks like an address, print it in hex instead. */
471
472decout (stream, type, val)
473 GDB_FILE *stream;
474 struct type *type;
475 LONGEST val;
476{
477 long lv = val;
478
479 switch (output_radix)
480 {
481 case 0:
482 if ((lv == val || (unsigned) lv == val)
483 && ((lv & 0xf0000000) == 0x80000000
484 || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))
485 {
486 print_longest (stream, "x", 0, val);
487 return;
488 }
489
490 case 10:
491 print_longest (stream, TYPE_UNSIGNED (type) ? "u" : "d", 0, val);
492 return;
493
494 case 8:
495 print_longest (stream, "o", 0, val);
496 return;
497
498 case 16:
499 print_longest (stream, "x", 0, val);
500 return;
501 }
502}
503
504/* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
505 This command is mostly obsolete now that the print command allows
506 formats to apply to aggregates, but is still handy occasionally. */
507
508static void
509set_base_command (arg)
510 char *arg;
511{
512 int new_radix;
513
514 if (!arg)
515 output_radix = 0;
516 else
517 {
518 new_radix = atoi (arg);
519 if (new_radix != 10 && new_radix != 16 && new_radix != 8)
520 error ("base must be 8, 10 or 16, or null");
521 else output_radix = new_radix;
522 }
523}
524
525/* Turn pipelining on or off in the inferior. */
526
527static void
528set_pipelining_command (arg)
529 char *arg;
530{
531 if (!arg)
532 {
533 sequential = !sequential;
534 printf_filtered ("%s\n", sequential ? "off" : "on");
535 }
536 else if (STREQ (arg, "on"))
537 sequential = 0;
538 else if (STREQ (arg, "off"))
539 sequential = 1;
540 else error ("valid args are `on', to allow instructions to overlap, or\n\
541`off', to prevent it and thereby pinpoint exceptions.");
542}
543
544/* Enable, disable, or force parallel execution in the inferior. */
545
546static void
547set_parallel_command (arg)
548 char *arg;
549{
550 struct rlimit rl;
551 int prevparallel = parallel;
552
553 if (!strncmp (arg, "fixed", strlen (arg)))
554 parallel = 2;
555 else if (STREQ (arg, "on"))
556 parallel = 1;
557 else if (STREQ (arg, "off"))
558 parallel = 0;
559 else error ("valid args are `on', to allow multiple threads, or\n\
560`fixed', to force multiple threads, or\n\
561`off', to run with one thread only.");
562
563 if ((prevparallel == 0) != (parallel == 0) && inferior_pid)
564 printf_filtered ("will take effect at next run.\n");
565
566 getrlimit (RLIMIT_CONCUR, &rl);
567 rl.rlim_cur = parallel ? rl.rlim_max : 1;
568 setrlimit (RLIMIT_CONCUR, &rl);
569
570 if (inferior_pid)
571 set_fixed_scheduling (inferior_pid, parallel == 2);
572}
573
574/* Add a new name for an existing command. */
575
576static void
577alias_command (arg)
578 char *arg;
579{
580 static char *aliaserr = "usage is `alias NEW OLD', no args allowed";
581 char *newname = arg;
582 struct cmd_list_element *new, *old;
583
584 if (!arg)
585 error_no_arg ("newname oldname");
586
587 new = lookup_cmd (&arg, cmdlist, "", -1);
588 if (new && !strncmp (newname, new->name, strlen (new->name)))
589 {
590 newname = new->name;
591 if (!(*arg == '-'
592 || (*arg >= 'a' && *arg <= 'z')
593 || (*arg >= 'A' && *arg <= 'Z')
594 || (*arg >= '0' && *arg <= '9')))
595 error (aliaserr);
596 }
597 else
598 {
599 arg = newname;
600 while (*arg == '-'
601 || (*arg >= 'a' && *arg <= 'z')
602 || (*arg >= 'A' && *arg <= 'Z')
603 || (*arg >= '0' && *arg <= '9'))
604 arg++;
605 if (*arg != ' ' && *arg != '\t')
606 error (aliaserr);
607 *arg = '\0';
608 arg++;
609 }
610
611 old = lookup_cmd (&arg, cmdlist, "", 0);
612
613 if (*arg != '\0')
614 error (aliaserr);
615
616 if (new && !strncmp (newname, new->name, strlen (new->name)))
617 {
618 char *tem;
619 if (new->class == (int) class_user || new->class == (int) class_alias)
620 tem = "Redefine command \"%s\"? ";
621 else
622 tem = "Really redefine built-in command \"%s\"? ";
623 if (!query (tem, new->name))
624 error ("Command \"%s\" not redefined.", new->name);
625 }
626
627 add_com (newname, class_alias, old->function, old->doc);
628}
629
630
631
632/* Print the current thread number, and any threads with signals in the
633 queue. */
634
635thread_info ()
636{
637 struct threadpid *p;
638
639 if (have_inferior_p ())
640 {
641 ps.pi_buffer = (char *) &comm_registers;
642 ps.pi_nbytes = sizeof comm_registers;
643 ps.pi_offset = 0;
644 ps.pi_thread = inferior_thread;
645 ioctl (inferior_fd, PIXRDCREGS, &ps);
646 }
647
648 /* FIXME: stop_signal is from target.h but stop_sigcode is a
649 convex-specific thing. */
650 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
651 inferior_thread, stop_signal, stop_sigcode,
652 subsig_name (stop_signal, stop_sigcode));
653
654 for (p = signal_stack; p->pid; p--)
655 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
656 p->thread, p->signo, p->subsig,
657 subsig_name (p->signo, p->subsig));
658
659 if (iscrlbit (comm_registers.crctl.lbits.cc, 64+13))
660 printf_filtered ("New thread start pc %#x\n",
661 (long) (comm_registers.crreg.pcpsw >> 32));
662}
663
664/* Return string describing a signal.subcode number */
665
666static char *
667subsig_name (signo, subcode)
668 int signo, subcode;
669{
670 static char *subsig4[] = {
671 "error exit", "privileged instruction", "unknown",
672 "unknown", "undefined opcode",
673 0};
674 static char *subsig5[] = {0,
675 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
676 "join trap", "idle trap", "last thread", "wfork trap",
677 "process breakpoint", "trap instruction",
678 0};
679 static char *subsig8[] = {0,
680 "int overflow", "int divide check", "float overflow",
681 "float divide check", "float underflow", "reserved operand",
682 "sqrt error", "exp error", "ln error", "sin error", "cos error",
683 0};
684 static char *subsig10[] = {0,
685 "invalid inward ring address", "invalid outward ring call",
686 "invalid inward ring return", "invalid syscall gate",
687 "invalid rtn frame length", "invalid comm reg address",
688 "invalid trap gate",
689 0};
690 static char *subsig11[] = {0,
691 "read access denied", "write access denied", "execute access denied",
692 "segment descriptor fault", "page table fault", "data reference fault",
693 "i/o access denied", "levt pte invalid",
694 0};
695
696 static char **subsig_list[] =
697 {0, 0, 0, 0, subsig4, subsig5, 0, 0, subsig8, 0, subsig10, subsig11, 0};
698
699 int i;
700 char *p;
701
702 if ((p = strsignal (signo)) == NULL)
703 p = "unknown";
704 if (signo >= (sizeof subsig_list / sizeof *subsig_list)
705 || !subsig_list[signo])
706 return p;
707 for (i = 1; subsig_list[signo][i]; i++)
708 if (i == subcode)
709 return subsig_list[signo][subcode];
710 return p;
711}
712
713
714/* Print a compact display of thread status, essentially x/i $pc
715 for all active threads. */
716
717static void
718threadstat ()
719{
720 int t;
721
722 for (t = 0; t < n_threads; t++)
723 if (thread_state[t] == PI_TALIVE)
724 {
725 printf_filtered ("%d%c %08x%c %d.%d ", t,
726 (t == inferior_thread ? '*' : ' '), thread_pc[t],
727 (thread_is_in_kernel[t] ? '#' : ' '),
728 thread_signal[t], thread_sigcode[t]);
729 print_insn (thread_pc[t], stdout);
730 printf_filtered ("\n");
731 }
732}
733
734/* Change the current thread to ARG. */
735
736set_thread_command (arg)
737 char *arg;
738{
739 int thread;
740
741 if (!arg)
742 {
743 threadstat ();
744 return;
745 }
746
747 thread = parse_and_eval_address (arg);
748
749 if (thread < 0 || thread > n_threads || thread_state[thread] != PI_TALIVE)
750 error ("no such thread.");
751
752 select_thread (thread);
753
754 stop_pc = read_pc ();
755 flush_cached_frames ();
756 select_frame (get_current_frame (), 0);
757 print_stack_frame (selected_frame, selected_frame_level, -1);
758}
759
760/* Here on CONT command; gdb's dispatch address is changed to come here.
761 Set global variable ALL_CONTINUE to tell resume() that it should
762 start up all threads, and that a thread switch will not blow gdb's
763 mind. */
764
765static void
766convex_cont_command (proc_count_exp, from_tty)
767 char *proc_count_exp;
768 int from_tty;
769{
770 all_continue = 1;
771 cont_command (proc_count_exp, from_tty);
772}
773
774/* Here on 1CONT command. Resume only the current thread. */
775
776one_cont_command (proc_count_exp, from_tty)
777 char *proc_count_exp;
778 int from_tty;
779{
780 cont_command (proc_count_exp, from_tty);
781}
782
783/* Print the contents and lock bits of all communication registers,
784 or just register ARG if ARG is a communication register,
785 or the 3-word resource structure in memory at address ARG. */
786
787comm_registers_info (arg)
788 char *arg;
789{
790 int i, regnum;
791
792 if (arg)
793 {
794 if (sscanf (arg, "$c%d", &regnum) == 1) {
795 ;
796 } else if (sscanf (arg, "$C%d", &regnum) == 1) {
797 ;
798 } else {
799 regnum = parse_and_eval_address (arg);
800 if (regnum > 0)
801 regnum &= ~0x8000;
802 }
803
804 if (regnum >= 64)
805 error ("%s: invalid register name.", arg);
806
807 /* if we got a (user) address, examine the resource struct there */
808
809 if (regnum < 0)
810 {
811 static int buf[3];
812 read_memory (regnum, buf, sizeof buf);
813 printf_filtered ("%08x %08x%08x%s\n", regnum, buf[1], buf[2],
814 buf[0] & 0xff ? " locked" : "");
815 return;
816 }
817 }
818
819 ps.pi_buffer = (char *) &comm_registers;
820 ps.pi_nbytes = sizeof comm_registers;
821 ps.pi_offset = 0;
822 ps.pi_thread = inferior_thread;
823 ioctl (inferior_fd, PIXRDCREGS, &ps);
824
825 for (i = 0; i < 64; i++)
826 if (!arg || i == regnum)
827 printf_filtered ("%2d 0x8%03x %016llx%s\n", i, i,
828 comm_registers.crreg.r4[i],
829 (iscrlbit (comm_registers.crctl.lbits.cc, i)
830 ? " locked" : ""));
831}
832
833/* Print the psw */
834
835static void
836psw_info (arg)
837 char *arg;
838{
839 struct pswbit
840 {
841 int bit;
842 int pos;
843 char *text;
844 };
845
846 static struct pswbit pswbit[] =
847 {
848 { 0x80000000, -1, "A carry" },
849 { 0x40000000, -1, "A integer overflow" },
850 { 0x20000000, -1, "A zero divide" },
851 { 0x10000000, -1, "Integer overflow enable" },
852 { 0x08000000, -1, "Trace" },
853 { 0x06000000, 25, "Frame length" },
854 { 0x01000000, -1, "Sequential" },
855 { 0x00800000, -1, "S carry" },
856 { 0x00400000, -1, "S integer overflow" },
857 { 0x00200000, -1, "S zero divide" },
858 { 0x00100000, -1, "Zero divide enable" },
859 { 0x00080000, -1, "Floating underflow" },
860 { 0x00040000, -1, "Floating overflow" },
861 { 0x00020000, -1, "Floating reserved operand" },
862 { 0x00010000, -1, "Floating zero divide" },
863 { 0x00008000, -1, "Floating error enable" },
864 { 0x00004000, -1, "Floating underflow enable" },
865 { 0x00002000, -1, "IEEE" },
866 { 0x00001000, -1, "Sequential stores" },
867 { 0x00000800, -1, "Intrinsic error" },
868 { 0x00000400, -1, "Intrinsic error enable" },
869 { 0x00000200, -1, "Trace thread creates" },
870 { 0x00000100, -1, "Thread init trap" },
871 { 0x000000e0, 5, "Reserved" },
872 { 0x0000001f, 0, "Intrinsic error code" },
873 {0, 0, 0},
874 };
875
876 long psw;
877 struct pswbit *p;
878
879 if (arg)
880 psw = parse_and_eval_address (arg);
881 else
882 psw = read_register (PS_REGNUM);
883
884 for (p = pswbit; p->bit; p++)
885 {
886 if (p->pos < 0)
887 printf_filtered ("%08x %s %s\n", p->bit,
888 (psw & p->bit) ? "yes" : "no ", p->text);
889 else
890 printf_filtered ("%08x %3d %s\n", p->bit,
891 (psw & p->bit) >> p->pos, p->text);
892 }
893}
894\f
895#include "symtab.h"
896
897/* reg (fmt_field, inst_field) --
898 the {first,second,third} operand of instruction as fmt_field = [ijk]
899 gets the value of the field from the [ijk] position of the instruction */
900
901#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
902
903/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
904
905#define lit(i) op[fmt->i]
906
907/* aj[j] -- name for A register j */
908
909#define aj ((char (*)[3])(op[A]))
910\f
911union inst {
912 struct {
913 unsigned : 7;
914 unsigned i : 3;
915 unsigned j : 3;
916 unsigned k : 3;
917 unsigned : 16;
918 unsigned : 32;
919 } f0;
920 struct {
921 unsigned : 8;
922 unsigned indir : 1;
923 unsigned len : 1;
924 unsigned j : 3;
925 unsigned k : 3;
926 unsigned : 16;
927 unsigned : 32;
928 } f1;
929 unsigned char byte[8];
930 unsigned short half[4];
931 char signed_byte[8];
932 short signed_half[4];
933};
934
935struct opform {
936 int mask; /* opcode mask */
937 int shift; /* opcode align */
938 struct formstr *formstr[3]; /* ST, E0, E1 */
939};
940
941struct formstr {
942 unsigned lop:8, rop:5; /* opcode */
943 unsigned fmt:5; /* inst format */
944 unsigned i:5, j:5, k:2; /* operand formats */
945};
946
947#include "opcode/convex.h"
948
949CONST unsigned char formdecode [] = {
950 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
951 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
952 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
953 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
954 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
955 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
956 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
957 4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,
958 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
959 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
960 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
961 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
962 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
963 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
964 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
965 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
966};
967
968CONST struct opform opdecode[] = {
969 0x7e00, 9, format0, e0_format0, e1_format0,
970 0x3f00, 8, format1, e0_format1, e1_format1,
971 0x1fc0, 6, format2, e0_format2, e1_format2,
972 0x0fc0, 6, format3, e0_format3, e1_format3,
973 0x0700, 8, format4, e0_format4, e1_format4,
974 0x03c0, 6, format5, e0_format5, e1_format5,
975 0x01f8, 3, format6, e0_format6, e1_format6,
976 0x00f8, 3, format7, e0_format7, e1_format7,
977 0x0000, 0, formatx, formatx, formatx,
978 0x0f80, 7, formatx, formatx, formatx,
979 0x0f80, 7, formatx, formatx, formatx,
980};
981\f
982/* Print the instruction at address MEMADDR in debugged memory,
983 on STREAM. Returns length of the instruction, in bytes. */
984
985int
986convex_print_insn (memaddr, stream)
987 CORE_ADDR memaddr;
988 FILE *stream;
989{
990 union inst inst;
991 struct formstr *fmt;
992 register int format, op1, pfx;
993 int l;
994
995 read_memory (memaddr, &inst, sizeof inst);
996
997 /* Remove and note prefix, if present */
998
999 pfx = inst.half[0];
1000 if ((pfx & 0xfff0) == 0x7ef0)
1001 {
1002 pfx = ((pfx >> 3) & 1) + 1;
1003 *(long long *) &inst = *(long long *) &inst.half[1];
1004 }
1005 else pfx = 0;
1006
1007 /* Split opcode into format.op1 and look up in appropriate table */
1008
1009 format = formdecode[inst.byte[0]];
1010 op1 = (inst.half[0] & opdecode[format].mask) >> opdecode[format].shift;
1011 if (format == 9)
1012 {
1013 if (pfx)
1014 fmt = formatx;
1015 else if (inst.f1.j == 0)
1016 fmt = &format1a[op1];
1017 else if (inst.f1.j == 1)
1018 fmt = &format1b[op1];
1019 else
1020 fmt = formatx;
1021 }
1022 else
1023 fmt = &opdecode[format].formstr[pfx][op1];
1024
1025 /* Print it */
1026
1027 if (fmt->fmt == xxx)
1028 {
1029 /* noninstruction */
1030 fprintf (stream, "0x%04x", pfx ? pfx : inst.half[0]);
1031 return 2;
1032 }
1033
1034 if (pfx)
1035 pfx = 2;
1036
1037 fprintf (stream, "%s%s%s", lop[fmt->lop], rop[fmt->rop],
1038 &" "[strlen(lop[fmt->lop]) + strlen(rop[fmt->rop])]);
1039
1040 switch (fmt->fmt)
1041 {
1042 case rrr: /* three register */
1043 fprintf (stream, "%s,%s,%s", reg(i,i), reg(j,j), reg(k,k));
1044 return pfx + 2;
1045
1046 case rr: /* two register */
1047 fprintf (stream, "%s,%s", reg(i,j), reg(j,k));
1048 return pfx + 2;
1049
1050 case rxr: /* two register, reversed i and j fields */
1051 fprintf (stream, "%s,%s", reg(i,k), reg(j,j));
1052 return pfx + 2;
1053
1054 case r: /* one register */
1055 fprintf (stream, "%s", reg(i,k));
1056 return pfx + 2;
1057
1058 case nops: /* no operands */
1059 return pfx + 2;
1060
1061 case nr: /* short immediate, one register */
1062 fprintf (stream, "#%d,%s", inst.f0.j, reg(i,k));
1063 return pfx + 2;
1064
1065 case pcrel: /* pc relative */
1066 print_address (memaddr + 2 * inst.signed_byte[1], stream);
1067 return pfx + 2;
1068
1069 case lr: /* literal, one register */
1070 fprintf (stream, "%s,%s", lit(i), reg(j,k));
1071 return pfx + 2;
1072
1073 case rxl: /* one register, literal */
1074 fprintf (stream, "%s,%s", reg(i,k), lit(j));
1075 return pfx + 2;
1076
1077 case rlr: /* register, literal, register */
1078 fprintf (stream, "%s,%s,%s", reg(i,j), lit(j), reg(k,k));
1079 return pfx + 2;
1080
1081 case rrl: /* register, register, literal */
1082 fprintf (stream, "%s,%s,%s", reg(i,j), reg(j,k), lit(k));
1083 return pfx + 2;
1084
1085 case iml: /* immediate, literal */
1086 if (inst.f1.len)
1087 {
1088 fprintf (stream, "#%#x,%s",
1089 (inst.signed_half[1] << 16) + inst.half[2], lit(i));
1090 return pfx + 6;
1091 }
1092 else
1093 {
1094 fprintf (stream, "#%d,%s", inst.signed_half[1], lit(i));
1095 return pfx + 4;
1096 }
1097
1098 case imr: /* immediate, register */
1099 if (inst.f1.len)
1100 {
1101 fprintf (stream, "#%#x,%s",
1102 (inst.signed_half[1] << 16) + inst.half[2], reg(i,k));
1103 return pfx + 6;
1104 }
1105 else
1106 {
1107 fprintf (stream, "#%d,%s", inst.signed_half[1], reg(i,k));
1108 return pfx + 4;
1109 }
1110
1111 case a1r: /* memory, register */
1112 l = print_effa (inst, stream);
1113 fprintf (stream, ",%s", reg(i,k));
1114 return pfx + l;
1115
1116 case a1l: /* memory, literal */
1117 l = print_effa (inst, stream);
1118 fprintf (stream, ",%s", lit(i));
1119 return pfx + l;
1120
1121 case a2r: /* register, memory */
1122 fprintf (stream, "%s,", reg(i,k));
1123 return pfx + print_effa (inst, stream);
1124
1125 case a2l: /* literal, memory */
1126 fprintf (stream, "%s,", lit(i));
1127 return pfx + print_effa (inst, stream);
1128
1129 case a3: /* memory */
1130 return pfx + print_effa (inst, stream);
1131
1132 case a4: /* system call */
1133 l = 29; goto a4a5;
1134 case a5: /* trap */
1135 l = 27;
1136 a4a5:
1137 if (inst.f1.len)
1138 {
1139 unsigned int m = (inst.signed_half[1] << 16) + inst.half[2];
1140 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
1141 return pfx + 6;
1142 }
1143 else
1144 {
1145 unsigned int m = inst.signed_half[1];
1146 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
1147 return pfx + 4;
1148 }
1149 }
1150}
1151
1152
1153/* print effective address @nnn(aj), return instruction length */
1154
1155int print_effa (inst, stream)
1156 union inst inst;
1157 FILE *stream;
1158{
1159 int n, l;
1160
1161 if (inst.f1.len)
1162 {
1163 n = (inst.signed_half[1] << 16) + inst.half[2];
1164 l = 6;
1165 }
1166 else
1167 {
1168 n = inst.signed_half[1];
1169 l = 4;
1170 }
1171
1172 if (inst.f1.indir)
1173 printf ("@");
1174
1175 if (!inst.f1.j)
1176 {
1177 print_address (n, stream);
1178 return l;
1179 }
1180
1181 fprintf (stream, (n & 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",
1182 n, aj[inst.f1.j]);
1183
1184 return l;
1185}
1186
1187\f
1188void
1189_initialize_convex_dep ()
1190{
1191 add_com ("alias", class_support, alias_command,
1192 "Add a new name for an existing command.");
1193
1194 add_cmd ("base", class_vars, set_base_command,
1195 "Change the integer output radix to 8, 10 or 16\n\
1196or use just `set base' with no args to return to the ad-hoc default,\n\
1197which is 16 for integers that look like addresses, 10 otherwise.",
1198 &setlist);
1199
1200 add_cmd ("pipeline", class_run, set_pipelining_command,
1201 "Enable or disable overlapped execution of instructions.\n\
1202With `set pipe off', exceptions are reported with\n\
1203$pc pointing at the instruction after the faulting one.\n\
1204The default is `set pipe on', which runs faster.",
1205 &setlist);
1206
1207 add_cmd ("parallel", class_run, set_parallel_command,
1208 "Enable or disable multi-threaded execution of parallel code.\n\
1209`set parallel off' means run the program on a single CPU.\n\
1210`set parallel fixed' means run the program with all CPUs assigned to it.\n\
1211`set parallel on' means run the program on any CPUs that are available.",
1212 &setlist);
1213
1214 add_com ("1cont", class_run, one_cont_command,
1215 "Continue the program, activating only the current thread.\n\
1216Args are the same as the `cont' command.");
1217
1218 add_com ("thread", class_run, set_thread_command,
1219 "Change the current thread, the one under scrutiny and control.\n\
1220With no arg, show the active threads, the current one marked with *.");
1221
1222 add_info ("threads", thread_info,
1223 "List status of active threads.");
1224
1225 add_info ("comm-registers", comm_registers_info,
1226 "List communication registers and their contents.\n\
1227A communication register name as argument means describe only that register.\n\
1228An address as argument means describe the resource structure at that address.\n\
1229`Locked' means that the register has been sent to but not yet received from.");
1230
1231 add_info ("psw", psw_info,
1232 "Display $ps, the processor status word, bit by bit.\n\
1233An argument means display that value's interpretation as a psw.");
1234
1235 add_cmd ("convex", no_class, 0, "Convex-specific commands.\n\
123632-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
123764-bit registers $S0-7 $V0-7 $C0-63\n\
1238\n\
1239info threads display info on stopped threads waiting to signal\n\
1240thread display list of active threads\n\
1241thread N select thread N (its registers, stack, memory, etc.)\n\
1242step, next, etc step selected thread only\n\
12431cont continue selected thread only\n\
1244cont continue all threads\n\
1245info comm-registers display contents of comm register(s) or a resource struct\n\
1246info psw display processor status word $ps\n\
1247set base N change integer radix used by `print' without a format\n\
1248set pipeline off exceptions are precise, $pc points after the faulting insn\n\
1249set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
1250set parallel off program runs on a single CPU\n\
1251set parallel fixed all CPUs are assigned to the program\n\
1252set parallel on normal mode, parallel execution on random available CPUs\n\
1253",
1254 &cmdlist);
1255
1256}
This page took 0.067848 seconds and 4 git commands to generate.