tic4x-dis.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. /* Print instructions for the Texas TMS320C[34]X, for GDB and GNU Binutils.
  2. Copyright (C) 2002-2015 Free Software Foundation, Inc.
  3. Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
  4. This file is part of the GNU opcodes library.
  5. This library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. It is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. #include "sysdep.h"
  18. #include <math.h>
  19. #include "libiberty.h"
  20. #include "dis-asm.h"
  21. #include "opcode/tic4x.h"
  22. #define TIC4X_DEBUG 0
  23. #define TIC4X_HASH_SIZE 11 /* 11 (bits) and above should give unique entries. */
  24. #define TIC4X_SPESOP_SIZE 8 /* Max 8. ops for special instructions. */
  25. typedef enum
  26. {
  27. IMMED_SINT,
  28. IMMED_SUINT,
  29. IMMED_SFLOAT,
  30. IMMED_INT,
  31. IMMED_UINT,
  32. IMMED_FLOAT
  33. }
  34. immed_t;
  35. typedef enum
  36. {
  37. INDIRECT_SHORT,
  38. INDIRECT_LONG,
  39. INDIRECT_TIC4X
  40. }
  41. indirect_t;
  42. static int tic4x_version = 0;
  43. static int tic4x_dp = 0;
  44. static int
  45. tic4x_pc_offset (unsigned int op)
  46. {
  47. /* Determine the PC offset for a C[34]x instruction.
  48. This could be simplified using some boolean algebra
  49. but at the expense of readability. */
  50. switch (op >> 24)
  51. {
  52. case 0x60: /* br */
  53. case 0x62: /* call (C4x) */
  54. case 0x64: /* rptb (C4x) */
  55. return 1;
  56. case 0x61: /* brd */
  57. case 0x63: /* laj */
  58. case 0x65: /* rptbd (C4x) */
  59. return 3;
  60. case 0x66: /* swi */
  61. case 0x67:
  62. return 0;
  63. default:
  64. break;
  65. }
  66. switch ((op & 0xffe00000) >> 20)
  67. {
  68. case 0x6a0: /* bB */
  69. case 0x720: /* callB */
  70. case 0x740: /* trapB */
  71. return 1;
  72. case 0x6a2: /* bBd */
  73. case 0x6a6: /* bBat */
  74. case 0x6aa: /* bBaf */
  75. case 0x722: /* lajB */
  76. case 0x748: /* latB */
  77. case 0x798: /* rptbd */
  78. return 3;
  79. default:
  80. break;
  81. }
  82. switch ((op & 0xfe200000) >> 20)
  83. {
  84. case 0x6e0: /* dbB */
  85. return 1;
  86. case 0x6e2: /* dbBd */
  87. return 3;
  88. default:
  89. break;
  90. }
  91. return 0;
  92. }
  93. static int
  94. tic4x_print_char (struct disassemble_info * info, char ch)
  95. {
  96. if (info != NULL)
  97. (*info->fprintf_func) (info->stream, "%c", ch);
  98. return 1;
  99. }
  100. static int
  101. tic4x_print_str (struct disassemble_info *info, char *str)
  102. {
  103. if (info != NULL)
  104. (*info->fprintf_func) (info->stream, "%s", str);
  105. return 1;
  106. }
  107. static int
  108. tic4x_print_register (struct disassemble_info *info, unsigned long regno)
  109. {
  110. static tic4x_register_t ** registertable = NULL;
  111. unsigned int i;
  112. if (registertable == NULL)
  113. {
  114. registertable = xmalloc (sizeof (tic4x_register_t *) * REG_TABLE_SIZE);
  115. for (i = 0; i < tic3x_num_registers; i++)
  116. registertable[tic3x_registers[i].regno] = (tic4x_register_t *) (tic3x_registers + i);
  117. if (IS_CPU_TIC4X (tic4x_version))
  118. {
  119. /* Add C4x additional registers, overwriting
  120. any C3x registers if necessary. */
  121. for (i = 0; i < tic4x_num_registers; i++)
  122. registertable[tic4x_registers[i].regno] =
  123. (tic4x_register_t *)(tic4x_registers + i);
  124. }
  125. }
  126. if ((int) regno > (IS_CPU_TIC4X (tic4x_version) ? TIC4X_REG_MAX : TIC3X_REG_MAX))
  127. return 0;
  128. if (info != NULL)
  129. (*info->fprintf_func) (info->stream, "%s", registertable[regno]->name);
  130. return 1;
  131. }
  132. static int
  133. tic4x_print_addr (struct disassemble_info *info, unsigned long addr)
  134. {
  135. if (info != NULL)
  136. (*info->print_address_func)(addr, info);
  137. return 1;
  138. }
  139. static int
  140. tic4x_print_relative (struct disassemble_info *info,
  141. unsigned long pc,
  142. long offset,
  143. unsigned long opcode)
  144. {
  145. return tic4x_print_addr (info, pc + offset + tic4x_pc_offset (opcode));
  146. }
  147. static int
  148. tic4x_print_direct (struct disassemble_info *info, unsigned long arg)
  149. {
  150. if (info != NULL)
  151. {
  152. (*info->fprintf_func) (info->stream, "@");
  153. tic4x_print_addr (info, arg + (tic4x_dp << 16));
  154. }
  155. return 1;
  156. }
  157. #if 0
  158. /* FIXME: make the floating point stuff not rely on host
  159. floating point arithmetic. */
  160. static void
  161. tic4x_print_ftoa (unsigned int val, FILE *stream, fprintf_ftype pfunc)
  162. {
  163. int e;
  164. int s;
  165. int f;
  166. double num = 0.0;
  167. e = EXTRS (val, 31, 24); /* Exponent. */
  168. if (e != -128)
  169. {
  170. s = EXTRU (val, 23, 23); /* Sign bit. */
  171. f = EXTRU (val, 22, 0); /* Mantissa. */
  172. if (s)
  173. f += -2 * (1 << 23);
  174. else
  175. f += (1 << 23);
  176. num = f / (double)(1 << 23);
  177. num = ldexp (num, e);
  178. }
  179. (*pfunc)(stream, "%.9g", num);
  180. }
  181. #endif
  182. static int
  183. tic4x_print_immed (struct disassemble_info *info,
  184. immed_t type,
  185. unsigned long arg)
  186. {
  187. int s;
  188. int f;
  189. int e;
  190. double num = 0.0;
  191. if (info == NULL)
  192. return 1;
  193. switch (type)
  194. {
  195. case IMMED_SINT:
  196. case IMMED_INT:
  197. (*info->fprintf_func) (info->stream, "%ld", (long) arg);
  198. break;
  199. case IMMED_SUINT:
  200. case IMMED_UINT:
  201. (*info->fprintf_func) (info->stream, "%lu", arg);
  202. break;
  203. case IMMED_SFLOAT:
  204. e = EXTRS (arg, 15, 12);
  205. if (e != -8)
  206. {
  207. s = EXTRU (arg, 11, 11);
  208. f = EXTRU (arg, 10, 0);
  209. if (s)
  210. f += -2 * (1 << 11);
  211. else
  212. f += (1 << 11);
  213. num = f / (double)(1 << 11);
  214. num = ldexp (num, e);
  215. }
  216. (*info->fprintf_func) (info->stream, "%f", num);
  217. break;
  218. case IMMED_FLOAT:
  219. e = EXTRS (arg, 31, 24);
  220. if (e != -128)
  221. {
  222. s = EXTRU (arg, 23, 23);
  223. f = EXTRU (arg, 22, 0);
  224. if (s)
  225. f += -2 * (1 << 23);
  226. else
  227. f += (1 << 23);
  228. num = f / (double)(1 << 23);
  229. num = ldexp (num, e);
  230. }
  231. (*info->fprintf_func) (info->stream, "%f", num);
  232. break;
  233. }
  234. return 1;
  235. }
  236. static int
  237. tic4x_print_cond (struct disassemble_info *info, unsigned int cond)
  238. {
  239. static tic4x_cond_t **condtable = NULL;
  240. unsigned int i;
  241. if (condtable == NULL)
  242. {
  243. condtable = xmalloc (sizeof (tic4x_cond_t *) * 32);
  244. for (i = 0; i < tic4x_num_conds; i++)
  245. condtable[tic4x_conds[i].cond] = (tic4x_cond_t *)(tic4x_conds + i);
  246. }
  247. if (cond > 31 || condtable[cond] == NULL)
  248. return 0;
  249. if (info != NULL)
  250. (*info->fprintf_func) (info->stream, "%s", condtable[cond]->name);
  251. return 1;
  252. }
  253. static int
  254. tic4x_print_indirect (struct disassemble_info *info,
  255. indirect_t type,
  256. unsigned long arg)
  257. {
  258. unsigned int aregno;
  259. unsigned int modn;
  260. unsigned int disp;
  261. char *a;
  262. aregno = 0;
  263. modn = 0;
  264. disp = 1;
  265. switch(type)
  266. {
  267. case INDIRECT_TIC4X: /* *+ARn(disp) */
  268. disp = EXTRU (arg, 7, 3);
  269. aregno = EXTRU (arg, 2, 0) + REG_AR0;
  270. modn = 0;
  271. break;
  272. case INDIRECT_SHORT:
  273. disp = 1;
  274. aregno = EXTRU (arg, 2, 0) + REG_AR0;
  275. modn = EXTRU (arg, 7, 3);
  276. break;
  277. case INDIRECT_LONG:
  278. disp = EXTRU (arg, 7, 0);
  279. aregno = EXTRU (arg, 10, 8) + REG_AR0;
  280. modn = EXTRU (arg, 15, 11);
  281. if (modn > 7 && disp != 0)
  282. return 0;
  283. break;
  284. default:
  285. (*info->fprintf_func)(info->stream, "# internal error: Unknown indirect type %d", type);
  286. return 0;
  287. }
  288. if (modn > TIC3X_MODN_MAX)
  289. return 0;
  290. a = tic4x_indirects[modn].name;
  291. while (*a)
  292. {
  293. switch (*a)
  294. {
  295. case 'a':
  296. tic4x_print_register (info, aregno);
  297. break;
  298. case 'd':
  299. tic4x_print_immed (info, IMMED_UINT, disp);
  300. break;
  301. case 'y':
  302. tic4x_print_str (info, "ir0");
  303. break;
  304. case 'z':
  305. tic4x_print_str (info, "ir1");
  306. break;
  307. default:
  308. tic4x_print_char (info, *a);
  309. break;
  310. }
  311. a++;
  312. }
  313. return 1;
  314. }
  315. static int
  316. tic4x_print_op (struct disassemble_info *info,
  317. unsigned long instruction,
  318. tic4x_inst_t *p,
  319. unsigned long pc)
  320. {
  321. int val;
  322. char *s;
  323. char *parallel = NULL;
  324. /* Print instruction name. */
  325. s = p->name;
  326. while (*s && parallel == NULL)
  327. {
  328. switch (*s)
  329. {
  330. case 'B':
  331. if (! tic4x_print_cond (info, EXTRU (instruction, 20, 16)))
  332. return 0;
  333. break;
  334. case 'C':
  335. if (! tic4x_print_cond (info, EXTRU (instruction, 27, 23)))
  336. return 0;
  337. break;
  338. case '_':
  339. parallel = s + 1; /* Skip past `_' in name. */
  340. break;
  341. default:
  342. tic4x_print_char (info, *s);
  343. break;
  344. }
  345. s++;
  346. }
  347. /* Print arguments. */
  348. s = p->args;
  349. if (*s)
  350. tic4x_print_char (info, ' ');
  351. while (*s)
  352. {
  353. switch (*s)
  354. {
  355. case '*': /* Indirect 0--15. */
  356. if (! tic4x_print_indirect (info, INDIRECT_LONG,
  357. EXTRU (instruction, 15, 0)))
  358. return 0;
  359. break;
  360. case '#': /* Only used for ldp, ldpk. */
  361. tic4x_print_immed (info, IMMED_UINT, EXTRU (instruction, 15, 0));
  362. break;
  363. case '@': /* Direct 0--15. */
  364. tic4x_print_direct (info, EXTRU (instruction, 15, 0));
  365. break;
  366. case 'A': /* Address register 24--22. */
  367. if (! tic4x_print_register (info, EXTRU (instruction, 24, 22) +
  368. REG_AR0))
  369. return 0;
  370. break;
  371. case 'B': /* 24-bit unsigned int immediate br(d)/call/rptb
  372. address 0--23. */
  373. if (IS_CPU_TIC4X (tic4x_version))
  374. tic4x_print_relative (info, pc, EXTRS (instruction, 23, 0),
  375. p->opcode);
  376. else
  377. tic4x_print_addr (info, EXTRU (instruction, 23, 0));
  378. break;
  379. case 'C': /* Indirect (short C4x) 0--7. */
  380. if (! IS_CPU_TIC4X (tic4x_version))
  381. return 0;
  382. if (! tic4x_print_indirect (info, INDIRECT_TIC4X,
  383. EXTRU (instruction, 7, 0)))
  384. return 0;
  385. break;
  386. case 'D':
  387. /* Cockup if get here... */
  388. break;
  389. case 'E': /* Register 0--7. */
  390. case 'e':
  391. if (! tic4x_print_register (info, EXTRU (instruction, 7, 0)))
  392. return 0;
  393. break;
  394. case 'F': /* 16-bit float immediate 0--15. */
  395. tic4x_print_immed (info, IMMED_SFLOAT,
  396. EXTRU (instruction, 15, 0));
  397. break;
  398. case 'i': /* Extended indirect 0--7. */
  399. if (EXTRU (instruction, 7, 5) == 7)
  400. {
  401. if (!tic4x_print_register (info, EXTRU (instruction, 4, 0)))
  402. return 0;
  403. break;
  404. }
  405. /* Fallthrough */
  406. case 'I': /* Indirect (short) 0--7. */
  407. if (! tic4x_print_indirect (info, INDIRECT_SHORT,
  408. EXTRU (instruction, 7, 0)))
  409. return 0;
  410. break;
  411. case 'j': /* Extended indirect 8--15 */
  412. if (EXTRU (instruction, 15, 13) == 7)
  413. {
  414. if (! tic4x_print_register (info, EXTRU (instruction, 12, 8)))
  415. return 0;
  416. break;
  417. }
  418. case 'J': /* Indirect (short) 8--15. */
  419. if (! tic4x_print_indirect (info, INDIRECT_SHORT,
  420. EXTRU (instruction, 15, 8)))
  421. return 0;
  422. break;
  423. case 'G': /* Register 8--15. */
  424. case 'g':
  425. if (! tic4x_print_register (info, EXTRU (instruction, 15, 8)))
  426. return 0;
  427. break;
  428. case 'H': /* Register 16--18. */
  429. if (! tic4x_print_register (info, EXTRU (instruction, 18, 16)))
  430. return 0;
  431. break;
  432. case 'K': /* Register 19--21. */
  433. if (! tic4x_print_register (info, EXTRU (instruction, 21, 19)))
  434. return 0;
  435. break;
  436. case 'L': /* Register 22--24. */
  437. if (! tic4x_print_register (info, EXTRU (instruction, 24, 22)))
  438. return 0;
  439. break;
  440. case 'M': /* Register 22--22. */
  441. tic4x_print_register (info, EXTRU (instruction, 22, 22) + REG_R2);
  442. break;
  443. case 'N': /* Register 23--23. */
  444. tic4x_print_register (info, EXTRU (instruction, 23, 23) + REG_R0);
  445. break;
  446. case 'O': /* Indirect (short C4x) 8--15. */
  447. if (! IS_CPU_TIC4X (tic4x_version))
  448. return 0;
  449. if (! tic4x_print_indirect (info, INDIRECT_TIC4X,
  450. EXTRU (instruction, 15, 8)))
  451. return 0;
  452. break;
  453. case 'P': /* Displacement 0--15 (used by Bcond and BcondD). */
  454. tic4x_print_relative (info, pc, EXTRS (instruction, 15, 0),
  455. p->opcode);
  456. break;
  457. case 'Q': /* Register 0--15. */
  458. case 'q':
  459. if (! tic4x_print_register (info, EXTRU (instruction, 15, 0)))
  460. return 0;
  461. break;
  462. case 'R': /* Register 16--20. */
  463. case 'r':
  464. if (! tic4x_print_register (info, EXTRU (instruction, 20, 16)))
  465. return 0;
  466. break;
  467. case 'S': /* 16-bit signed immediate 0--15. */
  468. tic4x_print_immed (info, IMMED_SINT,
  469. EXTRS (instruction, 15, 0));
  470. break;
  471. case 'T': /* 5-bit signed immediate 16--20 (C4x stik). */
  472. if (! IS_CPU_TIC4X (tic4x_version))
  473. return 0;
  474. if (! tic4x_print_immed (info, IMMED_SUINT,
  475. EXTRU (instruction, 20, 16)))
  476. return 0;
  477. break;
  478. case 'U': /* 16-bit unsigned int immediate 0--15. */
  479. tic4x_print_immed (info, IMMED_SUINT, EXTRU (instruction, 15, 0));
  480. break;
  481. case 'V': /* 5/9-bit unsigned vector 0--4/8. */
  482. tic4x_print_immed (info, IMMED_SUINT,
  483. IS_CPU_TIC4X (tic4x_version) ?
  484. EXTRU (instruction, 8, 0) :
  485. EXTRU (instruction, 4, 0) & ~0x20);
  486. break;
  487. case 'W': /* 8-bit signed immediate 0--7. */
  488. if (! IS_CPU_TIC4X (tic4x_version))
  489. return 0;
  490. tic4x_print_immed (info, IMMED_SINT, EXTRS (instruction, 7, 0));
  491. break;
  492. case 'X': /* Expansion register 4--0. */
  493. val = EXTRU (instruction, 4, 0) + REG_IVTP;
  494. if (val < REG_IVTP || val > REG_TVTP)
  495. return 0;
  496. if (! tic4x_print_register (info, val))
  497. return 0;
  498. break;
  499. case 'Y': /* Address register 16--20. */
  500. val = EXTRU (instruction, 20, 16);
  501. if (val < REG_AR0 || val > REG_SP)
  502. return 0;
  503. if (! tic4x_print_register (info, val))
  504. return 0;
  505. break;
  506. case 'Z': /* Expansion register 16--20. */
  507. val = EXTRU (instruction, 20, 16) + REG_IVTP;
  508. if (val < REG_IVTP || val > REG_TVTP)
  509. return 0;
  510. if (! tic4x_print_register (info, val))
  511. return 0;
  512. break;
  513. case '|': /* Parallel instruction. */
  514. tic4x_print_str (info, " || ");
  515. tic4x_print_str (info, parallel);
  516. tic4x_print_char (info, ' ');
  517. break;
  518. case ';':
  519. tic4x_print_char (info, ',');
  520. break;
  521. default:
  522. tic4x_print_char (info, *s);
  523. break;
  524. }
  525. s++;
  526. }
  527. return 1;
  528. }
  529. static void
  530. tic4x_hash_opcode_special (tic4x_inst_t **optable_special,
  531. const tic4x_inst_t *inst)
  532. {
  533. int i;
  534. for (i = 0;i < TIC4X_SPESOP_SIZE; i++)
  535. if (optable_special[i] != NULL
  536. && optable_special[i]->opcode == inst->opcode)
  537. {
  538. /* Collision (we have it already) - overwrite. */
  539. optable_special[i] = (tic4x_inst_t *) inst;
  540. return;
  541. }
  542. for (i = 0; i < TIC4X_SPESOP_SIZE; i++)
  543. if (optable_special[i] == NULL)
  544. {
  545. /* Add the new opcode. */
  546. optable_special[i] = (tic4x_inst_t *) inst;
  547. return;
  548. }
  549. /* This should never occur. This happens if the number of special
  550. instructions exceeds TIC4X_SPESOP_SIZE. Please increase the variable
  551. of this variable */
  552. #if TIC4X_DEBUG
  553. printf ("optable_special[] is full, please increase TIC4X_SPESOP_SIZE!\n");
  554. #endif
  555. }
  556. static void
  557. tic4x_hash_opcode (tic4x_inst_t **optable,
  558. tic4x_inst_t **optable_special,
  559. const tic4x_inst_t *inst,
  560. const unsigned long tic4x_oplevel)
  561. {
  562. int j;
  563. int opcode = inst->opcode >> (32 - TIC4X_HASH_SIZE);
  564. int opmask = inst->opmask >> (32 - TIC4X_HASH_SIZE);
  565. /* Use a TIC4X_HASH_SIZE bit index as a hash index. We should
  566. have unique entries so there's no point having a linked list
  567. for each entry? */
  568. for (j = opcode; j < opmask; j++)
  569. if ((j & opmask) == opcode
  570. && inst->oplevel & tic4x_oplevel)
  571. {
  572. #if TIC4X_DEBUG
  573. /* We should only have collisions for synonyms like
  574. ldp for ldi. */
  575. if (optable[j] != NULL)
  576. printf ("Collision at index %d, %s and %s\n",
  577. j, optable[j]->name, inst->name);
  578. #endif
  579. /* Catch those ops that collide with others already inside the
  580. hash, and have a opmask greater than the one we use in the
  581. hash. Store them in a special-list, that will handle full
  582. 32-bit INSN, not only the first 11-bit (or so). */
  583. if (optable[j] != NULL
  584. && inst->opmask & ~(opmask << (32 - TIC4X_HASH_SIZE)))
  585. {
  586. /* Add the instruction already on the list. */
  587. tic4x_hash_opcode_special (optable_special, optable[j]);
  588. /* Add the new instruction. */
  589. tic4x_hash_opcode_special (optable_special, inst);
  590. }
  591. optable[j] = (tic4x_inst_t *) inst;
  592. }
  593. }
  594. /* Disassemble the instruction in 'instruction'.
  595. 'pc' should be the address of this instruction, it will
  596. be used to print the target address if this is a relative jump or call
  597. the disassembled instruction is written to 'info'.
  598. The function returns the length of this instruction in words. */
  599. static int
  600. tic4x_disassemble (unsigned long pc,
  601. unsigned long instruction,
  602. struct disassemble_info *info)
  603. {
  604. static tic4x_inst_t **optable = NULL;
  605. static tic4x_inst_t **optable_special = NULL;
  606. tic4x_inst_t *p;
  607. int i;
  608. unsigned long tic4x_oplevel;
  609. tic4x_version = info->mach;
  610. tic4x_oplevel = (IS_CPU_TIC4X (tic4x_version)) ? OP_C4X : 0;
  611. tic4x_oplevel |= OP_C3X | OP_LPWR | OP_IDLE2 | OP_ENH;
  612. if (optable == NULL)
  613. {
  614. optable = xcalloc (sizeof (tic4x_inst_t *), (1 << TIC4X_HASH_SIZE));
  615. optable_special = xcalloc (sizeof (tic4x_inst_t *), TIC4X_SPESOP_SIZE);
  616. /* Install opcodes in reverse order so that preferred
  617. forms overwrite synonyms. */
  618. for (i = tic4x_num_insts - 1; i >= 0; i--)
  619. tic4x_hash_opcode (optable, optable_special, &tic4x_insts[i],
  620. tic4x_oplevel);
  621. /* We now need to remove the insn that are special from the
  622. "normal" optable, to make the disasm search this extra list
  623. for them. */
  624. for (i = 0; i < TIC4X_SPESOP_SIZE; i++)
  625. if (optable_special[i] != NULL)
  626. optable[optable_special[i]->opcode >> (32 - TIC4X_HASH_SIZE)] = NULL;
  627. }
  628. /* See if we can pick up any loading of the DP register... */
  629. if ((instruction >> 16) == 0x5070 || (instruction >> 16) == 0x1f70)
  630. tic4x_dp = EXTRU (instruction, 15, 0);
  631. p = optable[instruction >> (32 - TIC4X_HASH_SIZE)];
  632. if (p != NULL)
  633. {
  634. if (((instruction & p->opmask) == p->opcode)
  635. && tic4x_print_op (NULL, instruction, p, pc))
  636. tic4x_print_op (info, instruction, p, pc);
  637. else
  638. (*info->fprintf_func) (info->stream, "%08lx", instruction);
  639. }
  640. else
  641. {
  642. for (i = 0; i<TIC4X_SPESOP_SIZE; i++)
  643. if (optable_special[i] != NULL
  644. && optable_special[i]->opcode == instruction)
  645. {
  646. (*info->fprintf_func)(info->stream, "%s", optable_special[i]->name);
  647. break;
  648. }
  649. if (i == TIC4X_SPESOP_SIZE)
  650. (*info->fprintf_func) (info->stream, "%08lx", instruction);
  651. }
  652. /* Return size of insn in words. */
  653. return 1;
  654. }
  655. /* The entry point from objdump and gdb. */
  656. int
  657. print_insn_tic4x (bfd_vma memaddr, struct disassemble_info *info)
  658. {
  659. int status;
  660. unsigned long pc;
  661. unsigned long op;
  662. bfd_byte buffer[4];
  663. status = (*info->read_memory_func) (memaddr, buffer, 4, info);
  664. if (status != 0)
  665. {
  666. (*info->memory_error_func) (status, memaddr, info);
  667. return -1;
  668. }
  669. pc = memaddr;
  670. op = bfd_getl32 (buffer);
  671. info->bytes_per_line = 4;
  672. info->bytes_per_chunk = 4;
  673. info->octets_per_byte = 4;
  674. info->display_endian = BFD_ENDIAN_LITTLE;
  675. return tic4x_disassemble (pc, op, info) * 4;
  676. }