source: trunk/binutils/opcodes/h8500-dis.c@ 3416

Last change on this file since 3416 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.9 KB
Line 
1/* Disassemble h8500 instructions.
2 Copyright 1993, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include <stdio.h>
19
20#define DISASSEMBLER_TABLE
21#define DEFINE_TABLE
22
23#include "sysdep.h"
24#include "h8500-opc.h"
25#include "dis-asm.h"
26#include "opintl.h"
27
28/* Maximum length of an instruction. */
29#define MAXLEN 8
30
31#include <setjmp.h>
32
33static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
34
35struct private
36{
37 /* Points to first byte not fetched. */
38 bfd_byte *max_fetched;
39 bfd_byte the_buffer[MAXLEN];
40 bfd_vma insn_start;
41 jmp_buf bailout;
42};
43
44/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
45 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
46 on error. */
47#define FETCH_DATA(info, addr) \
48 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
49 ? 1 : fetch_data ((info), (addr)))
50
51static int
52fetch_data (info, addr)
53 struct disassemble_info *info;
54 bfd_byte *addr;
55{
56 int status;
57 struct private *priv = (struct private *) info->private_data;
58 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
59
60 status = (*info->read_memory_func) (start,
61 priv->max_fetched,
62 addr - priv->max_fetched,
63 info);
64 if (status != 0)
65 {
66 (*info->memory_error_func) (status, start, info);
67 longjmp (priv->bailout, 1);
68 }
69 else
70 priv->max_fetched = addr;
71 return 1;
72}
73
74static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" };
75
76int
77print_insn_h8500 (addr, info)
78 bfd_vma addr;
79 disassemble_info *info;
80{
81 const h8500_opcode_info *opcode;
82 void *stream = info->stream;
83 fprintf_ftype func = info->fprintf_func;
84
85 struct private priv;
86 bfd_byte *buffer = priv.the_buffer;
87
88 info->private_data = (PTR) & priv;
89 priv.max_fetched = priv.the_buffer;
90 priv.insn_start = addr;
91 if (setjmp (priv.bailout) != 0)
92 /* Error return. */
93 return -1;
94
95 if (0)
96 {
97 static int one;
98
99 if (!one)
100 {
101 one = 1;
102 for (opcode = h8500_table; opcode->name; opcode++)
103 {
104 if ((opcode->bytes[0].contents & 0x8) == 0)
105 printf ("%s\n", opcode->name);
106 }
107 }
108 }
109
110 /* Run down the table to find the one which matches. */
111 for (opcode = h8500_table; opcode->name; opcode++)
112 {
113 int byte;
114 int rn = 0;
115 int rd = 0;
116 int rs = 0;
117 int disp = 0;
118 int abs = 0;
119 int imm = 0;
120 int pcrel = 0;
121 int qim = 0;
122 int i;
123 int cr = 0;
124
125 for (byte = 0; byte < opcode->length; byte++)
126 {
127 FETCH_DATA (info, buffer + byte + 1);
128 if ((buffer[byte] & opcode->bytes[byte].mask)
129 != (opcode->bytes[byte].contents))
130 {
131 goto next;
132 }
133 else
134 {
135 /* Extract any info parts. */
136 switch (opcode->bytes[byte].insert)
137 {
138 case 0:
139 case FP:
140 break;
141 default:
142 /* xgettext:c-format */
143 func (stream, _("can't cope with insert %d\n"),
144 opcode->bytes[byte].insert);
145 break;
146 case RN:
147 rn = buffer[byte] & 0x7;
148 break;
149 case RS:
150 rs = buffer[byte] & 0x7;
151 break;
152 case CRB:
153 cr = buffer[byte] & 0x7;
154 if (cr == 0)
155 goto next;
156 break;
157 case CRW:
158 cr = buffer[byte] & 0x7;
159 if (cr != 0)
160 goto next;
161 break;
162 case DISP16:
163 FETCH_DATA (info, buffer + byte + 2);
164 disp = (buffer[byte] << 8) | (buffer[byte + 1]);
165 break;
166 case FPIND_D8:
167 case DISP8:
168 disp = ((char) (buffer[byte]));
169 break;
170 case RD:
171 case RDIND:
172 rd = buffer[byte] & 0x7;
173 break;
174 case ABS24:
175 FETCH_DATA (info, buffer + byte + 3);
176 abs =
177 (buffer[byte] << 16)
178 | (buffer[byte + 1] << 8)
179 | (buffer[byte + 2]);
180 break;
181 case ABS16:
182 FETCH_DATA (info, buffer + byte + 2);
183 abs = (buffer[byte] << 8) | (buffer[byte + 1]);
184 break;
185 case ABS8:
186 abs = (buffer[byte]);
187 break;
188 case IMM16:
189 FETCH_DATA (info, buffer + byte + 2);
190 imm = (buffer[byte] << 8) | (buffer[byte + 1]);
191 break;
192 case IMM4:
193 imm = (buffer[byte]) & 0xf;
194 break;
195 case IMM8:
196 case RLIST:
197 imm = (buffer[byte]);
198 break;
199 case PCREL16:
200 FETCH_DATA (info, buffer + byte + 2);
201 pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
202 break;
203 case PCREL8:
204 pcrel = (buffer[byte]);
205 break;
206 case QIM:
207 switch (buffer[byte] & 0x7)
208 {
209 case 0:
210 qim = 1;
211 break;
212 case 1:
213 qim = 2;
214 break;
215 case 4:
216 qim = -1;
217 break;
218 case 5:
219 qim = -2;
220 break;
221 }
222 break;
223
224 }
225 }
226 }
227 /* We get here when all the masks have passed so we can output
228 the operands. */
229 FETCH_DATA (info, buffer + opcode->length);
230 for (i = 0; i < opcode->length; i++)
231 {
232 (func) (stream, "%02x ", buffer[i]);
233 }
234 for (; i < 6; i++)
235 {
236 (func) (stream, " ");
237 }
238 (func) (stream, "%s\t", opcode->name);
239 for (i = 0; i < opcode->nargs; i++)
240 {
241 if (i)
242 (func) (stream, ",");
243 switch (opcode->arg_type[i])
244 {
245 case FP:
246 func (stream, "fp");
247 break;
248 case RNIND_D16:
249 func (stream, "@(0x%x:16,r%d)", disp, rn);
250 break;
251 case RNIND_D8:
252 func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
253 break;
254 case RDIND_D16:
255 func (stream, "@(0x%x:16,r%d)", disp, rd);
256 break;
257 case RDIND_D8:
258 func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
259 break;
260 case FPIND_D8:
261 func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
262 break;
263 case CRB:
264 case CRW:
265 func (stream, "%s", crname[cr]);
266 break;
267 case RN:
268 func (stream, "r%d", rn);
269 break;
270 case RD:
271 func (stream, "r%d", rd);
272 break;
273 case RS:
274 func (stream, "r%d", rs);
275 break;
276 case RNDEC:
277 func (stream, "@-r%d", rn);
278 break;
279 case RNINC:
280 func (stream, "@r%d+", rn);
281 break;
282 case RNIND:
283 func (stream, "@r%d", rn);
284 break;
285 case RDIND:
286 func (stream, "@r%d", rd);
287 break;
288 case SPINC:
289 func (stream, "@sp+");
290 break;
291 case SPDEC:
292 func (stream, "@-sp");
293 break;
294 case ABS24:
295 func (stream, "@0x%0x:24", abs);
296 break;
297 case ABS16:
298 func (stream, "@0x%0x:16", abs & 0xffff);
299 break;
300 case ABS8:
301 func (stream, "@0x%0x:8", abs & 0xff);
302 break;
303 case IMM16:
304 func (stream, "#0x%0x:16", imm & 0xffff);
305 break;
306 case RLIST:
307 {
308 int i;
309 int nc = 0;
310 func (stream, "(");
311 for (i = 0; i < 8; i++)
312 {
313 if (imm & (1 << i))
314 {
315 func (stream, "r%d", i);
316 if (nc)
317 func (stream, ",");
318 nc = 1;
319 }
320 }
321 func (stream, ")");
322 }
323 break;
324 case IMM8:
325 func (stream, "#0x%0x:8", imm & 0xff);
326 break;
327 case PCREL16:
328 func (stream, "0x%0x:16",
329 (pcrel + addr + opcode->length) & 0xffff);
330 break;
331 case PCREL8:
332 func (stream, "#0x%0x:8",
333 ((char) pcrel + addr + opcode->length) & 0xffff);
334 break;
335 case QIM:
336 func (stream, "#%d:q", qim);
337 break;
338 case IMM4:
339 func (stream, "#%d:4", imm);
340 break;
341 }
342 }
343 return opcode->length;
344 next:
345 ;
346 }
347
348 /* Couldn't understand anything. */
349 /* xgettext:c-format */
350 func (stream, _("%02x\t\t*unknown*"), buffer[0]);
351 return 1;
352}
Note: See TracBrowser for help on using the repository browser.