h8300-dis.c 18 KB

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