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