* arm-dis.c (print_insn_arm): Don't print instruction bytes.
[deliverable/binutils-gdb.git] / opcodes / mn10300-dis.c
1 /* Disassemble MN10300 instructions.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18
19 #include <stdio.h>
20
21 #include "ansidecl.h"
22 #include "opcode/mn10300.h"
23 #include "dis-asm.h"
24
25 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
26 unsigned long insn, unsigned int));
27
28 int
29 print_insn_mn10300 (memaddr, info)
30 bfd_vma memaddr;
31 struct disassemble_info *info;
32 {
33 int status;
34 bfd_byte buffer[4];
35 unsigned long insn;
36 unsigned int consume;
37
38 /* First figure out how big the opcode is. */
39 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
40 if (status != 0)
41 {
42 (*info->memory_error_func) (status, memaddr, info);
43 return -1;
44 }
45 insn = *(unsigned char *) buffer;
46
47 /* These are one byte insns. */
48 if ((insn & 0xf3) == 0x00
49 || (insn & 0xf0) == 0x10
50 || (insn & 0xfc) == 0x3c
51 || (insn & 0xf3) == 0x41
52 || (insn & 0xf3) == 0x40
53 || (insn & 0xfc) == 0x50
54 || (insn & 0xfc) == 0x54
55 || (insn & 0xf0) == 0x60
56 || (insn & 0xf0) == 0x70
57 || ((insn & 0xf0) == 0x80
58 && (insn & 0x0c) >> 2 != (insn & 0x03))
59 || ((insn & 0xf0) == 0x90
60 && (insn & 0x0c) >> 2 != (insn & 0x03))
61 || ((insn & 0xf0) == 0xa0
62 && (insn & 0x0c) >> 2 != (insn & 0x03))
63 || ((insn & 0xf0) == 0xb0
64 && (insn & 0x0c) >> 2 != (insn & 0x03))
65 || (insn & 0xff) == 0xcb
66 || (insn & 0xfc) == 0xd0
67 || (insn & 0xfc) == 0xd4
68 || (insn & 0xfc) == 0xd8
69 || (insn & 0xf0) == 0xe0)
70 {
71 consume = 1;
72 }
73
74 /* These are two byte insns. */
75 else if ((insn & 0xf0) == 0x80
76 || (insn & 0xf0) == 0x90
77 || (insn & 0xf0) == 0xa0
78 || (insn & 0xf0) == 0xb0
79 || (insn & 0xfc) == 0x20
80 || (insn & 0xfc) == 0x28
81 || (insn & 0xf3) == 0x43
82 || (insn & 0xf3) == 0x42
83 || (insn & 0xfc) == 0x58
84 || (insn & 0xfc) == 0x5c
85 || ((insn & 0xf0) == 0xc0
86 && (insn & 0xff) != 0xcb
87 && (insn & 0xff) != 0xcc
88 && (insn & 0xff) != 0xcd)
89 || (insn & 0xff) == 0xf0
90 || (insn & 0xff) == 0xf1
91 || (insn & 0xff) == 0xf2
92 || (insn & 0xff) == 0xf3
93 || (insn & 0xff) == 0xf4
94 || (insn & 0xff) == 0xf5
95 || (insn & 0xff) == 0xf6)
96 {
97 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
98 if (status != 0)
99 {
100 (*info->memory_error_func) (status, memaddr, info);
101 return -1;
102 }
103 insn = bfd_getb16 (buffer);
104 consume = 2;
105 }
106
107 /* These are three byte insns. */
108 else if ((insn & 0xff) == 0xf8
109 || (insn & 0xff) == 0xcc
110 || (insn & 0xff) == 0xf9
111 || (insn & 0xf3) == 0x01
112 || (insn & 0xf3) == 0x02
113 || (insn & 0xf3) == 0x03
114 || (insn & 0xfc) == 0x24
115 || (insn & 0xfc) == 0x2c
116 || (insn & 0xfc) == 0x30
117 || (insn & 0xfc) == 0x34
118 || (insn & 0xfc) == 0x38
119 || (insn & 0xff) == 0xde
120 || (insn & 0xff) == 0xdf
121 || (insn & 0xff) == 0xcc)
122 {
123 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
124 if (status != 0)
125 {
126 (*info->memory_error_func) (status, memaddr, info);
127 return -1;
128 }
129 insn = bfd_getb16 (buffer);
130 insn <<= 8;
131 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
132 if (status != 0)
133 {
134 (*info->memory_error_func) (status, memaddr, info);
135 return -1;
136 }
137 insn |= *(unsigned char *)buffer;
138 consume = 3;
139 }
140
141 /* These are four byte insns. */
142 else if ((insn & 0xff) == 0xfa
143 || (insn & 0xff) == 0xfb)
144 {
145 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
146 if (status != 0)
147 {
148 (*info->memory_error_func) (status, memaddr, info);
149 return -1;
150 }
151 insn = bfd_getb32 (buffer);
152 consume = 4;
153 }
154
155 /* These are five byte insns. */
156 else if ((insn & 0xff) == 0xcd
157 || (insn & 0xff) == 0xdc)
158 {
159 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
160 if (status != 0)
161 {
162 (*info->memory_error_func) (status, memaddr, info);
163 return -1;
164 }
165 insn = bfd_getb32 (buffer);
166 consume = 5;
167 }
168
169 /* These are six byte insns. */
170 else if ((insn & 0xff) == 0xfd
171 || (insn & 0xff) == 0xfc)
172 {
173 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
174 if (status != 0)
175 {
176 (*info->memory_error_func) (status, memaddr, info);
177 return -1;
178 }
179
180 insn = bfd_getb32 (buffer);
181 consume = 6;
182 }
183
184 /* Else its a seven byte insns (in theory). */
185 else
186 {
187 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
188 if (status != 0)
189 {
190 (*info->memory_error_func) (status, memaddr, info);
191 return -1;
192 }
193
194 insn = bfd_getb32 (buffer);
195 consume = 7;
196 }
197
198 disassemble (memaddr, info, insn, consume);
199
200 return consume;
201 }
202
203 static void
204 disassemble (memaddr, info, insn, size)
205 bfd_vma memaddr;
206 struct disassemble_info *info;
207 unsigned long insn;
208 unsigned int size;
209 {
210 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
211 const struct mn10300_operand *operand;
212 bfd_byte buffer[4];
213 unsigned long extension = 0;
214 int status, match = 0;
215
216 /* Find the opcode. */
217 while (op->name)
218 {
219 int mysize, extra_shift;
220
221 if (op->format == FMT_S0)
222 mysize = 1;
223 else if (op->format == FMT_S1
224 || op->format == FMT_D0)
225 mysize = 2;
226 else if (op->format == FMT_S2
227 || op->format == FMT_D1)
228 mysize = 3;
229 else if (op->format == FMT_S4)
230 mysize = 5;
231 else if (op->format == FMT_D2)
232 mysize = 4;
233 else if (op->format == FMT_D4)
234 mysize = 6;
235 else
236 mysize = 7;
237
238 if ((op->mask & insn) == op->opcode
239 && size == mysize)
240 {
241 const unsigned char *opindex_ptr;
242 unsigned int nocomma;
243 int paren = 0;
244
245 if (op->format == FMT_D1 || op->format == FMT_S1)
246 extra_shift = 8;
247 else if (op->format == FMT_D2 || op->format == FMT_D4
248 || op->format == FMT_S2 || op->format == FMT_S4
249 || op->format == FMT_S6 || op->format == FMT_D5)
250 extra_shift = 16;
251 else
252 extra_shift = 0;
253
254 if (size == 1 || size == 2)
255 {
256 extension = 0;
257 }
258 else if (size == 3
259 && (op->format == FMT_D1
260 || op->opcode == 0xdf0000
261 || op->opcode == 0xde0000))
262 {
263 extension = 0;
264 }
265 else if (size == 3)
266 {
267 insn &= 0xff0000;
268 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
269 if (status != 0)
270 {
271 (*info->memory_error_func) (status, memaddr, info);
272 return;
273 }
274
275 insn |= bfd_getl16 (buffer);
276 extension = 0;
277 }
278 else if (size == 4
279 && (op->opcode == 0xfaf80000
280 || op->opcode == 0xfaf00000
281 || op->opcode == 0xfaf40000))
282 {
283 extension = 0;
284 }
285 else if (size == 4)
286 {
287 insn &= 0xffff0000;
288 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
289 if (status != 0)
290 {
291 (*info->memory_error_func) (status, memaddr, info);
292 return;
293 }
294
295 insn |= bfd_getl16 (buffer);
296 extension = 0;
297 }
298 else if (size == 5 && op->opcode == 0xdc000000)
299 {
300 unsigned long temp = 0;
301 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
302 if (status != 0)
303 {
304 (*info->memory_error_func) (status, memaddr, info);
305 return;
306 }
307 temp |= bfd_getl32 (buffer);
308
309 insn &= 0xff000000;
310 insn |= (temp & 0xffffff00) >> 8;
311 extension = temp & 0xff;
312 }
313 else if (size == 5)
314 {
315 unsigned long temp = 0;
316 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
317 if (status != 0)
318 {
319 (*info->memory_error_func) (status, memaddr, info);
320 return;
321 }
322 temp |= bfd_getl16 (buffer);
323
324 insn &= 0xff0000ff;
325 insn |= temp << 8;
326
327 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
328 if (status != 0)
329 {
330 (*info->memory_error_func) (status, memaddr, info);
331 return;
332 }
333 extension = *(unsigned char *)buffer;
334 }
335 else if (size == 6)
336 {
337 unsigned long temp = 0;
338 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
339 if (status != 0)
340 {
341 (*info->memory_error_func) (status, memaddr, info);
342 return;
343 }
344 temp |= bfd_getl32 (buffer);
345
346 insn &= 0xffff0000;
347 insn |= (temp >> 16) & 0xffff;
348 extension = temp & 0xffff;
349 }
350 else if (size == 7 && op->opcode == 0xdd000000)
351 {
352 unsigned long temp = 0;
353 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
354 if (status != 0)
355 {
356 (*info->memory_error_func) (status, memaddr, info);
357 return;
358 }
359 temp |= bfd_getl32 (buffer);
360
361 insn &= 0xff000000;
362 insn |= (temp >> 8) & 0xffffff;
363 extension = (temp & 0xff) << 16;
364
365 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
366 if (status != 0)
367 {
368 (*info->memory_error_func) (status, memaddr, info);
369 return;
370 }
371 extension |= bfd_getb16 (buffer);
372 }
373 else if (size == 7)
374 {
375 unsigned long temp = 0;
376 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
377 if (status != 0)
378 {
379 (*info->memory_error_func) (status, memaddr, info);
380 return;
381 }
382 temp |= bfd_getl32 (buffer);
383
384 insn &= 0xffff0000;
385 insn |= (temp >> 16) & 0xffff;
386 extension = (temp & 0xffff) << 8;
387
388 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
389 if (status != 0)
390 {
391 (*info->memory_error_func) (status, memaddr, info);
392 return;
393 }
394 extension |= *(unsigned char *)buffer;
395 }
396
397 match = 1;
398 (*info->fprintf_func) (info->stream, "%s\t", op->name);
399
400 /* Now print the operands. */
401 for (opindex_ptr = op->operands, nocomma = 1;
402 *opindex_ptr != 0;
403 opindex_ptr++)
404 {
405 unsigned long value;
406
407 operand = &mn10300_operands[*opindex_ptr];
408
409 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
410 {
411 unsigned long temp;
412 value = insn & ((1 << operand->bits) - 1);
413 value <<= (32 - operand->bits);
414 temp = extension >> operand->shift;
415 temp &= ((1 << (32 - operand->bits)) - 1);
416 value |= temp;
417 }
418 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
419 {
420 value = ((extension >> (operand->shift))
421 & ((1 << operand->bits) - 1));
422 }
423 else
424 {
425 value = ((insn >> (operand->shift))
426 & ((1 << operand->bits) - 1));
427 }
428
429 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
430 value = ((long)(value << (32 - operand->bits))
431 >> (32 - operand->bits));
432
433 if (!nocomma
434 && (!paren
435 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
436 (*info->fprintf_func) (info->stream, ",");
437
438 nocomma = 0;
439
440 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
441 {
442 value = ((insn >> (operand->shift + extra_shift))
443 & ((1 << operand->bits) - 1));
444 (*info->fprintf_func) (info->stream, "d%d", value);
445 }
446
447 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
448 {
449 value = ((insn >> (operand->shift + extra_shift))
450 & ((1 << operand->bits) - 1));
451 (*info->fprintf_func) (info->stream, "a%d", value);
452 }
453
454 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
455 (*info->fprintf_func) (info->stream, "sp");
456
457 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
458 (*info->fprintf_func) (info->stream, "psw");
459
460 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
461 (*info->fprintf_func) (info->stream, "mdr");
462
463 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
464 {
465 if (paren)
466 (*info->fprintf_func) (info->stream, ")");
467 else
468 {
469 (*info->fprintf_func) (info->stream, "(");
470 nocomma = 1;
471 }
472 paren = !paren;
473 }
474
475 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
476 (*info->print_address_func) (value + memaddr, info);
477
478 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
479 (*info->print_address_func) (value, info);
480
481 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
482 {
483 int comma = 0;
484
485 (*info->fprintf_func) (info->stream, "[");
486 if (value & 0x80)
487 {
488 (*info->fprintf_func) (info->stream, "d2");
489 comma = 1;
490 }
491
492 if (value & 0x40)
493 {
494 if (comma)
495 (*info->fprintf_func) (info->stream, ",");
496 (*info->fprintf_func) (info->stream, "d3");
497 comma = 1;
498 }
499
500 if (value & 0x20)
501 {
502 if (comma)
503 (*info->fprintf_func) (info->stream, ",");
504 (*info->fprintf_func) (info->stream, "a2");
505 comma = 1;
506 }
507
508 if (value & 0x10)
509 {
510 if (comma)
511 (*info->fprintf_func) (info->stream, ",");
512 (*info->fprintf_func) (info->stream, "a3");
513 comma = 1;
514 }
515
516 if (value & 0x08)
517 {
518 if (comma)
519 (*info->fprintf_func) (info->stream, ",");
520 (*info->fprintf_func) (info->stream, "other");
521 comma = 1;
522 }
523 (*info->fprintf_func) (info->stream, "]");
524 }
525
526 else
527 (*info->fprintf_func) (info->stream, "%d", value);
528 }
529 /* All done. */
530 break;
531 }
532 op++;
533 }
534
535 if (!match)
536 {
537 (*info->fprintf_func) (info->stream, "unknown\t0x%04x", insn);
538 }
539 }
This page took 0.072321 seconds and 4 git commands to generate.