]> Git Repo - binutils.git/blob - gdb/tahoe-pinsn.c
ansi name abuse changes
[binutils.git] / gdb / tahoe-pinsn.c
1 /*
2  * Ported by the State University of New York at Buffalo by the Distributed
3  * Computer Systems Lab, Department of Computer Science, 1991.
4  */
5
6 #include <stdio.h>
7
8 #include "defs.h"
9 #include "param.h"
10 #include "symtab.h"
11 #include "tahoe-opcode.h"
12
13 /* Tahoe instructions are never longer than this.  */
14 #define MAXLEN 62
15
16 /* Number of elements in the opcode table.  */
17 #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
18
19 extern char *reg_names[];
20
21 static unsigned char *print_insn_arg ();
22
23 /* Print the Tahoe instruction at address MEMADDR in debugged memory,
24    on STREAM.  Returns length of the instruction, in bytes.  */
25
26 int
27 print_insn (memaddr, stream)
28      CORE_ADDR memaddr;
29      FILE *stream;
30 {
31   unsigned char buffer[MAXLEN];
32   register int i;
33   register unsigned char *p;
34   register char *d;
35
36   read_memory (memaddr, buffer, MAXLEN);
37
38   for (i = 0; i < NOPCODES; i++)
39     if (votstrs[i].detail.code == buffer[0]
40         || votstrs[i].detail.code == *(unsigned short *)buffer)
41       break;
42
43   /* Handle undefined instructions.  */
44   if (i == NOPCODES)
45     {
46       fprintf (stream, "0%o", buffer[0]);
47       return 1;
48     }
49
50   fprintf (stream, "%s", votstrs[i].name);
51
52   /* Point at first byte of argument data,
53      and at descriptor for first argument.  */
54   p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
55   d = votstrs[i].detail.args;
56
57   if (*d)
58     fputc ('\t', stream);
59
60   while (*d)
61     {
62       p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
63       d += 2;
64       if (*d)
65         fprintf (stream, ",");
66     }
67   return p - buffer;
68 }
69 /*******************************************************************/
70 static unsigned char *
71 print_insn_arg (d, p, addr, stream)
72      char *d;
73      register char *p;
74      CORE_ADDR addr;
75      FILE *stream;
76 {
77   int temp1 = 0;
78   register int regnum = *p & 0xf;
79   float floatlitbuf;
80
81   if (*d == 'b')
82     {
83       if (d[1] == 'b')
84         fprintf (stream, "0x%x", addr + *p++ + 1);
85       else
86         {
87
88           temp1 = *p;
89           temp1 <<= 8;
90           temp1 |= *(p + 1);
91           fprintf (stream, "0x%x", addr + temp1 + 2);
92           p += 2;
93         }
94     }
95   else
96     switch ((*p++ >> 4) & 0xf)
97       {
98       case 0:
99       case 1:
100       case 2:
101       case 3:                   /* Liter>al(short immediate byte) mode */
102         if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
103           {
104             *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
105             fprintf (stream, "$%f", floatlitbuf);
106           }
107         else
108           fprintf (stream, "$%d", p[-1] & 0x3f);
109         break;
110
111       case 4:                   /* Indexed */
112         p = (char *) print_insn_arg (d, p, addr + 1, stream);
113         fprintf (stream, "[%s]", reg_names[regnum]);
114         break;
115
116       case 5:                   /* Register */
117         fprintf (stream, reg_names[regnum]);
118         break;
119
120       case 7:                   /* Autodecrement */
121         fputc ('-', stream);
122       case 6:                   /* Register deferred */
123         fprintf (stream, "(%s)", reg_names[regnum]);
124         break;
125
126       case 9:                   /* Absolute Address & Autoincrement deferred */
127         fputc ('*', stream);
128         if (regnum == PC_REGNUM)
129           {
130             temp1 = *p;
131             temp1 <<= 8;
132             temp1 |= *(p +1);
133
134             fputc ('$', stream);
135             print_address (temp1, stream);
136             p += 4;
137             break;
138           }
139       case 8:                   /*Immediate & Autoincrement SP */
140         if (regnum == 8)         /*88 is Immediate Byte Mode*/
141           fprintf (stream, "$%d", *p++);
142
143         else if (regnum == 9)        /*89 is Immediate Word Mode*/
144           {
145             temp1 = *p;
146             temp1 <<= 8; 
147             temp1 |= *(p +1);
148             fprintf (stream, "$%d", temp1);
149             p += 2;
150           }  
151
152         else if (regnum == PC_REGNUM)    /*8F is Immediate Long Mode*/
153           {
154             temp1 = *p;
155             temp1 <<=8;
156             temp1 |= *(p +1);
157             temp1 <<=8;
158             temp1 |= *(p +2);
159             temp1 <<= 8;
160             temp1 |= *(p +3);
161             fprintf (stream, "$%d", temp1);
162             p += 4;
163           }
164
165         else                            /*8E is Autoincrement SP Mode*/
166               fprintf (stream, "(%s)+", reg_names[regnum]);
167         break;
168
169       case 11:                  /* Register + Byte Displacement Deferred Mode*/
170         fputc ('*', stream);
171       case 10:                  /* Register + Byte Displacement Mode*/
172         if (regnum == PC_REGNUM)
173           print_address (addr + *p + 2, stream);
174         else
175           fprintf (stream, "%d(%s)", *p, reg_names[regnum]);
176         p += 1;
177         break;
178
179       case 13:                  /* Register + Word Displacement Deferred Mode*/
180         fputc ('*', stream);
181       case 12:                  /* Register + Word Displacement Mode*/
182         temp1 = *p;
183         temp1 <<= 8;
184         temp1 |= *(p +1);
185         if (regnum == PC_REGNUM)
186           print_address (addr + temp1 + 3, stream);
187         else
188           fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
189         p += 2;
190         break;
191
192       case 15:                  /* Register + Long Displacement Deferred Mode*/
193         fputc ('*', stream);
194       case 14:                  /* Register + Long Displacement Mode*/
195         temp1 = *p;
196         temp1 <<= 8;
197         temp1 |= *(p +1);
198         temp1 <<= 8;
199         temp1 |= *(p +2);
200         temp1 <<= 8;
201         temp1 |= *(p +3);
202         if (regnum == PC_REGNUM)
203           print_address (addr + temp1 + 5, stream);
204         else
205           fprintf (stream, "%d(%s)", temp1, reg_names[regnum]);
206         p += 4;
207       }
208
209   return (unsigned char *) p;
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
This page took 0.036106 seconds and 4 git commands to generate.