]> Git Repo - binutils.git/blob - gdb/mips-pinsn.c
* mips-xdep.c (REGISTER_PTRACE_ADDR, fetch_inferior_registers,
[binutils.git] / gdb / mips-pinsn.c
1 /* Print mips instructions for GDB, the GNU debugger.
2    Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
3    Contributed by Nobuyuki Hikichi([email protected]).
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "defs.h"
22 #include "symtab.h"
23 #include "opcode/mips.h"
24
25 /* Mips instructions are never longer than this many bytes.  */
26 #define MAXLEN 4
27
28 /* Number of elements in the opcode table.  */
29 #define NOPCODES (sizeof mips_opcodes / sizeof mips_opcodes[0])
30
31 #define MKLONG(p)  *(unsigned long*)p
32 \f
33 /* subroutine */
34 static unsigned char *
35 print_insn_arg (d, l, stream, pc)
36      char *d;
37      register unsigned long int *l;
38      FILE *stream;
39      CORE_ADDR pc;
40 {
41   switch (*d)
42     {
43     case ',':
44     case '(':
45     case ')':
46       fputc (*d, stream);
47       break;
48
49     case 's':
50       fprintf (stream, "$%s", reg_names[((struct op_i_fmt *) l)->rs]);
51       break;
52
53     case 't':
54       fprintf (stream, "$%s", reg_names[((struct op_i_fmt *) l)->rt]);
55       break;
56
57     case 'i':
58       fprintf (stream, "%d", ((struct op_i_fmt *) l)->immediate);
59       break;
60
61     case 'j': /* same as i, but sign-extended */
62       fprintf (stream, "%d", ((struct op_b_fmt *) l)->delta);
63       break;
64
65     case 'a':
66       print_address ((pc & 0xF0000000) | (((struct op_j_fmt *)l)->target << 2),
67                      stream);
68       break;
69
70     case 'b':
71       print_address ((((struct op_b_fmt *) l)->delta << 2) + pc + 4, stream);
72       break;
73
74     case 'd':
75       fprintf (stream, "$%s", reg_names[((struct op_r_fmt *) l)->rd]);
76       break;
77
78     case 'h':
79       fprintf (stream, "0x%x", ((struct op_r_fmt *) l)->shamt);
80       break;
81
82     case 'S':
83       fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->fs);
84       break;
85
86     case 'T':
87       fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->ft);
88       break;
89
90     case 'D':
91       fprintf (stream, "$f%d", ((struct fop_r_fmt *) l)->fd);
92       break;
93
94     default:
95       fprintf (stream, "# internal error, undefined modifier(%c)", *d);
96       break;
97     }
98 }
99 \f
100 /* Print the mips instruction at address MEMADDR in debugged memory,
101    on STREAM.  Returns length of the instruction, in bytes, which
102    is always 4.  */
103
104 int
105 print_insn (memaddr, stream)
106      CORE_ADDR memaddr;
107      FILE *stream;
108 {
109   unsigned char buffer[MAXLEN];
110   register int i;
111   register char *d;
112   unsigned long int l;
113
114   read_memory (memaddr, buffer, MAXLEN);
115   SWAP_TARGET_AND_HOST (buffer, MAXLEN);
116
117   for (i = 0; i < NOPCODES; i++)
118     {
119       register unsigned int opcode = mips_opcodes[i].opcode;
120       register unsigned int match = mips_opcodes[i].match;
121       if ((*(unsigned int*)buffer & match) == opcode)
122         break;
123     }
124
125   l = MKLONG (buffer);
126   /* Handle undefined instructions.  */
127   if (i == NOPCODES)
128     {
129       fprintf (stream, "0x%x",l);
130       return 4;
131     }
132
133   fprintf (stream, "%s", mips_opcodes[i].name);
134
135   if (!(d = mips_opcodes[i].args))
136     return 4;
137
138   fputc (' ', stream);
139
140   while (*d)
141     print_insn_arg (d++, &l, stream, memaddr);
142
143   return 4;
144 }
This page took 0.032819 seconds and 4 git commands to generate.