v850-dis.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /* Disassemble V850 instructions.
  2. Copyright (C) 1996-2015 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. #include "sysdep.h"
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "opcode/v850.h"
  20. #include "dis-asm.h"
  21. #include "opintl.h"
  22. static const char *const v850_reg_names[] =
  23. {
  24. "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
  25. "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  26. "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  27. "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
  28. };
  29. static const char *const v850_sreg_names[] =
  30. {
  31. "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
  32. "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
  33. "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
  34. "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
  35. "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
  36. "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
  37. "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
  38. "fewr", "dbwr", "bsel"
  39. };
  40. static const char *const v850_cc_names[] =
  41. {
  42. "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
  43. "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
  44. };
  45. static const char *const v850_float_cc_names[] =
  46. {
  47. "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
  48. "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
  49. };
  50. static const char *const v850_vreg_names[] =
  51. {
  52. "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
  53. "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
  54. "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
  55. "vr28", "vr29", "vr30", "vr31"
  56. };
  57. static const char *const v850_cacheop_names[] =
  58. {
  59. "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
  60. "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
  61. };
  62. static const int v850_cacheop_codes[] =
  63. {
  64. 0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
  65. 0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
  66. };
  67. static const char *const v850_prefop_names[] =
  68. { "prefi", "prefd" };
  69. static const int v850_prefop_codes[] =
  70. { 0x00, 0x04, -1};
  71. static void
  72. print_value (int flags,
  73. bfd_vma memaddr,
  74. struct disassemble_info *info,
  75. long value)
  76. {
  77. if (flags & V850_PCREL)
  78. {
  79. bfd_vma addr = value + memaddr;
  80. if (flags & V850_INVERSE_PCREL)
  81. addr = memaddr - value;
  82. info->print_address_func (addr, info);
  83. }
  84. else if (flags & V850_OPERAND_DISP)
  85. {
  86. if (flags & V850_OPERAND_SIGNED)
  87. {
  88. info->fprintf_func (info->stream, "%ld", value);
  89. }
  90. else
  91. {
  92. info->fprintf_func (info->stream, "%lu", value);
  93. }
  94. }
  95. else if ((flags & V850E_IMMEDIATE32)
  96. || (flags & V850E_IMMEDIATE16HI))
  97. {
  98. info->fprintf_func (info->stream, "0x%lx", value);
  99. }
  100. else
  101. {
  102. if (flags & V850_OPERAND_SIGNED)
  103. {
  104. info->fprintf_func (info->stream, "%ld", value);
  105. }
  106. else
  107. {
  108. info->fprintf_func (info->stream, "%lu", value);
  109. }
  110. }
  111. }
  112. static long
  113. get_operand_value (const struct v850_operand *operand,
  114. unsigned long insn,
  115. int bytes_read,
  116. bfd_vma memaddr,
  117. struct disassemble_info * info,
  118. bfd_boolean noerror,
  119. int *invalid)
  120. {
  121. long value;
  122. bfd_byte buffer[4];
  123. if ((operand->flags & V850E_IMMEDIATE16)
  124. || (operand->flags & V850E_IMMEDIATE16HI))
  125. {
  126. int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
  127. if (status == 0)
  128. {
  129. value = bfd_getl16 (buffer);
  130. if (operand->flags & V850E_IMMEDIATE16HI)
  131. value <<= 16;
  132. else if (value & 0x8000)
  133. value |= (-1UL << 16);
  134. return value;
  135. }
  136. if (!noerror)
  137. info->memory_error_func (status, memaddr + bytes_read, info);
  138. return 0;
  139. }
  140. if (operand->flags & V850E_IMMEDIATE23)
  141. {
  142. int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
  143. if (status == 0)
  144. {
  145. value = bfd_getl32 (buffer);
  146. value = (operand->extract) (value, invalid);
  147. return value;
  148. }
  149. if (!noerror)
  150. info->memory_error_func (status, memaddr + bytes_read, info);
  151. return 0;
  152. }
  153. if (operand->flags & V850E_IMMEDIATE32)
  154. {
  155. int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
  156. if (status == 0)
  157. {
  158. bytes_read += 4;
  159. value = bfd_getl32 (buffer);
  160. return value;
  161. }
  162. if (!noerror)
  163. info->memory_error_func (status, memaddr + bytes_read, info);
  164. return 0;
  165. }
  166. if (operand->extract)
  167. value = (operand->extract) (insn, invalid);
  168. else
  169. {
  170. if (operand->bits == -1)
  171. value = (insn & operand->shift);
  172. else
  173. value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
  174. if (operand->flags & V850_OPERAND_SIGNED)
  175. value = ((long)(value << (sizeof (long)*8 - operand->bits))
  176. >> (sizeof (long)*8 - operand->bits));
  177. }
  178. return value;
  179. }
  180. static int
  181. disassemble (bfd_vma memaddr,
  182. struct disassemble_info *info,
  183. int bytes_read,
  184. unsigned long insn)
  185. {
  186. struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
  187. const struct v850_operand *operand;
  188. int match = 0;
  189. int target_processor;
  190. switch (info->mach)
  191. {
  192. case 0:
  193. default:
  194. target_processor = PROCESSOR_V850;
  195. break;
  196. case bfd_mach_v850e:
  197. target_processor = PROCESSOR_V850E;
  198. break;
  199. case bfd_mach_v850e1:
  200. target_processor = PROCESSOR_V850E;
  201. break;
  202. case bfd_mach_v850e2:
  203. target_processor = PROCESSOR_V850E2;
  204. break;
  205. case bfd_mach_v850e2v3:
  206. target_processor = PROCESSOR_V850E2V3;
  207. break;
  208. case bfd_mach_v850e3v5:
  209. target_processor = PROCESSOR_V850E3V5;
  210. break;
  211. }
  212. /* If this is a two byte insn, then mask off the high bits. */
  213. if (bytes_read == 2)
  214. insn &= 0xffff;
  215. /* Find the opcode. */
  216. while (op->name)
  217. {
  218. if ((op->mask & insn) == op->opcode
  219. && (op->processors & target_processor)
  220. && !(op->processors & PROCESSOR_OPTION_ALIAS))
  221. {
  222. /* Code check start. */
  223. const unsigned char *opindex_ptr;
  224. unsigned int opnum;
  225. unsigned int memop;
  226. for (opindex_ptr = op->operands, opnum = 1;
  227. *opindex_ptr != 0;
  228. opindex_ptr++, opnum++)
  229. {
  230. int invalid = 0;
  231. long value;
  232. operand = &v850_operands[*opindex_ptr];
  233. value = get_operand_value (operand, insn, bytes_read, memaddr,
  234. info, 1, &invalid);
  235. if (invalid)
  236. goto next_opcode;
  237. if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
  238. goto next_opcode;
  239. if ((operand->flags & V850_NOT_SA) && value == 0xd)
  240. goto next_opcode;
  241. if ((operand->flags & V850_NOT_IMM0) && value == 0)
  242. goto next_opcode;
  243. }
  244. /* Code check end. */
  245. match = 1;
  246. (*info->fprintf_func) (info->stream, "%s\t", op->name);
  247. #if 0
  248. fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
  249. insn, op->mask, op->opcode, op->name );
  250. #endif
  251. memop = op->memop;
  252. /* Now print the operands.
  253. MEMOP is the operand number at which a memory
  254. address specification starts, or zero if this
  255. instruction has no memory addresses.
  256. A memory address is always two arguments.
  257. This information allows us to determine when to
  258. insert commas into the output stream as well as
  259. when to insert disp[reg] expressions onto the
  260. output stream. */
  261. for (opindex_ptr = op->operands, opnum = 1;
  262. *opindex_ptr != 0;
  263. opindex_ptr++, opnum++)
  264. {
  265. bfd_boolean square = FALSE;
  266. long value;
  267. int flag;
  268. char *prefix;
  269. operand = &v850_operands[*opindex_ptr];
  270. value = get_operand_value (operand, insn, bytes_read, memaddr,
  271. info, 0, 0);
  272. /* The first operand is always output without any
  273. special handling.
  274. For the following arguments:
  275. If memop && opnum == memop + 1, then we need '[' since
  276. we're about to output the register used in a memory
  277. reference.
  278. If memop && opnum == memop + 2, then we need ']' since
  279. we just finished the register in a memory reference. We
  280. also need a ',' before this operand.
  281. Else we just need a comma.
  282. We may need to output a trailing ']' if the last operand
  283. in an instruction is the register for a memory address.
  284. The exception (and there's always an exception) are the
  285. "jmp" insn which needs square brackets around it's only
  286. register argument, and the clr1/not1/set1/tst1 insns
  287. which [...] around their second register argument. */
  288. prefix = "";
  289. if (operand->flags & V850_OPERAND_BANG)
  290. {
  291. prefix = "!";
  292. }
  293. else if (operand->flags & V850_OPERAND_PERCENT)
  294. {
  295. prefix = "%";
  296. }
  297. if (opnum == 1 && opnum == memop)
  298. {
  299. info->fprintf_func (info->stream, "%s[", prefix);
  300. square = TRUE;
  301. }
  302. else if ( (strcmp ("stc.w", op->name) == 0
  303. || strcmp ("cache", op->name) == 0
  304. || strcmp ("pref", op->name) == 0)
  305. && opnum == 2 && opnum == memop)
  306. {
  307. info->fprintf_func (info->stream, ", [");
  308. square = TRUE;
  309. }
  310. else if ( (strcmp (op->name, "pushsp") == 0
  311. || strcmp (op->name, "popsp") == 0
  312. || strcmp (op->name, "dbpush" ) == 0)
  313. && opnum == 2)
  314. {
  315. info->fprintf_func (info->stream, "-");
  316. }
  317. else if (opnum > 1
  318. && (v850_operands[*(opindex_ptr - 1)].flags
  319. & V850_OPERAND_DISP) != 0
  320. && opnum == memop)
  321. {
  322. info->fprintf_func (info->stream, "%s[", prefix);
  323. square = TRUE;
  324. }
  325. else if (opnum == 2
  326. && ( op->opcode == 0x00e407e0 /* clr1 */
  327. || op->opcode == 0x00e207e0 /* not1 */
  328. || op->opcode == 0x00e007e0 /* set1 */
  329. || op->opcode == 0x00e607e0 /* tst1 */
  330. ))
  331. {
  332. info->fprintf_func (info->stream, ", %s[", prefix);
  333. square = TRUE;
  334. }
  335. else if (opnum > 1)
  336. info->fprintf_func (info->stream, ", %s", prefix);
  337. /* Extract the flags, ignoring ones which do not
  338. effect disassembly output. */
  339. flag = operand->flags & (V850_OPERAND_REG
  340. | V850_REG_EVEN
  341. | V850_OPERAND_EP
  342. | V850_OPERAND_SRG
  343. | V850E_OPERAND_REG_LIST
  344. | V850_OPERAND_CC
  345. | V850_OPERAND_VREG
  346. | V850_OPERAND_CACHEOP
  347. | V850_OPERAND_PREFOP
  348. | V850_OPERAND_FLOAT_CC);
  349. switch (flag)
  350. {
  351. case V850_OPERAND_REG:
  352. info->fprintf_func (info->stream, "%s", v850_reg_names[value]);
  353. break;
  354. case (V850_OPERAND_REG|V850_REG_EVEN):
  355. info->fprintf_func (info->stream, "%s", v850_reg_names[value * 2]);
  356. break;
  357. case V850_OPERAND_EP:
  358. info->fprintf_func (info->stream, "ep");
  359. break;
  360. case V850_OPERAND_SRG:
  361. info->fprintf_func (info->stream, "%s", v850_sreg_names[value]);
  362. break;
  363. case V850E_OPERAND_REG_LIST:
  364. {
  365. static int list12_regs[32] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  366. 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
  367. int *regs;
  368. int i;
  369. unsigned long int mask = 0;
  370. int pc = 0;
  371. switch (operand->shift)
  372. {
  373. case 0xffe00001: regs = list12_regs; break;
  374. default:
  375. /* xgettext:c-format */
  376. fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift);
  377. abort ();
  378. }
  379. for (i = 0; i < 32; i++)
  380. {
  381. if (value & (1 << i))
  382. {
  383. switch (regs[ i ])
  384. {
  385. default: mask |= (1 << regs[ i ]); break;
  386. /* xgettext:c-format */
  387. case 0: fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
  388. case -1: pc = 1; break;
  389. }
  390. }
  391. }
  392. info->fprintf_func (info->stream, "{");
  393. if (mask || pc)
  394. {
  395. if (mask)
  396. {
  397. unsigned int bit;
  398. int shown_one = 0;
  399. for (bit = 0; bit < 32; bit++)
  400. if (mask & (1 << bit))
  401. {
  402. unsigned long int first = bit;
  403. unsigned long int last;
  404. if (shown_one)
  405. info->fprintf_func (info->stream, ", ");
  406. else
  407. shown_one = 1;
  408. info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
  409. for (bit++; bit < 32; bit++)
  410. if ((mask & (1 << bit)) == 0)
  411. break;
  412. last = bit;
  413. if (last > first + 1)
  414. {
  415. info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
  416. }
  417. }
  418. }
  419. if (pc)
  420. info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
  421. }
  422. info->fprintf_func (info->stream, "}");
  423. }
  424. break;
  425. case V850_OPERAND_CC:
  426. info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
  427. break;
  428. case V850_OPERAND_FLOAT_CC:
  429. info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]);
  430. break;
  431. case V850_OPERAND_CACHEOP:
  432. {
  433. int idx;
  434. for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
  435. {
  436. if (value == v850_cacheop_codes[idx])
  437. {
  438. info->fprintf_func (info->stream, "%s",
  439. v850_cacheop_names[idx]);
  440. goto MATCH_CACHEOP_CODE;
  441. }
  442. }
  443. info->fprintf_func (info->stream, "%d", (int) value);
  444. }
  445. MATCH_CACHEOP_CODE:
  446. break;
  447. case V850_OPERAND_PREFOP:
  448. {
  449. int idx;
  450. for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
  451. {
  452. if (value == v850_prefop_codes[idx])
  453. {
  454. info->fprintf_func (info->stream, "%s",
  455. v850_prefop_names[idx]);
  456. goto MATCH_PREFOP_CODE;
  457. }
  458. }
  459. info->fprintf_func (info->stream, "%d", (int) value);
  460. }
  461. MATCH_PREFOP_CODE:
  462. break;
  463. case V850_OPERAND_VREG:
  464. info->fprintf_func (info->stream, "%s", v850_vreg_names[value]);
  465. break;
  466. default:
  467. print_value (operand->flags, memaddr, info, value);
  468. break;
  469. }
  470. if (square)
  471. (*info->fprintf_func) (info->stream, "]");
  472. }
  473. /* All done. */
  474. break;
  475. }
  476. next_opcode:
  477. op++;
  478. }
  479. return match;
  480. }
  481. int
  482. print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
  483. {
  484. int status, status2, match;
  485. bfd_byte buffer[8];
  486. int length = 0, code_length = 0;
  487. unsigned long insn = 0, insn2 = 0;
  488. int target_processor;
  489. switch (info->mach)
  490. {
  491. case 0:
  492. default:
  493. target_processor = PROCESSOR_V850;
  494. break;
  495. case bfd_mach_v850e:
  496. target_processor = PROCESSOR_V850E;
  497. break;
  498. case bfd_mach_v850e1:
  499. target_processor = PROCESSOR_V850E;
  500. break;
  501. case bfd_mach_v850e2:
  502. target_processor = PROCESSOR_V850E2;
  503. break;
  504. case bfd_mach_v850e2v3:
  505. target_processor = PROCESSOR_V850E2V3;
  506. break;
  507. case bfd_mach_v850e3v5:
  508. target_processor = PROCESSOR_V850E3V5;
  509. break;
  510. }
  511. status = info->read_memory_func (memaddr, buffer, 2, info);
  512. if (status)
  513. {
  514. info->memory_error_func (status, memaddr, info);
  515. return -1;
  516. }
  517. insn = bfd_getl16 (buffer);
  518. status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
  519. if (!status2)
  520. {
  521. insn2 = bfd_getl16 (buffer);
  522. /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
  523. }
  524. /* Special case. */
  525. if (length == 0
  526. && ((target_processor & PROCESSOR_V850E2_UP) != 0))
  527. {
  528. if ((insn & 0xffff) == 0x02e0 /* jr 32bit */
  529. && !status2 && (insn2 & 0x1) == 0)
  530. {
  531. length = 2;
  532. code_length = 6;
  533. }
  534. else if ((insn & 0xffe0) == 0x02e0 /* jarl 32bit */
  535. && !status2 && (insn2 & 0x1) == 0)
  536. {
  537. length = 2;
  538. code_length = 6;
  539. }
  540. else if ((insn & 0xffe0) == 0x06e0 /* jmp 32bit */
  541. && !status2 && (insn2 & 0x1) == 0)
  542. {
  543. length = 2;
  544. code_length = 6;
  545. }
  546. }
  547. if (length == 0
  548. && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
  549. {
  550. if ( ((insn & 0xffe0) == 0x07a0 /* ld.dw 23bit (v850e3v5) */
  551. && !status2 && (insn2 & 0x000f) == 0x0009)
  552. || ((insn & 0xffe0) == 0x07a0 /* st.dw 23bit (v850e3v5) */
  553. && !status2 && (insn2 & 0x000f) == 0x000f))
  554. {
  555. length = 4;
  556. code_length = 6;
  557. }
  558. }
  559. if (length == 0
  560. && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
  561. {
  562. if (((insn & 0xffe0) == 0x0780 /* ld.b 23bit */
  563. && !status2 && (insn2 & 0x000f) == 0x0005)
  564. || ((insn & 0xffe0) == 0x07a0 /* ld.bu 23bit */
  565. && !status2 && (insn2 & 0x000f) == 0x0005)
  566. || ((insn & 0xffe0) == 0x0780 /* ld.h 23bit */
  567. && !status2 && (insn2 & 0x000f) == 0x0007)
  568. || ((insn & 0xffe0) == 0x07a0 /* ld.hu 23bit */
  569. && !status2 && (insn2 & 0x000f) == 0x0007)
  570. || ((insn & 0xffe0) == 0x0780 /* ld.w 23bit */
  571. && !status2 && (insn2 & 0x000f) == 0x0009))
  572. {
  573. length = 4;
  574. code_length = 6;
  575. }
  576. else if (((insn & 0xffe0) == 0x0780 /* st.b 23bit */
  577. && !status2 && (insn2 & 0x000f) == 0x000d)
  578. || ((insn & 0xffe0) == 0x07a0 /* st.h 23bit */
  579. && !status2 && (insn2 & 0x000f) == 0x000d)
  580. || ((insn & 0xffe0) == 0x0780 /* st.w 23bit */
  581. && !status2 && (insn2 & 0x000f) == 0x000f))
  582. {
  583. length = 4;
  584. code_length = 6;
  585. }
  586. }
  587. if (length == 0
  588. && target_processor != PROCESSOR_V850)
  589. {
  590. if ((insn & 0xffe0) == 0x0620) /* 32 bit MOV */
  591. {
  592. length = 2;
  593. code_length = 6;
  594. }
  595. else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16<<16 */
  596. && !status2 && (insn2 & 0x001f) == 0x0013)
  597. {
  598. length = 4;
  599. code_length = 6;
  600. }
  601. else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16 */
  602. && !status2 && (insn2 & 0x001f) == 0x000b)
  603. {
  604. length = 4;
  605. code_length = 6;
  606. }
  607. else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm32 */
  608. && !status2 && (insn2 & 0x001f) == 0x001b)
  609. {
  610. length = 4;
  611. code_length = 8;
  612. }
  613. }
  614. if (length == 4
  615. || (length == 0
  616. && (insn & 0x0600) == 0x0600))
  617. {
  618. /* This is a 4 byte insn. */
  619. status = info->read_memory_func (memaddr, buffer, 4, info);
  620. if (!status)
  621. {
  622. insn = bfd_getl32 (buffer);
  623. if (!length)
  624. length = code_length = 4;
  625. }
  626. }
  627. if (code_length > length)
  628. {
  629. status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
  630. if (status)
  631. length = 0;
  632. }
  633. if (length == 0 && !status)
  634. length = code_length = 2;
  635. if (length == 2)
  636. insn &= 0xffff;
  637. /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
  638. if (length == 0)
  639. return -1;
  640. match = disassemble (memaddr, info, length, insn);
  641. if (!match)
  642. {
  643. int l = 0;
  644. status = info->read_memory_func (memaddr, buffer, code_length, info);
  645. while (l < code_length)
  646. {
  647. if (code_length - l == 2)
  648. {
  649. insn = bfd_getl16 (buffer + l) & 0xffff;
  650. info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
  651. l += 2;
  652. }
  653. else
  654. {
  655. insn = bfd_getl32 (buffer + l);
  656. info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
  657. l += 4;
  658. }
  659. }
  660. }
  661. return code_length;
  662. }