2007-08-10 Michael Snyder <msnyder@access-company.com>
[deliverable/binutils-gdb.git] / opcodes / h8300-dis.c
CommitLineData
252b5132 1/* Disassemble h8300 instructions.
9b201bb5
NC
2 Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007 Free Software Foundation, Inc.
252b5132 4
9b201bb5
NC
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
ed049af3 8 it under the terms of the GNU General Public License as published by
9b201bb5
NC
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
252b5132 11
9b201bb5
NC
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
252b5132 16
ed049af3
NC
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
47b0e7ad
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132
RH
21
22#define DEFINE_TABLE
23
0d8dfecf 24#include "sysdep.h"
252b5132
RH
25#define h8_opcodes h8ops
26#include "opcode/h8300.h"
27#include "dis-asm.h"
28#include "opintl.h"
a3e64b75
KD
29#include "libiberty.h"
30
31struct h8_instruction
32{
33 int length;
34 const struct h8_opcode *opcode;
35};
36
37struct h8_instruction *h8_instructions;
252b5132 38
252b5132 39/* Run through the opcodes and sort them into order to make them easy
3903e627 40 to disassemble. */
20dc5b5a 41
252b5132 42static void
47b0e7ad 43bfd_h8_disassemble_init (void)
252b5132
RH
44{
45 unsigned int i;
a3e64b75
KD
46 unsigned int nopcodes;
47 const struct h8_opcode *p;
48 struct h8_instruction *pi;
252b5132 49
a3e64b75 50 nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
b34976b6 51
47b0e7ad 52 h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
a3e64b75
KD
53
54 for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
252b5132
RH
55 {
56 int n1 = 0;
57 int n2 = 0;
58
59 if ((int) p->data.nib[0] < 16)
5fec0fc5 60 n1 = (int) p->data.nib[0];
252b5132
RH
61 else
62 n1 = 0;
53d388d1 63
252b5132 64 if ((int) p->data.nib[1] < 16)
5fec0fc5 65 n2 = (int) p->data.nib[1];
252b5132
RH
66 else
67 n2 = 0;
68
69 /* Just make sure there are an even number of nibbles in it, and
3903e627 70 that the count is the same as the length. */
20dc5b5a 71 for (i = 0; p->data.nib[i] != (op_type) E; i++)
53d388d1
JL
72 ;
73
252b5132 74 if (i & 1)
20dc5b5a
MS
75 {
76 fprintf (stderr, "Internal error, h8_disassemble_init.\n");
77 abort ();
78 }
53d388d1 79
a3e64b75
KD
80 pi->length = i / 2;
81 pi->opcode = p;
252b5132 82 }
a3e64b75
KD
83
84 /* Add entry for the NULL vector terminator. */
85 pi->length = 0;
86 pi->opcode = p;
252b5132
RH
87}
88
20dc5b5a 89static void
47b0e7ad
NC
90extract_immediate (FILE *stream,
91 op_type looking_for,
92 int thisnib,
93 unsigned char *data,
94 int *cst,
95 int *len,
96 const struct h8_opcode *q)
20dc5b5a
MS
97{
98 switch (looking_for & SIZE)
99 {
100 case L_2:
101 *len = 2;
102 *cst = thisnib & 3;
103
104 /* DISP2 special treatment. */
105 if ((looking_for & MODE) == DISP)
106 {
47b0e7ad
NC
107 if (OP_KIND (q->how) == O_MOVAB
108 || OP_KIND (q->how) == O_MOVAW
109 || OP_KIND (q->how) == O_MOVAL)
20dc5b5a
MS
110 {
111 /* Handling for mova insn. */
47b0e7ad
NC
112 switch (q->args.nib[0] & MODE)
113 {
114 case INDEXB:
115 default:
116 break;
117 case INDEXW:
118 *cst *= 2;
119 break;
120 case INDEXL:
121 *cst *= 4;
122 break;
123 }
20dc5b5a
MS
124 }
125 else
126 {
127 /* Handling for non-mova insn. */
47b0e7ad
NC
128 switch (OP_SIZE (q->how))
129 {
130 default: break;
131 case SW:
132 *cst *= 2;
133 break;
134 case SL:
135 *cst *= 4;
136 break;
137 }
20dc5b5a
MS
138 }
139 }
140 break;
141 case L_8:
142 *len = 8;
143 *cst = data[0];
144 break;
145 case L_16:
146 case L_16U:
147 *len = 16;
148 *cst = (data[0] << 8) + data [1];
149#if 0
150 if ((looking_for & SIZE) == L_16)
47b0e7ad 151 *cst = (short) *cst; /* Sign extend. */
20dc5b5a
MS
152#endif
153 break;
154 case L_32:
155 *len = 32;
156 *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
157 break;
158 default:
159 *len = 0;
160 *cst = 0;
161 fprintf (stream, "DISP bad size\n");
162 break;
163 }
164}
165
166static const char *regnames[] =
167{
168 "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
169 "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
170};
171static const char *wregnames[] =
172{
173 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
174 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
175};
176static const char *lregnames[] =
177{
178 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
179 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
180};
181static const char *cregnames[] =
182{
183 "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
184};
185
186static void
47b0e7ad
NC
187print_one_arg (disassemble_info *info,
188 bfd_vma addr,
189 op_type x,
190 int cst,
191 int cstlen,
192 int rdisp_n,
193 int rn,
194 const char **pregnames,
195 int len)
252b5132 196{
47b0e7ad 197 void * stream = info->stream;
20dc5b5a
MS
198 fprintf_ftype outfn = info->fprintf_func;
199
47b0e7ad
NC
200 if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
201 outfn (stream, "#0x%x", (unsigned) cst);
20dc5b5a 202 else if ((x & MODE) == IMM)
47b0e7ad
NC
203 outfn (stream, "#0x%x", (unsigned) cst);
204 else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
205 outfn (stream, "#%d", (unsigned) cst);
20dc5b5a
MS
206 else if ((x & MODE) == CONST_2)
207 outfn (stream, "#2");
208 else if ((x & MODE) == CONST_4)
209 outfn (stream, "#4");
210 else if ((x & MODE) == CONST_8)
211 outfn (stream, "#8");
212 else if ((x & MODE) == CONST_16)
213 outfn (stream, "#16");
214 else if ((x & MODE) == REG)
215 {
216 switch (x & SIZE)
217 {
218 case L_8:
219 outfn (stream, "%s", regnames[rn]);
220 break;
221 case L_16:
222 case L_16U:
223 outfn (stream, "%s", wregnames[rn]);
224 break;
225 case L_P:
226 case L_32:
227 outfn (stream, "%s", lregnames[rn]);
228 break;
229 }
230 }
231 else if ((x & MODE) == LOWREG)
232 {
233 switch (x & SIZE)
234 {
235 case L_8:
236 /* Always take low half of reg. */
237 outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
238 break;
239 case L_16:
240 case L_16U:
241 /* Always take low half of reg. */
242 outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
243 break;
244 case L_P:
245 case L_32:
246 outfn (stream, "%s.l", lregnames[rn]);
247 break;
248 }
249 }
250 else if ((x & MODE) == POSTINC)
47b0e7ad
NC
251 outfn (stream, "@%s+", pregnames[rn]);
252
20dc5b5a 253 else if ((x & MODE) == POSTDEC)
47b0e7ad
NC
254 outfn (stream, "@%s-", pregnames[rn]);
255
20dc5b5a 256 else if ((x & MODE) == PREINC)
47b0e7ad
NC
257 outfn (stream, "@+%s", pregnames[rn]);
258
20dc5b5a 259 else if ((x & MODE) == PREDEC)
47b0e7ad
NC
260 outfn (stream, "@-%s", pregnames[rn]);
261
20dc5b5a 262 else if ((x & MODE) == IND)
47b0e7ad
NC
263 outfn (stream, "@%s", pregnames[rn]);
264
20dc5b5a 265 else if ((x & MODE) == ABS || (x & ABSJMP))
47b0e7ad
NC
266 outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
267
20dc5b5a 268 else if ((x & MODE) == MEMIND)
47b0e7ad
NC
269 outfn (stream, "@@%d (0x%x)", cst, cst);
270
20dc5b5a
MS
271 else if ((x & MODE) == VECIND)
272 {
273 /* FIXME Multiplier should be 2 or 4, depending on processor mode,
274 by which is meant "normal" vs. "middle", "advanced", "maximum". */
275
276 int offset = (cst + 0x80) * 4;
277 outfn (stream, "@@%d (0x%x)", offset, offset);
278 }
279 else if ((x & MODE) == PCREL)
280 {
281 if ((x & SIZE) == L_16 ||
282 (x & SIZE) == L_16U)
283 {
0fd3a477 284 outfn (stream, ".%s%d (0x%lx)",
20dc5b5a
MS
285 (short) cst > 0 ? "+" : "",
286 (short) cst,
0fd3a477 287 (long)(addr + (short) cst + len));
20dc5b5a
MS
288 }
289 else
290 {
0fd3a477 291 outfn (stream, ".%s%d (0x%lx)",
20dc5b5a
MS
292 (char) cst > 0 ? "+" : "",
293 (char) cst,
0fd3a477 294 (long)(addr + (char) cst + len));
20dc5b5a
MS
295 }
296 }
297 else if ((x & MODE) == DISP)
47b0e7ad
NC
298 outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
299
20dc5b5a 300 else if ((x & MODE) == INDEXB)
47b0e7ad
NC
301 /* Always take low half of reg. */
302 outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
303 regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
304
20dc5b5a 305 else if ((x & MODE) == INDEXW)
47b0e7ad
NC
306 /* Always take low half of reg. */
307 outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
308 wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
309
20dc5b5a 310 else if ((x & MODE) == INDEXL)
47b0e7ad
NC
311 outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
312
20dc5b5a 313 else if (x & CTRL)
47b0e7ad
NC
314 outfn (stream, cregnames[rn]);
315
20dc5b5a 316 else if ((x & MODE) == CCR)
47b0e7ad
NC
317 outfn (stream, "ccr");
318
20dc5b5a 319 else if ((x & MODE) == EXR)
47b0e7ad
NC
320 outfn (stream, "exr");
321
20dc5b5a 322 else if ((x & MODE) == MACREG)
47b0e7ad
NC
323 outfn (stream, "mac%c", cst ? 'l' : 'h');
324
20dc5b5a
MS
325 else
326 /* xgettext:c-format */
327 outfn (stream, _("Hmmmm 0x%x"), x);
328}
329
330static unsigned int
47b0e7ad 331bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
20dc5b5a
MS
332{
333 /* Find the first entry in the table for this opcode. */
334 int regno[3] = { 0, 0, 0 };
335 int dispregno[3] = { 0, 0, 0 };
336 int cst[3] = { 0, 0, 0 };
337 int cstlen[3] = { 0, 0, 0 };
b34976b6 338 static bfd_boolean init = 0;
a3e64b75 339 const struct h8_instruction *qi;
20dc5b5a 340 char const **pregnames = mach != 0 ? lregnames : wregnames;
252b5132 341 int status;
20dc5b5a
MS
342 unsigned int l;
343 unsigned char data[MAX_CODE_NIBBLES];
252b5132 344 void *stream = info->stream;
20dc5b5a 345 fprintf_ftype outfn = info->fprintf_func;
252b5132
RH
346
347 if (!init)
348 {
349 bfd_h8_disassemble_init ();
350 init = 1;
351 }
352
3903e627 353 status = info->read_memory_func (addr, data, 2, info);
5fec0fc5 354 if (status != 0)
252b5132 355 {
3903e627 356 info->memory_error_func (status, addr, info);
252b5132
RH
357 return -1;
358 }
53d388d1 359
20dc5b5a 360 for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
53d388d1 361 status = info->read_memory_func (addr + l, data + l, 2, info);
252b5132 362
3903e627 363 /* Find the exact opcode/arg combo. */
a3e64b75 364 for (qi = h8_instructions; qi->opcode->name; qi++)
252b5132 365 {
a3e64b75 366 const struct h8_opcode *q = qi->opcode;
a3202ebb 367 const op_type *nib = q->data.nib;
252b5132
RH
368 unsigned int len = 0;
369
252b5132
RH
370 while (1)
371 {
372 op_type looking_for = *nib;
20dc5b5a
MS
373 int thisnib = data[len / 2];
374 int opnr;
53d388d1 375
20dc5b5a
MS
376 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
377 opnr = ((looking_for & OP3) == OP3 ? 2
378 : (looking_for & DST) == DST ? 1 : 0);
53d388d1 379
5fec0fc5 380 if (looking_for < 16 && looking_for >= 0)
252b5132 381 {
5fec0fc5 382 if (looking_for != thisnib)
252b5132
RH
383 goto fail;
384 }
5fec0fc5 385 else
252b5132 386 {
252b5132
RH
387 if ((int) looking_for & (int) B31)
388 {
20dc5b5a 389 if (!((thisnib & 0x8) != 0))
252b5132 390 goto fail;
53d388d1 391
252b5132 392 looking_for = (op_type) ((int) looking_for & ~(int) B31);
20dc5b5a 393 thisnib &= 0x7;
252b5132 394 }
20dc5b5a 395 else if ((int) looking_for & (int) B30)
252b5132 396 {
20dc5b5a 397 if (!((thisnib & 0x8) == 0))
252b5132 398 goto fail;
53d388d1 399
252b5132
RH
400 looking_for = (op_type) ((int) looking_for & ~(int) B30);
401 }
402
20dc5b5a
MS
403 if ((int) looking_for & (int) B21)
404 {
405 if (!((thisnib & 0x4) != 0))
406 goto fail;
407
408 looking_for = (op_type) ((int) looking_for & ~(int) B21);
409 thisnib &= 0xb;
410 }
411 else if ((int) looking_for & (int) B20)
412 {
413 if (!((thisnib & 0x4) == 0))
414 goto fail;
415
416 looking_for = (op_type) ((int) looking_for & ~(int) B20);
417 }
418 if ((int) looking_for & (int) B11)
419 {
420 if (!((thisnib & 0x2) != 0))
421 goto fail;
422
423 looking_for = (op_type) ((int) looking_for & ~(int) B11);
424 thisnib &= 0xd;
425 }
426 else if ((int) looking_for & (int) B10)
427 {
428 if (!((thisnib & 0x2) == 0))
429 goto fail;
430
431 looking_for = (op_type) ((int) looking_for & ~(int) B10);
432 }
433
434 if ((int) looking_for & (int) B01)
435 {
436 if (!((thisnib & 0x1) != 0))
437 goto fail;
438
439 looking_for = (op_type) ((int) looking_for & ~(int) B01);
440 thisnib &= 0xe;
441 }
442 else if ((int) looking_for & (int) B00)
443 {
444 if (!((thisnib & 0x1) == 0))
445 goto fail;
446
447 looking_for = (op_type) ((int) looking_for & ~(int) B00);
448 }
449
450 if (looking_for & IGNORE)
451 {
452 /* Hitachi has declared that IGNORE must be zero. */
453 if (thisnib != 0)
454 goto fail;
455 }
456 else if ((looking_for & MODE) == DATA)
457 {
458 ; /* Skip embedded data. */
459 }
460 else if ((looking_for & MODE) == DBIT)
252b5132 461 {
53d388d1
JL
462 /* Exclude adds/subs by looking at bit 0 and 2, and
463 make sure the operand size, either w or l,
464 matches by looking at bit 1. */
465 if ((looking_for & 7) != (thisnib & 7))
3903e627 466 goto fail;
53d388d1 467
20dc5b5a 468 cst[opnr] = (thisnib & 0x8) ? 2 : 1;
5fec0fc5 469 }
47b0e7ad
NC
470 else if ((looking_for & MODE) == DISP
471 || (looking_for & MODE) == ABS
472 || (looking_for & MODE) == PCREL
473 || (looking_for & MODE) == INDEXB
474 || (looking_for & MODE) == INDEXW
475 || (looking_for & MODE) == INDEXL)
252b5132 476 {
20dc5b5a
MS
477 extract_immediate (stream, looking_for, thisnib,
478 data + len / 2, cst + opnr,
479 cstlen + opnr, q);
480 /* Even address == bra, odd == bra/s. */
481 if (q->how == O (O_BRAS, SB))
482 cst[opnr] -= 1;
252b5132 483 }
47b0e7ad
NC
484 else if ((looking_for & MODE) == REG
485 || (looking_for & MODE) == LOWREG
486 || (looking_for & MODE) == IND
487 || (looking_for & MODE) == PREINC
488 || (looking_for & MODE) == POSTINC
489 || (looking_for & MODE) == PREDEC
490 || (looking_for & MODE) == POSTDEC)
252b5132 491 {
20dc5b5a 492 regno[opnr] = thisnib;
252b5132 493 }
47b0e7ad 494 else if (looking_for & CTRL) /* Control Register. */
252b5132 495 {
20dc5b5a 496 thisnib &= 7;
47b0e7ad
NC
497 if (((looking_for & MODE) == CCR && (thisnib != C_CCR))
498 || ((looking_for & MODE) == EXR && (thisnib != C_EXR))
499 || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
500 || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
501 || ((looking_for & MODE) == VBR && (thisnib != C_VBR))
502 || ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
20dc5b5a 503 goto fail;
47b0e7ad
NC
504 if (((looking_for & MODE) == CCR_EXR
505 && (thisnib != C_CCR && thisnib != C_EXR))
506 || ((looking_for & MODE) == VBR_SBR
507 && (thisnib != C_VBR && thisnib != C_SBR))
508 || ((looking_for & MODE) == MACREG
509 && (thisnib != C_MACH && thisnib != C_MACL)))
20dc5b5a 510 goto fail;
47b0e7ad
NC
511 if (((looking_for & MODE) == CC_EX_VB_SB
512 && (thisnib != C_CCR && thisnib != C_EXR
513 && thisnib != C_VBR && thisnib != C_SBR)))
20dc5b5a
MS
514 goto fail;
515
516 regno[opnr] = thisnib;
517 }
518 else if ((looking_for & SIZE) == L_5)
519 {
520 cst[opnr] = data[len / 2] & 31;
521 cstlen[opnr] = 5;
522 }
523 else if ((looking_for & SIZE) == L_4)
524 {
525 cst[opnr] = thisnib;
526 cstlen[opnr] = 4;
527 }
47b0e7ad
NC
528 else if ((looking_for & SIZE) == L_16
529 || (looking_for & SIZE) == L_16U)
20dc5b5a
MS
530 {
531 cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
532 cstlen[opnr] = 16;
533 }
534 else if ((looking_for & MODE) == MEMIND)
535 {
536 cst[opnr] = data[1];
252b5132 537 }
20dc5b5a 538 else if ((looking_for & MODE) == VECIND)
252b5132 539 {
20dc5b5a 540 cst[opnr] = data[1] & 0x7f;
252b5132 541 }
20dc5b5a 542 else if ((looking_for & SIZE) == L_32)
252b5132 543 {
20dc5b5a 544 int i = len / 2;
53d388d1 545
20dc5b5a
MS
546 cst[opnr] = ((data[i] << 24)
547 | (data[i + 1] << 16)
548 | (data[i + 2] << 8)
549 | (data[i + 3]));
252b5132 550
20dc5b5a 551 cstlen[opnr] = 32;
252b5132 552 }
20dc5b5a 553 else if ((looking_for & SIZE) == L_24)
252b5132 554 {
20dc5b5a 555 int i = len / 2;
53d388d1 556
20dc5b5a
MS
557 cst[opnr] =
558 (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
559 cstlen[opnr] = 24;
252b5132
RH
560 }
561 else if (looking_for & IGNORE)
562 {
3903e627 563 ;
252b5132
RH
564 }
565 else if (looking_for & DISPREG)
566 {
20dc5b5a 567 dispregno[opnr] = thisnib & 7;
252b5132 568 }
20dc5b5a 569 else if ((looking_for & MODE) == KBIT)
252b5132 570 {
5fec0fc5 571 switch (thisnib)
252b5132
RH
572 {
573 case 9:
20dc5b5a 574 cst[opnr] = 4;
252b5132
RH
575 break;
576 case 8:
20dc5b5a 577 cst[opnr] = 2;
252b5132
RH
578 break;
579 case 0:
20dc5b5a 580 cst[opnr] = 1;
252b5132
RH
581 break;
582 default:
583 goto fail;
584 }
585 }
20dc5b5a 586 else if ((looking_for & SIZE) == L_8)
252b5132 587 {
20dc5b5a
MS
588 cstlen[opnr] = 8;
589 cst[opnr] = data[len / 2];
252b5132 590 }
47b0e7ad
NC
591 else if ((looking_for & SIZE) == L_3
592 || (looking_for & SIZE) == L_3NZ)
252b5132 593 {
20dc5b5a
MS
594 cst[opnr] = thisnib & 0x7;
595 if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
596 goto fail;
252b5132 597 }
20dc5b5a 598 else if ((looking_for & SIZE) == L_2)
252b5132 599 {
20dc5b5a
MS
600 cstlen[opnr] = 2;
601 cst[opnr] = thisnib & 0x3;
252b5132 602 }
20dc5b5a 603 else if ((looking_for & MODE) == MACREG)
252b5132 604 {
20dc5b5a 605 cst[opnr] = (thisnib == 3);
252b5132 606 }
20dc5b5a 607 else if (looking_for == (op_type) E)
252b5132 608 {
20dc5b5a 609 outfn (stream, "%s\t", q->name);
252b5132
RH
610
611 /* Gross. Disgusting. */
612 if (strcmp (q->name, "ldm.l") == 0)
613 {
614 int count, high;
615
20dc5b5a
MS
616 count = (data[1] / 16) & 0x3;
617 high = regno[1];
252b5132 618
20dc5b5a 619 outfn (stream, "@sp+,er%d-er%d", high - count, high);
a3e64b75 620 return qi->length;
252b5132
RH
621 }
622
623 if (strcmp (q->name, "stm.l") == 0)
624 {
625 int count, low;
626
20dc5b5a
MS
627 count = (data[1] / 16) & 0x3;
628 low = regno[0];
252b5132 629
20dc5b5a
MS
630 outfn (stream, "er%d-er%d,@-sp", low, low + count);
631 return qi->length;
632 }
633 if (strcmp (q->name, "rte/l") == 0
634 || strcmp (q->name, "rts/l") == 0)
635 {
636 if (regno[0] == 0)
637 outfn (stream, "er%d", regno[1]);
638 else
47b0e7ad
NC
639 outfn (stream, "er%d-er%d", regno[1] - regno[0],
640 regno[1]);
20dc5b5a
MS
641 return qi->length;
642 }
0112cd26 643 if (CONST_STRNEQ (q->name, "mova"))
20dc5b5a 644 {
a3202ebb 645 const op_type *args = q->args.nib;
20dc5b5a
MS
646
647 if (args[1] == (op_type) E)
648 {
649 /* Short form. */
650 print_one_arg (info, addr, args[0], cst[0],
651 cstlen[0], dispregno[0], regno[0],
652 pregnames, qi->length);
653 outfn (stream, ",er%d", dispregno[0]);
654 }
655 else
656 {
657 outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
658 print_one_arg (info, addr, args[1], cst[1],
659 cstlen[1], dispregno[1], regno[1],
660 pregnames, qi->length);
661 outfn (stream, ".%c),",
662 (args[0] & MODE) == INDEXB ? 'b' : 'w');
663 print_one_arg (info, addr, args[2], cst[2],
664 cstlen[2], dispregno[2], regno[2],
665 pregnames, qi->length);
666 }
a3e64b75 667 return qi->length;
252b5132 668 }
3903e627 669 /* Fill in the args. */
252b5132 670 {
a3202ebb 671 const op_type *args = q->args.nib;
252b5132 672 int hadone = 0;
20dc5b5a 673 int nargs;
252b5132 674
91809fda 675 /* Special case handling for the adds and subs instructions
47b0e7ad
NC
676 since in H8 mode thay can only take the r0-r7 registers
677 but in other (higher) modes they can take the er0-er7
678 registers as well. */
91809fda
NC
679 if (strcmp (qi->opcode->name, "adds") == 0
680 || strcmp (qi->opcode->name, "subs") == 0)
681 {
682 outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
683 return qi->length;
684 }
685
20dc5b5a 686 for (nargs = 0;
47b0e7ad 687 nargs < 3 && args[nargs] != (op_type) E;
20dc5b5a 688 nargs++)
252b5132 689 {
20dc5b5a 690 int x = args[nargs];
53d388d1 691
252b5132 692 if (hadone)
20dc5b5a
MS
693 outfn (stream, ",");
694
695 print_one_arg (info, addr, x,
696 cst[nargs], cstlen[nargs],
697 dispregno[nargs], regno[nargs],
698 pregnames, qi->length);
53d388d1 699
252b5132 700 hadone = 1;
252b5132
RH
701 }
702 }
53d388d1 703
a3e64b75 704 return qi->length;
252b5132 705 }
252b5132 706 else
5fec0fc5 707 /* xgettext:c-format */
20dc5b5a 708 outfn (stream, _("Don't understand 0x%x \n"), looking_for);
252b5132 709 }
53d388d1 710
252b5132
RH
711 len++;
712 nib++;
713 }
53d388d1 714
252b5132 715 fail:
c07ab2ec 716 ;
252b5132
RH
717 }
718
5fec0fc5 719 /* Fell off the end. */
ed049af3 720 outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
252b5132
RH
721 return 2;
722}
723
5fec0fc5 724int
47b0e7ad 725print_insn_h8300 (bfd_vma addr, disassemble_info *info)
252b5132 726{
5fec0fc5 727 return bfd_h8_disassemble (addr, info, 0);
252b5132
RH
728}
729
5fec0fc5 730int
47b0e7ad 731print_insn_h8300h (bfd_vma addr, disassemble_info *info)
252b5132 732{
5fec0fc5 733 return bfd_h8_disassemble (addr, info, 1);
252b5132
RH
734}
735
5fec0fc5 736int
47b0e7ad 737print_insn_h8300s (bfd_vma addr, disassemble_info *info)
252b5132 738{
5fec0fc5 739 return bfd_h8_disassemble (addr, info, 2);
252b5132 740}
This page took 0.376099 seconds and 4 git commands to generate.