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