1 /* Convex stuff for GDB.
2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
32 #include <sys/param.h>
35 #include <sys/ioctl.h>
36 #include <sys/pcntl.h>
37 #include <sys/thread.h>
45 exec_file_command (filename
, from_tty
)
53 /* Eliminate all traces of old exec file.
54 Mark text segment as empty. */
71 /* Now open and digest the file the user requested, if any. */
75 filename
= tilde_expand (filename
);
76 make_cleanup (free
, filename
);
78 execchan
= openp (getenv ("PATH"), 1, filename
, O_RDONLY
, 0,
81 perror_with_name (filename
);
83 if (myread (execchan
, &filehdr
, sizeof filehdr
) < 0)
84 perror_with_name (filename
);
86 if (! IS_SOFF_MAGIC (filehdr
.h_magic
))
87 error ("%s: not an executable file.", filename
);
89 if (myread (execchan
, &opthdr
, filehdr
.h_opthdr
) <= 0)
90 perror_with_name (filename
);
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. */
96 lseek (execchan
, (long) filehdr
.h_scnptr
, 0);
98 for (n
= 0; n
< filehdr
.h_nscns
; n
++)
100 if (myread (execchan
, &scnhdr
, sizeof scnhdr
) < 0)
101 perror_with_name (filename
);
103 if ((scnhdr
.s_flags
& S_TYPMASK
) >= S_TEXT
104 && (scnhdr
.s_flags
& S_TYPMASK
) <= S_COMON
)
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
;
112 if ((scnhdr
.s_flags
& S_TYPMASK
) == S_TEXT
)
114 text_start
= scnhdr
.s_vaddr
;
115 text_end
= scnhdr
.s_vaddr
+ scnhdr
.s_size
;
120 fstat (execchan
, &st_exec
);
121 exec_mtime
= st_exec
.st_mtime
;
126 printf_filtered ("No exec file now.\n");
128 /* Tell display code (if any) about the changed file name. */
129 if (exec_file_display_hook
)
130 (*exec_file_display_hook
) (filename
);
134 /* Read data from SOFF exec or core file.
135 Return 0 on success, EIO if address out of bounds. */
138 xfer_core_file (memaddr
, myaddr
, len
)
156 /* Determine which file the next bunch of addresses reside in,
157 and where in the file. Set the file's read/write pointer
158 to point at the proper place for the desired address
159 and set xferfile and xferchan for the correct file.
160 If desired address is nonexistent, leave them zero.
161 i is set to the number of bytes that can be handled
162 along with the next address. */
166 for (n
= 0; n
< n_core
; n
++)
168 if (memaddr
>= core_map
[n
].mem_addr
&& memaddr
< core_map
[n
].mem_end
169 && (core_map
[n
].thread
== -1
170 || core_map
[n
].thread
== inferior_thread
))
172 i
= min (len
, core_map
[n
].mem_end
- memaddr
);
173 fileptr
= core_map
[n
].file_addr
+ memaddr
- core_map
[n
].mem_addr
;
174 if (core_map
[n
].file_addr
)
176 xferfile
= &corefile
;
181 else if (core_map
[n
].mem_addr
>= memaddr
182 && core_map
[n
].mem_addr
< memaddr
+ i
)
183 i
= core_map
[n
].mem_addr
- memaddr
;
187 for (n
= 0; n
< n_exec
; n
++)
189 if (memaddr
>= exec_map
[n
].mem_addr
190 && memaddr
< exec_map
[n
].mem_end
)
192 i
= min (len
, exec_map
[n
].mem_end
- memaddr
);
193 fileptr
= exec_map
[n
].file_addr
+ memaddr
194 - exec_map
[n
].mem_addr
;
195 if (exec_map
[n
].file_addr
)
197 xferfile
= &execfile
;
202 else if (exec_map
[n
].mem_addr
>= memaddr
203 && exec_map
[n
].mem_addr
< memaddr
+ i
)
204 i
= exec_map
[n
].mem_addr
- memaddr
;
207 /* Now we know which file to use.
208 Set up its pointer and transfer the data. */
212 if (xferfile
== &execfile
)
213 error ("No program file to examine.");
215 error ("No core dump file or running program to examine.");
216 val
= lseek (xferchan
, fileptr
, 0);
218 perror_with_name (*xferfile
);
219 val
= myread (xferchan
, myaddr
, i
);
221 perror_with_name (*xferfile
);
223 /* If this address is for nonexistent memory,
224 read zeros if reading, or do nothing if writing. */
227 memset (myaddr
, '\0', i
);
239 /* Here from info files command to print an address map. */
243 struct pmap ptrs
[200];
246 /* ID strings for core and executable file sections */
248 static char *idstr
[] =
250 "0", "text", "data", "tdata", "bss", "tbss",
251 "common", "ttext", "ctx", "tctx", "10", "11", "12",
254 for (n
= 0; n
< n_core
; n
++)
256 core_map
[n
].which
= 0;
257 ptrs
[n
] = core_map
[n
];
259 for (n
= 0; n
< n_exec
; n
++)
261 exec_map
[n
].which
= 1;
262 ptrs
[n_core
+n
] = exec_map
[n
];
265 qsort (ptrs
, n_core
+ n_exec
, sizeof *ptrs
, ptr_cmp
);
267 for (n
= 0; n
< n_core
+ n_exec
; n
++)
269 struct pmap
*p
= &ptrs
[n
];
272 if (p
->mem_addr
< ptrs
[n
-1].mem_end
)
273 p
->mem_addr
= ptrs
[n
-1].mem_end
;
274 if (p
->mem_addr
>= p
->mem_end
)
277 printf_filtered ("%08x .. %08x %-6s %s\n",
278 p
->mem_addr
, p
->mem_end
, idstr
[p
->type
],
279 p
->which
? execfile
: corefile
);
283 /* Compare routine to put file sections in order.
284 Sort into increasing order on address, and put core file sections
285 before exec file sections if both files contain the same addresses. */
287 static ptr_cmp (a
, b
)
290 if (a
->mem_addr
!= b
->mem_addr
) return a
->mem_addr
- b
->mem_addr
;
291 return a
->which
- b
->which
;
294 /* Trapped internal variables are used to handle special registers.
295 A trapped i.v. calls a hook here every time it is dereferenced,
296 to provide a new value for the variable, and it calls a hook here
297 when a new value is assigned, to do something with the value.
299 The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).
300 The communication registers are $cN, $CN (N in 0..63).
301 They not handled as regular registers because it's expensive to
302 read them, and their size varies, and they have too many names. */
305 /* Return 1 if NAME is a trapped internal variable, else 0. */
308 is_trapped_internalvar (name
)
311 if ((name
[0] == 'c' || name
[0] == 'C')
312 && name
[1] >= '0' && name
[1] <= '9'
314 || (name
[2] >= '0' && name
[2] <= '9'
315 && name
[3] == '\0' && name
[1] != '0'))
316 && atoi (&name
[1]) < 64) return 1;
318 if ((name
[0] == 'v' || name
[0] == 'V')
319 && (((name
[1] & -8) == '0' && name
[2] == '\0')
320 || STREQ (name
, "vl")
321 || STREQ (name
, "vs")
322 || STREQ (name
, "vm")))
327 /* Return the value of trapped internal variable VAR */
330 value_of_trapped_internalvar (var
)
331 struct internalvar
*var
;
333 char *name
= var
->name
;
336 struct type
*range_type
;
337 long len
= *read_vector_register (VL_REGNUM
);
338 if (len
<= 0 || len
> 128) len
= 128;
340 if (STREQ (name
, "vl"))
342 val
= value_from_longest (builtin_type_int
,
343 (LONGEST
) *read_vector_register_1 (VL_REGNUM
));
345 else if (STREQ (name
, "vs"))
347 val
= value_from_longest (builtin_type_int
,
348 (LONGEST
) *read_vector_register_1 (VS_REGNUM
));
350 else if (STREQ (name
, "vm"))
354 memcpy (vm
, read_vector_register_1 (VM_REGNUM
), sizeof vm
);
356 create_range_type ((struct type
*) NULL
, builtin_type_int
, 0, len
- 1);
358 create_array_type ((struct type
*) NULL
, builtin_type_int
, range_type
);
359 val
= allocate_value (type
);
360 p
= (long *) VALUE_CONTENTS (val
);
361 for (i
= 0; i
< len
; i
++)
362 *p
++ = !! (vm
[3 - (i
>> 5)] & (1 << (i
& 037)));
364 else if (name
[0] == 'V')
367 create_range_type ((struct type
*) NULL
, builtin_type_int
0, len
- 1);
369 create_array_type ((struct type
*) NULL
, builtin_type_long_long
,
371 val
= allocate_value (type
);
372 memcpy (VALUE_CONTENTS (val
),
373 read_vector_register_1 (name
[1] - '0'),
376 else if (name
[0] == 'v')
380 create_range_type ((struct type
*) NULL
, builtin_type_int
0, len
- 1);
382 create_array_type ((struct type
*) NULL
, builtin_type_long
,
384 val
= allocate_value (type
);
385 p1
= read_vector_register_1 (name
[1] - '0');
386 p2
= (long *) VALUE_CONTENTS (val
);
387 while (--len
>= 0) {p1
++; *p2
++ = *p1
++;}
390 else if (name
[0] == 'c')
391 val
= value_from_longest (builtin_type_int
,
392 read_comm_register (atoi (&name
[1])));
393 else if (name
[0] == 'C')
394 val
= value_from_longest (builtin_type_long_long
,
395 read_comm_register (atoi (&name
[1])));
397 VALUE_LVAL (val
) = lval_internalvar
;
398 VALUE_INTERNALVAR (val
) = var
;
402 /* Handle a new value assigned to a trapped internal variable */
405 set_trapped_internalvar (var
, val
, bitpos
, bitsize
, offset
)
406 struct internalvar
*var
;
408 int bitpos
, bitsize
, offset
;
410 char *name
= var
->name
;
411 long long newval
= value_as_long (val
);
413 if (STREQ (name
, "vl"))
414 write_vector_register (VL_REGNUM
, 0, newval
);
415 else if (STREQ (name
, "vs"))
416 write_vector_register (VS_REGNUM
, 0, newval
);
417 else if (name
[0] == 'c' || name
[0] == 'C')
418 write_comm_register (atoi (&name
[1]), newval
);
419 else if (STREQ (name
, "vm"))
420 error ("can't assign to $vm");
423 offset
/= bitsize
/ 8;
424 write_vector_register (name
[1] - '0', offset
, newval
);
428 /* Print an integer value when no format was specified. gdb normally
429 prints these values in decimal, but the the leading 0x80000000 of
430 pointers produces intolerable 10-digit negative numbers.
431 If it looks like an address, print it in hex instead. */
433 decout (stream
, type
, val
)
440 switch (output_radix
)
443 if ((lv
== val
|| (unsigned) lv
== val
)
444 && ((lv
& 0xf0000000) == 0x80000000
445 || ((lv
& 0xf0000000) == 0xf0000000 && lv
< STACK_END_ADDR
)))
447 fprintf_filtered (stream
, "%#x", lv
);
452 fprintf_filtered (stream
, TYPE_UNSIGNED (type
) ? "%llu" : "%lld", val
);
456 if (TYPE_LENGTH (type
) <= sizeof lv
)
457 fprintf_filtered (stream
, "%#o", lv
);
459 fprintf_filtered (stream
, "%#llo", val
);
463 if (TYPE_LENGTH (type
) <= sizeof lv
)
464 fprintf_filtered (stream
, "%#x", lv
);
466 fprintf_filtered (stream
, "%#llx", val
);
471 /* Change the default output radix to 10 or 16, or set it to 0 (heuristic).
472 This command is mostly obsolete now that the print command allows
473 formats to apply to aggregates, but is still handy occasionally. */
476 set_base_command (arg
)
485 new_radix
= atoi (arg
);
486 if (new_radix
!= 10 && new_radix
!= 16 && new_radix
!= 8)
487 error ("base must be 8, 10 or 16, or null");
488 else output_radix
= new_radix
;
492 /* Turn pipelining on or off in the inferior. */
495 set_pipelining_command (arg
)
500 sequential
= !sequential
;
501 printf_filtered ("%s\n", sequential
? "off" : "on");
503 else if (STREQ (arg
, "on"))
505 else if (STREQ (arg
, "off"))
507 else error ("valid args are `on', to allow instructions to overlap, or\n\
508 `off', to prevent it and thereby pinpoint exceptions.");
511 /* Enable, disable, or force parallel execution in the inferior. */
514 set_parallel_command (arg
)
518 int prevparallel
= parallel
;
520 if (!strncmp (arg
, "fixed", strlen (arg
)))
522 else if (STREQ (arg
, "on"))
524 else if (STREQ (arg
, "off"))
526 else error ("valid args are `on', to allow multiple threads, or\n\
527 `fixed', to force multiple threads, or\n\
528 `off', to run with one thread only.");
530 if ((prevparallel
== 0) != (parallel
== 0) && inferior_pid
)
531 printf_filtered ("will take effect at next run.\n");
533 getrlimit (RLIMIT_CONCUR
, &rl
);
534 rl
.rlim_cur
= parallel
? rl
.rlim_max
: 1;
535 setrlimit (RLIMIT_CONCUR
, &rl
);
538 set_fixed_scheduling (inferior_pid
, parallel
== 2);
541 /* Add a new name for an existing command. */
547 static char *aliaserr
= "usage is `alias NEW OLD', no args allowed";
549 struct cmd_list_element
*new, *old
;
552 error_no_arg ("newname oldname");
554 new = lookup_cmd (&arg
, cmdlist
, "", -1);
555 if (new && !strncmp (newname
, new->name
, strlen (new->name
)))
559 || (*arg
>= 'a' && *arg
<= 'z')
560 || (*arg
>= 'A' && *arg
<= 'Z')
561 || (*arg
>= '0' && *arg
<= '9')))
568 || (*arg
>= 'a' && *arg
<= 'z')
569 || (*arg
>= 'A' && *arg
<= 'Z')
570 || (*arg
>= '0' && *arg
<= '9'))
572 if (*arg
!= ' ' && *arg
!= '\t')
578 old
= lookup_cmd (&arg
, cmdlist
, "", 0);
583 if (new && !strncmp (newname
, new->name
, strlen (new->name
)))
586 if (new->class == (int) class_user
|| new->class == (int) class_alias
)
587 tem
= "Redefine command \"%s\"? ";
589 tem
= "Really redefine built-in command \"%s\"? ";
590 if (!query (tem
, new->name
))
591 error ("Command \"%s\" not redefined.", new->name
);
594 add_com (newname
, class_alias
, old
->function
, old
->doc
);
599 /* Print the current thread number, and any threads with signals in the
606 if (have_inferior_p ())
608 ps
.pi_buffer
= (char *) &comm_registers
;
609 ps
.pi_nbytes
= sizeof comm_registers
;
611 ps
.pi_thread
= inferior_thread
;
612 ioctl (inferior_fd
, PIXRDCREGS
, &ps
);
615 /* FIXME: stop_signal is from target.h but stop_sigcode is a
616 convex-specific thing. */
617 printf_filtered ("Current thread %d stopped with signal %d.%d (%s).\n",
618 inferior_thread
, stop_signal
, stop_sigcode
,
619 subsig_name (stop_signal
, stop_sigcode
));
621 for (p
= signal_stack
; p
->pid
; p
--)
622 printf_filtered ("Thread %d stopped with signal %d.%d (%s).\n",
623 p
->thread
, p
->signo
, p
->subsig
,
624 subsig_name (p
->signo
, p
->subsig
));
626 if (iscrlbit (comm_registers
.crctl
.lbits
.cc
, 64+13))
627 printf_filtered ("New thread start pc %#x\n",
628 (long) (comm_registers
.crreg
.pcpsw
>> 32));
631 /* Return string describing a signal.subcode number */
634 subsig_name (signo
, subcode
)
637 static char *subsig4
[] = {
638 "error exit", "privileged instruction", "unknown",
639 "unknown", "undefined opcode",
641 static char *subsig5
[] = {0,
642 "breakpoint", "single step", "fork trap", "exec trap", "pfork trap",
643 "join trap", "idle trap", "last thread", "wfork trap",
644 "process breakpoint", "trap instruction",
646 static char *subsig8
[] = {0,
647 "int overflow", "int divide check", "float overflow",
648 "float divide check", "float underflow", "reserved operand",
649 "sqrt error", "exp error", "ln error", "sin error", "cos error",
651 static char *subsig10
[] = {0,
652 "invalid inward ring address", "invalid outward ring call",
653 "invalid inward ring return", "invalid syscall gate",
654 "invalid rtn frame length", "invalid comm reg address",
657 static char *subsig11
[] = {0,
658 "read access denied", "write access denied", "execute access denied",
659 "segment descriptor fault", "page table fault", "data reference fault",
660 "i/o access denied", "levt pte invalid",
663 static char **subsig_list
[] =
664 {0, 0, 0, 0, subsig4
, subsig5
, 0, 0, subsig8
, 0, subsig10
, subsig11
, 0};
669 if ((p
= strsignal (signo
)) == NULL
)
671 if (signo
>= (sizeof subsig_list
/ sizeof *subsig_list
)
672 || !subsig_list
[signo
])
674 for (i
= 1; subsig_list
[signo
][i
]; i
++)
676 return subsig_list
[signo
][subcode
];
681 /* Print a compact display of thread status, essentially x/i $pc
682 for all active threads. */
689 for (t
= 0; t
< n_threads
; t
++)
690 if (thread_state
[t
] == PI_TALIVE
)
692 printf_filtered ("%d%c %08x%c %d.%d ", t
,
693 (t
== inferior_thread
? '*' : ' '), thread_pc
[t
],
694 (thread_is_in_kernel
[t
] ? '#' : ' '),
695 thread_signal
[t
], thread_sigcode
[t
]);
696 print_insn (thread_pc
[t
], stdout
);
697 printf_filtered ("\n");
701 /* Change the current thread to ARG. */
703 set_thread_command (arg
)
714 thread
= parse_and_eval_address (arg
);
716 if (thread
< 0 || thread
> n_threads
|| thread_state
[thread
] != PI_TALIVE
)
717 error ("no such thread.");
719 select_thread (thread
);
721 stop_pc
= read_pc ();
722 flush_cached_frames ();
723 select_frame (get_current_frame (), 0);
724 print_stack_frame (selected_frame
, selected_frame_level
, -1);
727 /* Here on CONT command; gdb's dispatch address is changed to come here.
728 Set global variable ALL_CONTINUE to tell resume() that it should
729 start up all threads, and that a thread switch will not blow gdb's
733 convex_cont_command (proc_count_exp
, from_tty
)
734 char *proc_count_exp
;
738 cont_command (proc_count_exp
, from_tty
);
741 /* Here on 1CONT command. Resume only the current thread. */
743 one_cont_command (proc_count_exp
, from_tty
)
744 char *proc_count_exp
;
747 cont_command (proc_count_exp
, from_tty
);
750 /* Print the contents and lock bits of all communication registers,
751 or just register ARG if ARG is a communication register,
752 or the 3-word resource structure in memory at address ARG. */
754 comm_registers_info (arg
)
761 if (sscanf (arg
, "$c%d", ®num
) == 1) {
763 } else if (sscanf (arg
, "$C%d", ®num
) == 1) {
766 regnum
= parse_and_eval_address (arg
);
772 error ("%s: invalid register name.", arg
);
774 /* if we got a (user) address, examine the resource struct there */
779 read_memory (regnum
, buf
, sizeof buf
);
780 printf_filtered ("%08x %08x%08x%s\n", regnum
, buf
[1], buf
[2],
781 buf
[0] & 0xff ? " locked" : "");
786 ps
.pi_buffer
= (char *) &comm_registers
;
787 ps
.pi_nbytes
= sizeof comm_registers
;
789 ps
.pi_thread
= inferior_thread
;
790 ioctl (inferior_fd
, PIXRDCREGS
, &ps
);
792 for (i
= 0; i
< 64; i
++)
793 if (!arg
|| i
== regnum
)
794 printf_filtered ("%2d 0x8%03x %016llx%s\n", i
, i
,
795 comm_registers
.crreg
.r4
[i
],
796 (iscrlbit (comm_registers
.crctl
.lbits
.cc
, i
)
813 static struct pswbit pswbit
[] =
815 { 0x80000000, -1, "A carry" },
816 { 0x40000000, -1, "A integer overflow" },
817 { 0x20000000, -1, "A zero divide" },
818 { 0x10000000, -1, "Integer overflow enable" },
819 { 0x08000000, -1, "Trace" },
820 { 0x06000000, 25, "Frame length" },
821 { 0x01000000, -1, "Sequential" },
822 { 0x00800000, -1, "S carry" },
823 { 0x00400000, -1, "S integer overflow" },
824 { 0x00200000, -1, "S zero divide" },
825 { 0x00100000, -1, "Zero divide enable" },
826 { 0x00080000, -1, "Floating underflow" },
827 { 0x00040000, -1, "Floating overflow" },
828 { 0x00020000, -1, "Floating reserved operand" },
829 { 0x00010000, -1, "Floating zero divide" },
830 { 0x00008000, -1, "Floating error enable" },
831 { 0x00004000, -1, "Floating underflow enable" },
832 { 0x00002000, -1, "IEEE" },
833 { 0x00001000, -1, "Sequential stores" },
834 { 0x00000800, -1, "Intrinsic error" },
835 { 0x00000400, -1, "Intrinsic error enable" },
836 { 0x00000200, -1, "Trace thread creates" },
837 { 0x00000100, -1, "Thread init trap" },
838 { 0x000000e0, 5, "Reserved" },
839 { 0x0000001f, 0, "Intrinsic error code" },
847 psw
= parse_and_eval_address (arg
);
849 psw
= read_register (PS_REGNUM
);
851 for (p
= pswbit
; p
->bit
; p
++)
854 printf_filtered ("%08x %s %s\n", p
->bit
,
855 (psw
& p
->bit
) ? "yes" : "no ", p
->text
);
857 printf_filtered ("%08x %3d %s\n", p
->bit
,
858 (psw
& p
->bit
) >> p
->pos
, p
->text
);
864 /* reg (fmt_field, inst_field) --
865 the {first,second,third} operand of instruction as fmt_field = [ijk]
866 gets the value of the field from the [ijk] position of the instruction */
868 #define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
870 /* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
872 #define lit(i) op[fmt->i]
874 /* aj[j] -- name for A register j */
876 #define aj ((char (*)[3])(op[A]))
896 unsigned char byte
[8];
897 unsigned short half
[4];
899 short signed_half
[4];
903 int mask
; /* opcode mask */
904 int shift
; /* opcode align */
905 struct formstr
*formstr
[3]; /* ST, E0, E1 */
909 unsigned lop
:8, rop
:5; /* opcode */
910 unsigned fmt
:5; /* inst format */
911 unsigned i
:5, j
:5, k
:2; /* operand formats */
914 #include "opcode/convex.h"
916 CONST
unsigned char formdecode
[] = {
917 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
918 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
919 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
920 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
921 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
922 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
923 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
924 4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,
925 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
926 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
927 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
928 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
929 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
930 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
931 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
932 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
935 CONST
struct opform opdecode
[] = {
936 0x7e00, 9, format0
, e0_format0
, e1_format0
,
937 0x3f00, 8, format1
, e0_format1
, e1_format1
,
938 0x1fc0, 6, format2
, e0_format2
, e1_format2
,
939 0x0fc0, 6, format3
, e0_format3
, e1_format3
,
940 0x0700, 8, format4
, e0_format4
, e1_format4
,
941 0x03c0, 6, format5
, e0_format5
, e1_format5
,
942 0x01f8, 3, format6
, e0_format6
, e1_format6
,
943 0x00f8, 3, format7
, e0_format7
, e1_format7
,
944 0x0000, 0, formatx
, formatx
, formatx
,
945 0x0f80, 7, formatx
, formatx
, formatx
,
946 0x0f80, 7, formatx
, formatx
, formatx
,
949 /* Print the instruction at address MEMADDR in debugged memory,
950 on STREAM. Returns length of the instruction, in bytes. */
953 convex_print_insn (memaddr
, stream
)
959 register int format
, op1
, pfx
;
962 read_memory (memaddr
, &inst
, sizeof inst
);
964 /* Remove and note prefix, if present */
967 if ((pfx
& 0xfff0) == 0x7ef0)
969 pfx
= ((pfx
>> 3) & 1) + 1;
970 *(long long *) &inst
= *(long long *) &inst
.half
[1];
974 /* Split opcode into format.op1 and look up in appropriate table */
976 format
= formdecode
[inst
.byte
[0]];
977 op1
= (inst
.half
[0] & opdecode
[format
].mask
) >> opdecode
[format
].shift
;
982 else if (inst
.f1
.j
== 0)
983 fmt
= &format1a
[op1
];
984 else if (inst
.f1
.j
== 1)
985 fmt
= &format1b
[op1
];
990 fmt
= &opdecode
[format
].formstr
[pfx
][op1
];
997 fprintf (stream
, "0x%04x", pfx
? pfx
: inst
.half
[0]);
1004 fprintf (stream
, "%s%s%s", lop
[fmt
->lop
], rop
[fmt
->rop
],
1005 &" "[strlen(lop
[fmt
->lop
]) + strlen(rop
[fmt
->rop
])]);
1009 case rrr
: /* three register */
1010 fprintf (stream
, "%s,%s,%s", reg(i
,i
), reg(j
,j
), reg(k
,k
));
1013 case rr
: /* two register */
1014 fprintf (stream
, "%s,%s", reg(i
,j
), reg(j
,k
));
1017 case rxr
: /* two register, reversed i and j fields */
1018 fprintf (stream
, "%s,%s", reg(i
,k
), reg(j
,j
));
1021 case r
: /* one register */
1022 fprintf (stream
, "%s", reg(i
,k
));
1025 case nops
: /* no operands */
1028 case nr
: /* short immediate, one register */
1029 fprintf (stream
, "#%d,%s", inst
.f0
.j
, reg(i
,k
));
1032 case pcrel
: /* pc relative */
1033 print_address (memaddr
+ 2 * inst
.signed_byte
[1], stream
);
1036 case lr
: /* literal, one register */
1037 fprintf (stream
, "%s,%s", lit(i
), reg(j
,k
));
1040 case rxl
: /* one register, literal */
1041 fprintf (stream
, "%s,%s", reg(i
,k
), lit(j
));
1044 case rlr
: /* register, literal, register */
1045 fprintf (stream
, "%s,%s,%s", reg(i
,j
), lit(j
), reg(k
,k
));
1048 case rrl
: /* register, register, literal */
1049 fprintf (stream
, "%s,%s,%s", reg(i
,j
), reg(j
,k
), lit(k
));
1052 case iml
: /* immediate, literal */
1055 fprintf (stream
, "#%#x,%s",
1056 (inst
.signed_half
[1] << 16) + inst
.half
[2], lit(i
));
1061 fprintf (stream
, "#%d,%s", inst
.signed_half
[1], lit(i
));
1065 case imr
: /* immediate, register */
1068 fprintf (stream
, "#%#x,%s",
1069 (inst
.signed_half
[1] << 16) + inst
.half
[2], reg(i
,k
));
1074 fprintf (stream
, "#%d,%s", inst
.signed_half
[1], reg(i
,k
));
1078 case a1r
: /* memory, register */
1079 l
= print_effa (inst
, stream
);
1080 fprintf (stream
, ",%s", reg(i
,k
));
1083 case a1l
: /* memory, literal */
1084 l
= print_effa (inst
, stream
);
1085 fprintf (stream
, ",%s", lit(i
));
1088 case a2r
: /* register, memory */
1089 fprintf (stream
, "%s,", reg(i
,k
));
1090 return pfx
+ print_effa (inst
, stream
);
1092 case a2l
: /* literal, memory */
1093 fprintf (stream
, "%s,", lit(i
));
1094 return pfx
+ print_effa (inst
, stream
);
1096 case a3
: /* memory */
1097 return pfx
+ print_effa (inst
, stream
);
1099 case a4
: /* system call */
1106 unsigned int m
= (inst
.signed_half
[1] << 16) + inst
.half
[2];
1107 fprintf (stream
, "#%d,#%d", m
>> l
, m
& (-1 >> (32-l
)));
1112 unsigned int m
= inst
.signed_half
[1];
1113 fprintf (stream
, "#%d,#%d", m
>> l
, m
& (-1 >> (32-l
)));
1120 /* print effective address @nnn(aj), return instruction length */
1122 int print_effa (inst
, stream
)
1130 n
= (inst
.signed_half
[1] << 16) + inst
.half
[2];
1135 n
= inst
.signed_half
[1];
1144 print_address (n
, stream
);
1148 fprintf (stream
, (n
& 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",
1156 _initialize_convex_dep ()
1158 add_com ("alias", class_support
, alias_command
,
1159 "Add a new name for an existing command.");
1161 add_cmd ("base", class_vars
, set_base_command
,
1162 "Change the integer output radix to 8, 10 or 16\n\
1163 or use just `set base' with no args to return to the ad-hoc default,\n\
1164 which is 16 for integers that look like addresses, 10 otherwise.",
1167 add_cmd ("pipeline", class_run
, set_pipelining_command
,
1168 "Enable or disable overlapped execution of instructions.\n\
1169 With `set pipe off', exceptions are reported with\n\
1170 $pc pointing at the instruction after the faulting one.\n\
1171 The default is `set pipe on', which runs faster.",
1174 add_cmd ("parallel", class_run
, set_parallel_command
,
1175 "Enable or disable multi-threaded execution of parallel code.\n\
1176 `set parallel off' means run the program on a single CPU.\n\
1177 `set parallel fixed' means run the program with all CPUs assigned to it.\n\
1178 `set parallel on' means run the program on any CPUs that are available.",
1181 add_com ("1cont", class_run
, one_cont_command
,
1182 "Continue the program, activating only the current thread.\n\
1183 Args are the same as the `cont' command.");
1185 add_com ("thread", class_run
, set_thread_command
,
1186 "Change the current thread, the one under scrutiny and control.\n\
1187 With no arg, show the active threads, the current one marked with *.");
1189 add_info ("threads", thread_info
,
1190 "List status of active threads.");
1192 add_info ("comm-registers", comm_registers_info
,
1193 "List communication registers and their contents.\n\
1194 A communication register name as argument means describe only that register.\n\
1195 An address as argument means describe the resource structure at that address.\n\
1196 `Locked' means that the register has been sent to but not yet received from.");
1198 add_info ("psw", psw_info
,
1199 "Display $ps, the processor status word, bit by bit.\n\
1200 An argument means display that value's interpretation as a psw.");
1202 add_cmd ("convex", no_class
, 0, "Convex-specific commands.\n\
1203 32-bit registers $pc $ps $sp $ap $fp $a1-5 $s0-7 $v0-7 $vl $vs $vm $c0-63\n\
1204 64-bit registers $S0-7 $V0-7 $C0-63\n\
1206 info threads display info on stopped threads waiting to signal\n\
1207 thread display list of active threads\n\
1208 thread N select thread N (its registers, stack, memory, etc.)\n\
1209 step, next, etc step selected thread only\n\
1210 1cont continue selected thread only\n\
1211 cont continue all threads\n\
1212 info comm-registers display contents of comm register(s) or a resource struct\n\
1213 info psw display processor status word $ps\n\
1214 set base N change integer radix used by `print' without a format\n\
1215 set pipeline off exceptions are precise, $pc points after the faulting insn\n\
1216 set pipeline on normal mode, $pc is somewhere ahead of faulting insn\n\
1217 set parallel off program runs on a single CPU\n\
1218 set parallel fixed all CPUs are assigned to the program\n\
1219 set parallel on normal mode, parallel execution on random available CPUs\n\
This page took 0.054555 seconds and 4 git commands to generate.