xtensa-isa.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794
  1. /* Configurable Xtensa ISA support.
  2. Copyright (C) 2003-2015 Free Software Foundation, Inc.
  3. This file is part of BFD, the Binary File Descriptor library.
  4. This program 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 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public 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 "bfd.h"
  18. #include "libbfd.h"
  19. #include "xtensa-isa.h"
  20. #include "xtensa-isa-internal.h"
  21. xtensa_isa_status xtisa_errno;
  22. char xtisa_error_msg[1024];
  23. xtensa_isa_status
  24. xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
  25. {
  26. return xtisa_errno;
  27. }
  28. char *
  29. xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
  30. {
  31. return xtisa_error_msg;
  32. }
  33. #define CHECK_ALLOC(MEM,ERRVAL) \
  34. do { \
  35. if ((MEM) == 0) \
  36. { \
  37. xtisa_errno = xtensa_isa_out_of_memory; \
  38. strcpy (xtisa_error_msg, "out of memory"); \
  39. return (ERRVAL); \
  40. } \
  41. } while (0)
  42. #define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
  43. do { \
  44. if ((MEM) == 0) \
  45. { \
  46. xtisa_errno = xtensa_isa_out_of_memory; \
  47. strcpy (xtisa_error_msg, "out of memory"); \
  48. if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
  49. if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
  50. return (ERRVAL); \
  51. } \
  52. } while (0)
  53. /* Instruction buffers. */
  54. int
  55. xtensa_insnbuf_size (xtensa_isa isa)
  56. {
  57. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  58. return intisa->insnbuf_size;
  59. }
  60. xtensa_insnbuf
  61. xtensa_insnbuf_alloc (xtensa_isa isa)
  62. {
  63. xtensa_insnbuf result = (xtensa_insnbuf)
  64. malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
  65. CHECK_ALLOC (result, 0);
  66. return result;
  67. }
  68. void
  69. xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
  70. xtensa_insnbuf buf)
  71. {
  72. free (buf);
  73. }
  74. /* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
  75. internal representation of a xtensa instruction word, return the index of
  76. its word and the bit index of its low order byte in the xtensa_insnbuf. */
  77. static inline int
  78. byte_to_word_index (int byte_index)
  79. {
  80. return byte_index / sizeof (xtensa_insnbuf_word);
  81. }
  82. static inline int
  83. byte_to_bit_index (int byte_index)
  84. {
  85. return (byte_index & 0x3) * 8;
  86. }
  87. /* Copy an instruction in the 32-bit words pointed at by "insn" to
  88. characters pointed at by "cp". This is more complicated than you
  89. might think because we want 16-bit instructions in bytes 2 & 3 for
  90. big-endian configurations. This function allows us to specify
  91. which byte in "insn" to start with and which way to increment,
  92. allowing trivial implementation for both big- and little-endian
  93. configurations....and it seems to make pretty good code for
  94. both. */
  95. int
  96. xtensa_insnbuf_to_chars (xtensa_isa isa,
  97. const xtensa_insnbuf insn,
  98. unsigned char *cp,
  99. int num_chars)
  100. {
  101. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  102. int insn_size = xtensa_isa_maxlength (isa);
  103. int fence_post, start, increment, i, byte_count;
  104. xtensa_format fmt;
  105. if (num_chars == 0)
  106. num_chars = insn_size;
  107. if (intisa->is_big_endian)
  108. {
  109. start = insn_size - 1;
  110. increment = -1;
  111. }
  112. else
  113. {
  114. start = 0;
  115. increment = 1;
  116. }
  117. /* Find the instruction format. Do nothing if the buffer does not contain
  118. a valid instruction since we need to know how many bytes to copy. */
  119. fmt = xtensa_format_decode (isa, insn);
  120. if (fmt == XTENSA_UNDEFINED)
  121. return XTENSA_UNDEFINED;
  122. byte_count = xtensa_format_length (isa, fmt);
  123. if (byte_count == XTENSA_UNDEFINED)
  124. return XTENSA_UNDEFINED;
  125. if (byte_count > num_chars)
  126. {
  127. xtisa_errno = xtensa_isa_buffer_overflow;
  128. strcpy (xtisa_error_msg, "output buffer too small for instruction");
  129. return XTENSA_UNDEFINED;
  130. }
  131. fence_post = start + (byte_count * increment);
  132. for (i = start; i != fence_post; i += increment, ++cp)
  133. {
  134. int word_inx = byte_to_word_index (i);
  135. int bit_inx = byte_to_bit_index (i);
  136. *cp = (insn[word_inx] >> bit_inx) & 0xff;
  137. }
  138. return byte_count;
  139. }
  140. /* Inward conversion from byte stream to xtensa_insnbuf. See
  141. xtensa_insnbuf_to_chars for a discussion of why this is complicated
  142. by endianness. */
  143. void
  144. xtensa_insnbuf_from_chars (xtensa_isa isa,
  145. xtensa_insnbuf insn,
  146. const unsigned char *cp,
  147. int num_chars)
  148. {
  149. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  150. int max_size, insn_size, fence_post, start, increment, i;
  151. max_size = xtensa_isa_maxlength (isa);
  152. /* Decode the instruction length so we know how many bytes to read. */
  153. insn_size = (intisa->length_decode_fn) (cp);
  154. if (insn_size == XTENSA_UNDEFINED)
  155. {
  156. /* This should never happen when the byte stream contains a
  157. valid instruction. Just read the maximum number of bytes.... */
  158. insn_size = max_size;
  159. }
  160. if (num_chars == 0 || num_chars > insn_size)
  161. num_chars = insn_size;
  162. if (intisa->is_big_endian)
  163. {
  164. start = max_size - 1;
  165. increment = -1;
  166. }
  167. else
  168. {
  169. start = 0;
  170. increment = 1;
  171. }
  172. fence_post = start + (num_chars * increment);
  173. memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
  174. for (i = start; i != fence_post; i += increment, ++cp)
  175. {
  176. int word_inx = byte_to_word_index (i);
  177. int bit_inx = byte_to_bit_index (i);
  178. insn[word_inx] |= (*cp & 0xff) << bit_inx;
  179. }
  180. }
  181. /* ISA information. */
  182. extern xtensa_isa_internal xtensa_modules;
  183. xtensa_isa
  184. xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
  185. {
  186. xtensa_isa_internal *isa = &xtensa_modules;
  187. int n, is_user;
  188. /* Set up the opcode name lookup table. */
  189. isa->opname_lookup_table =
  190. bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
  191. CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
  192. for (n = 0; n < isa->num_opcodes; n++)
  193. {
  194. isa->opname_lookup_table[n].key = isa->opcodes[n].name;
  195. isa->opname_lookup_table[n].u.opcode = n;
  196. }
  197. qsort (isa->opname_lookup_table, isa->num_opcodes,
  198. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  199. /* Set up the state name lookup table. */
  200. isa->state_lookup_table =
  201. bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
  202. CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
  203. for (n = 0; n < isa->num_states; n++)
  204. {
  205. isa->state_lookup_table[n].key = isa->states[n].name;
  206. isa->state_lookup_table[n].u.state = n;
  207. }
  208. qsort (isa->state_lookup_table, isa->num_states,
  209. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  210. /* Set up the sysreg name lookup table. */
  211. isa->sysreg_lookup_table =
  212. bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
  213. CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
  214. for (n = 0; n < isa->num_sysregs; n++)
  215. {
  216. isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
  217. isa->sysreg_lookup_table[n].u.sysreg = n;
  218. }
  219. qsort (isa->sysreg_lookup_table, isa->num_sysregs,
  220. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  221. /* Set up the user & system sysreg number tables. */
  222. for (is_user = 0; is_user < 2; is_user++)
  223. {
  224. isa->sysreg_table[is_user] =
  225. bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
  226. * sizeof (xtensa_sysreg));
  227. CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
  228. errno_p, error_msg_p);
  229. for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
  230. isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
  231. }
  232. for (n = 0; n < isa->num_sysregs; n++)
  233. {
  234. xtensa_sysreg_internal *sreg = &isa->sysregs[n];
  235. is_user = sreg->is_user;
  236. isa->sysreg_table[is_user][sreg->number] = n;
  237. }
  238. /* Set up the interface lookup table. */
  239. isa->interface_lookup_table =
  240. bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
  241. CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
  242. error_msg_p);
  243. for (n = 0; n < isa->num_interfaces; n++)
  244. {
  245. isa->interface_lookup_table[n].key = isa->interfaces[n].name;
  246. isa->interface_lookup_table[n].u.intf = n;
  247. }
  248. qsort (isa->interface_lookup_table, isa->num_interfaces,
  249. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  250. /* Set up the funcUnit lookup table. */
  251. isa->funcUnit_lookup_table =
  252. bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
  253. CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
  254. error_msg_p);
  255. for (n = 0; n < isa->num_funcUnits; n++)
  256. {
  257. isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
  258. isa->funcUnit_lookup_table[n].u.fun = n;
  259. }
  260. qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
  261. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  262. isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
  263. sizeof (xtensa_insnbuf_word));
  264. return (xtensa_isa) isa;
  265. }
  266. void
  267. xtensa_isa_free (xtensa_isa isa)
  268. {
  269. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  270. int n;
  271. /* With this version of the code, the xtensa_isa structure is not
  272. dynamically allocated, so this function is not essential. Free
  273. the memory allocated by xtensa_isa_init and restore the xtensa_isa
  274. structure to its initial state. */
  275. if (intisa->opname_lookup_table)
  276. {
  277. free (intisa->opname_lookup_table);
  278. intisa->opname_lookup_table = 0;
  279. }
  280. if (intisa->state_lookup_table)
  281. {
  282. free (intisa->state_lookup_table);
  283. intisa->state_lookup_table = 0;
  284. }
  285. if (intisa->sysreg_lookup_table)
  286. {
  287. free (intisa->sysreg_lookup_table);
  288. intisa->sysreg_lookup_table = 0;
  289. }
  290. for (n = 0; n < 2; n++)
  291. {
  292. if (intisa->sysreg_table[n])
  293. {
  294. free (intisa->sysreg_table[n]);
  295. intisa->sysreg_table[n] = 0;
  296. }
  297. }
  298. if (intisa->interface_lookup_table)
  299. {
  300. free (intisa->interface_lookup_table);
  301. intisa->interface_lookup_table = 0;
  302. }
  303. if (intisa->funcUnit_lookup_table)
  304. {
  305. free (intisa->funcUnit_lookup_table);
  306. intisa->funcUnit_lookup_table = 0;
  307. }
  308. }
  309. int
  310. xtensa_isa_name_compare (const void *v1, const void *v2)
  311. {
  312. xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
  313. xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
  314. return strcasecmp (e1->key, e2->key);
  315. }
  316. int
  317. xtensa_isa_maxlength (xtensa_isa isa)
  318. {
  319. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  320. return intisa->insn_size;
  321. }
  322. int
  323. xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
  324. {
  325. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  326. return (intisa->length_decode_fn) (cp);
  327. }
  328. int
  329. xtensa_isa_num_pipe_stages (xtensa_isa isa)
  330. {
  331. xtensa_opcode opcode;
  332. xtensa_funcUnit_use *use;
  333. int num_opcodes, num_uses;
  334. int i, stage;
  335. static int max_stage = XTENSA_UNDEFINED;
  336. /* Only compute the value once. */
  337. if (max_stage != XTENSA_UNDEFINED)
  338. return max_stage + 1;
  339. num_opcodes = xtensa_isa_num_opcodes (isa);
  340. for (opcode = 0; opcode < num_opcodes; opcode++)
  341. {
  342. num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
  343. for (i = 0; i < num_uses; i++)
  344. {
  345. use = xtensa_opcode_funcUnit_use (isa, opcode, i);
  346. stage = use->stage;
  347. if (stage > max_stage)
  348. max_stage = stage;
  349. }
  350. }
  351. return max_stage + 1;
  352. }
  353. int
  354. xtensa_isa_num_formats (xtensa_isa isa)
  355. {
  356. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  357. return intisa->num_formats;
  358. }
  359. int
  360. xtensa_isa_num_opcodes (xtensa_isa isa)
  361. {
  362. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  363. return intisa->num_opcodes;
  364. }
  365. int
  366. xtensa_isa_num_regfiles (xtensa_isa isa)
  367. {
  368. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  369. return intisa->num_regfiles;
  370. }
  371. int
  372. xtensa_isa_num_states (xtensa_isa isa)
  373. {
  374. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  375. return intisa->num_states;
  376. }
  377. int
  378. xtensa_isa_num_sysregs (xtensa_isa isa)
  379. {
  380. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  381. return intisa->num_sysregs;
  382. }
  383. int
  384. xtensa_isa_num_interfaces (xtensa_isa isa)
  385. {
  386. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  387. return intisa->num_interfaces;
  388. }
  389. int
  390. xtensa_isa_num_funcUnits (xtensa_isa isa)
  391. {
  392. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  393. return intisa->num_funcUnits;
  394. }
  395. /* Instruction formats. */
  396. #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
  397. do { \
  398. if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
  399. { \
  400. xtisa_errno = xtensa_isa_bad_format; \
  401. strcpy (xtisa_error_msg, "invalid format specifier"); \
  402. return (ERRVAL); \
  403. } \
  404. } while (0)
  405. #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
  406. do { \
  407. if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
  408. { \
  409. xtisa_errno = xtensa_isa_bad_slot; \
  410. strcpy (xtisa_error_msg, "invalid slot specifier"); \
  411. return (ERRVAL); \
  412. } \
  413. } while (0)
  414. const char *
  415. xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
  416. {
  417. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  418. CHECK_FORMAT (intisa, fmt, NULL);
  419. return intisa->formats[fmt].name;
  420. }
  421. xtensa_format
  422. xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
  423. {
  424. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  425. int fmt;
  426. if (!fmtname || !*fmtname)
  427. {
  428. xtisa_errno = xtensa_isa_bad_format;
  429. strcpy (xtisa_error_msg, "invalid format name");
  430. return XTENSA_UNDEFINED;
  431. }
  432. for (fmt = 0; fmt < intisa->num_formats; fmt++)
  433. {
  434. if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
  435. return fmt;
  436. }
  437. xtisa_errno = xtensa_isa_bad_format;
  438. sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
  439. return XTENSA_UNDEFINED;
  440. }
  441. xtensa_format
  442. xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
  443. {
  444. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  445. xtensa_format fmt;
  446. fmt = (intisa->format_decode_fn) (insn);
  447. if (fmt != XTENSA_UNDEFINED)
  448. return fmt;
  449. xtisa_errno = xtensa_isa_bad_format;
  450. strcpy (xtisa_error_msg, "cannot decode instruction format");
  451. return XTENSA_UNDEFINED;
  452. }
  453. int
  454. xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
  455. {
  456. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  457. CHECK_FORMAT (intisa, fmt, -1);
  458. (*intisa->formats[fmt].encode_fn) (insn);
  459. return 0;
  460. }
  461. int
  462. xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
  463. {
  464. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  465. CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  466. return intisa->formats[fmt].length;
  467. }
  468. int
  469. xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
  470. {
  471. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  472. CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  473. return intisa->formats[fmt].num_slots;
  474. }
  475. xtensa_opcode
  476. xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
  477. {
  478. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  479. int slot_id;
  480. CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  481. CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
  482. slot_id = intisa->formats[fmt].slot_id[slot];
  483. return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
  484. }
  485. int
  486. xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
  487. const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
  488. {
  489. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  490. int slot_id;
  491. CHECK_FORMAT (intisa, fmt, -1);
  492. CHECK_SLOT (intisa, fmt, slot, -1);
  493. slot_id = intisa->formats[fmt].slot_id[slot];
  494. (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
  495. return 0;
  496. }
  497. int
  498. xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
  499. xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
  500. {
  501. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  502. int slot_id;
  503. CHECK_FORMAT (intisa, fmt, -1);
  504. CHECK_SLOT (intisa, fmt, slot, -1);
  505. slot_id = intisa->formats[fmt].slot_id[slot];
  506. (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
  507. return 0;
  508. }
  509. /* Opcode information. */
  510. #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
  511. do { \
  512. if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
  513. { \
  514. xtisa_errno = xtensa_isa_bad_opcode; \
  515. strcpy (xtisa_error_msg, "invalid opcode specifier"); \
  516. return (ERRVAL); \
  517. } \
  518. } while (0)
  519. xtensa_opcode
  520. xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
  521. {
  522. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  523. xtensa_lookup_entry entry, *result = 0;
  524. if (!opname || !*opname)
  525. {
  526. xtisa_errno = xtensa_isa_bad_opcode;
  527. strcpy (xtisa_error_msg, "invalid opcode name");
  528. return XTENSA_UNDEFINED;
  529. }
  530. if (intisa->num_opcodes != 0)
  531. {
  532. entry.key = opname;
  533. result = bsearch (&entry, intisa->opname_lookup_table,
  534. intisa->num_opcodes, sizeof (xtensa_lookup_entry),
  535. xtensa_isa_name_compare);
  536. }
  537. if (!result)
  538. {
  539. xtisa_errno = xtensa_isa_bad_opcode;
  540. sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
  541. return XTENSA_UNDEFINED;
  542. }
  543. return result->u.opcode;
  544. }
  545. xtensa_opcode
  546. xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
  547. const xtensa_insnbuf slotbuf)
  548. {
  549. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  550. int slot_id;
  551. xtensa_opcode opc;
  552. CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  553. CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
  554. slot_id = intisa->formats[fmt].slot_id[slot];
  555. opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
  556. if (opc != XTENSA_UNDEFINED)
  557. return opc;
  558. xtisa_errno = xtensa_isa_bad_opcode;
  559. strcpy (xtisa_error_msg, "cannot decode opcode");
  560. return XTENSA_UNDEFINED;
  561. }
  562. int
  563. xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
  564. xtensa_insnbuf slotbuf, xtensa_opcode opc)
  565. {
  566. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  567. int slot_id;
  568. xtensa_opcode_encode_fn encode_fn;
  569. CHECK_FORMAT (intisa, fmt, -1);
  570. CHECK_SLOT (intisa, fmt, slot, -1);
  571. CHECK_OPCODE (intisa, opc, -1);
  572. slot_id = intisa->formats[fmt].slot_id[slot];
  573. encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
  574. if (!encode_fn)
  575. {
  576. xtisa_errno = xtensa_isa_wrong_slot;
  577. sprintf (xtisa_error_msg,
  578. "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
  579. intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
  580. return -1;
  581. }
  582. (*encode_fn) (slotbuf);
  583. return 0;
  584. }
  585. const char *
  586. xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
  587. {
  588. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  589. CHECK_OPCODE (intisa, opc, NULL);
  590. return intisa->opcodes[opc].name;
  591. }
  592. int
  593. xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
  594. {
  595. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  596. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  597. if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
  598. return 1;
  599. return 0;
  600. }
  601. int
  602. xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
  603. {
  604. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  605. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  606. if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
  607. return 1;
  608. return 0;
  609. }
  610. int
  611. xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
  612. {
  613. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  614. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  615. if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
  616. return 1;
  617. return 0;
  618. }
  619. int
  620. xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
  621. {
  622. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  623. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  624. if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
  625. return 1;
  626. return 0;
  627. }
  628. int
  629. xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
  630. {
  631. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  632. int iclass_id;
  633. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  634. iclass_id = intisa->opcodes[opc].iclass_id;
  635. return intisa->iclasses[iclass_id].num_operands;
  636. }
  637. int
  638. xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
  639. {
  640. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  641. int iclass_id;
  642. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  643. iclass_id = intisa->opcodes[opc].iclass_id;
  644. return intisa->iclasses[iclass_id].num_stateOperands;
  645. }
  646. int
  647. xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
  648. {
  649. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  650. int iclass_id;
  651. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  652. iclass_id = intisa->opcodes[opc].iclass_id;
  653. return intisa->iclasses[iclass_id].num_interfaceOperands;
  654. }
  655. int
  656. xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
  657. {
  658. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  659. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  660. return intisa->opcodes[opc].num_funcUnit_uses;
  661. }
  662. xtensa_funcUnit_use *
  663. xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
  664. {
  665. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  666. CHECK_OPCODE (intisa, opc, NULL);
  667. if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
  668. {
  669. xtisa_errno = xtensa_isa_bad_funcUnit;
  670. sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
  671. "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
  672. intisa->opcodes[opc].num_funcUnit_uses);
  673. return NULL;
  674. }
  675. return &intisa->opcodes[opc].funcUnit_uses[u];
  676. }
  677. /* Operand information. */
  678. #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
  679. do { \
  680. if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
  681. { \
  682. xtisa_errno = xtensa_isa_bad_operand; \
  683. sprintf (xtisa_error_msg, "invalid operand number (%d); " \
  684. "opcode \"%s\" has %d operands", (OPND), \
  685. (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
  686. return (ERRVAL); \
  687. } \
  688. } while (0)
  689. static xtensa_operand_internal *
  690. get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
  691. {
  692. xtensa_iclass_internal *iclass;
  693. int iclass_id, operand_id;
  694. CHECK_OPCODE (intisa, opc, NULL);
  695. iclass_id = intisa->opcodes[opc].iclass_id;
  696. iclass = &intisa->iclasses[iclass_id];
  697. CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
  698. operand_id = iclass->operands[opnd].u.operand_id;
  699. return &intisa->operands[operand_id];
  700. }
  701. const char *
  702. xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
  703. {
  704. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  705. xtensa_operand_internal *intop;
  706. intop = get_operand (intisa, opc, opnd);
  707. if (!intop) return NULL;
  708. return intop->name;
  709. }
  710. int
  711. xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
  712. {
  713. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  714. xtensa_iclass_internal *iclass;
  715. int iclass_id, operand_id;
  716. xtensa_operand_internal *intop;
  717. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  718. iclass_id = intisa->opcodes[opc].iclass_id;
  719. iclass = &intisa->iclasses[iclass_id];
  720. CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
  721. /* Special case for "sout" operands. */
  722. if (iclass->operands[opnd].inout == 's')
  723. return 0;
  724. operand_id = iclass->operands[opnd].u.operand_id;
  725. intop = &intisa->operands[operand_id];
  726. if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
  727. return 1;
  728. return 0;
  729. }
  730. char
  731. xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
  732. {
  733. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  734. xtensa_iclass_internal *iclass;
  735. int iclass_id;
  736. char inout;
  737. CHECK_OPCODE (intisa, opc, 0);
  738. iclass_id = intisa->opcodes[opc].iclass_id;
  739. iclass = &intisa->iclasses[iclass_id];
  740. CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
  741. inout = iclass->operands[opnd].inout;
  742. /* Special case for "sout" operands. */
  743. if (inout == 's')
  744. return 'o';
  745. return inout;
  746. }
  747. int
  748. xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
  749. xtensa_format fmt, int slot,
  750. const xtensa_insnbuf slotbuf, uint32 *valp)
  751. {
  752. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  753. xtensa_operand_internal *intop;
  754. int slot_id;
  755. xtensa_get_field_fn get_fn;
  756. intop = get_operand (intisa, opc, opnd);
  757. if (!intop) return -1;
  758. CHECK_FORMAT (intisa, fmt, -1);
  759. CHECK_SLOT (intisa, fmt, slot, -1);
  760. slot_id = intisa->formats[fmt].slot_id[slot];
  761. if (intop->field_id == XTENSA_UNDEFINED)
  762. {
  763. xtisa_errno = xtensa_isa_no_field;
  764. strcpy (xtisa_error_msg, "implicit operand has no field");
  765. return -1;
  766. }
  767. get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
  768. if (!get_fn)
  769. {
  770. xtisa_errno = xtensa_isa_wrong_slot;
  771. sprintf (xtisa_error_msg,
  772. "operand \"%s\" does not exist in slot %d of format \"%s\"",
  773. intop->name, slot, intisa->formats[fmt].name);
  774. return -1;
  775. }
  776. *valp = (*get_fn) (slotbuf);
  777. return 0;
  778. }
  779. int
  780. xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
  781. xtensa_format fmt, int slot,
  782. xtensa_insnbuf slotbuf, uint32 val)
  783. {
  784. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  785. xtensa_operand_internal *intop;
  786. int slot_id;
  787. xtensa_set_field_fn set_fn;
  788. intop = get_operand (intisa, opc, opnd);
  789. if (!intop) return -1;
  790. CHECK_FORMAT (intisa, fmt, -1);
  791. CHECK_SLOT (intisa, fmt, slot, -1);
  792. slot_id = intisa->formats[fmt].slot_id[slot];
  793. if (intop->field_id == XTENSA_UNDEFINED)
  794. {
  795. xtisa_errno = xtensa_isa_no_field;
  796. strcpy (xtisa_error_msg, "implicit operand has no field");
  797. return -1;
  798. }
  799. set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
  800. if (!set_fn)
  801. {
  802. xtisa_errno = xtensa_isa_wrong_slot;
  803. sprintf (xtisa_error_msg,
  804. "operand \"%s\" does not exist in slot %d of format \"%s\"",
  805. intop->name, slot, intisa->formats[fmt].name);
  806. return -1;
  807. }
  808. (*set_fn) (slotbuf, val);
  809. return 0;
  810. }
  811. int
  812. xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
  813. uint32 *valp)
  814. {
  815. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  816. xtensa_operand_internal *intop;
  817. uint32 test_val, orig_val;
  818. intop = get_operand (intisa, opc, opnd);
  819. if (!intop)
  820. return -1;
  821. if (!intop->encode)
  822. {
  823. /* This is a default operand for a field. How can we tell if the
  824. value fits in the field? Write the value into the field,
  825. read it back, and then make sure we get the same value. */
  826. static xtensa_insnbuf tmpbuf = 0;
  827. int slot_id;
  828. if (!tmpbuf)
  829. {
  830. tmpbuf = xtensa_insnbuf_alloc (isa);
  831. CHECK_ALLOC (tmpbuf, -1);
  832. }
  833. /* A default operand is always associated with a field,
  834. but check just to be sure.... */
  835. if (intop->field_id == XTENSA_UNDEFINED)
  836. {
  837. xtisa_errno = xtensa_isa_internal_error;
  838. strcpy (xtisa_error_msg, "operand has no field");
  839. return -1;
  840. }
  841. /* Find some slot that includes the field. */
  842. for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
  843. {
  844. xtensa_get_field_fn get_fn =
  845. intisa->slots[slot_id].get_field_fns[intop->field_id];
  846. xtensa_set_field_fn set_fn =
  847. intisa->slots[slot_id].set_field_fns[intop->field_id];
  848. if (get_fn && set_fn)
  849. {
  850. (*set_fn) (tmpbuf, *valp);
  851. return ((*get_fn) (tmpbuf) != *valp);
  852. }
  853. }
  854. /* Couldn't find any slot containing the field.... */
  855. xtisa_errno = xtensa_isa_no_field;
  856. strcpy (xtisa_error_msg, "field does not exist in any slot");
  857. return -1;
  858. }
  859. /* Encode the value. In some cases, the encoding function may detect
  860. errors, but most of the time the only way to determine if the value
  861. was successfully encoded is to decode it and check if it matches
  862. the original value. */
  863. orig_val = *valp;
  864. if ((*intop->encode) (valp)
  865. || (test_val = *valp, (*intop->decode) (&test_val))
  866. || test_val != orig_val)
  867. {
  868. xtisa_errno = xtensa_isa_bad_value;
  869. sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
  870. return -1;
  871. }
  872. return 0;
  873. }
  874. int
  875. xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
  876. uint32 *valp)
  877. {
  878. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  879. xtensa_operand_internal *intop;
  880. intop = get_operand (intisa, opc, opnd);
  881. if (!intop) return -1;
  882. /* Use identity function for "default" operands. */
  883. if (!intop->decode)
  884. return 0;
  885. if ((*intop->decode) (valp))
  886. {
  887. xtisa_errno = xtensa_isa_bad_value;
  888. sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
  889. return -1;
  890. }
  891. return 0;
  892. }
  893. int
  894. xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
  895. {
  896. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  897. xtensa_operand_internal *intop;
  898. intop = get_operand (intisa, opc, opnd);
  899. if (!intop) return XTENSA_UNDEFINED;
  900. if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
  901. return 1;
  902. return 0;
  903. }
  904. xtensa_regfile
  905. xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
  906. {
  907. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  908. xtensa_operand_internal *intop;
  909. intop = get_operand (intisa, opc, opnd);
  910. if (!intop) return XTENSA_UNDEFINED;
  911. return intop->regfile;
  912. }
  913. int
  914. xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
  915. {
  916. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  917. xtensa_operand_internal *intop;
  918. intop = get_operand (intisa, opc, opnd);
  919. if (!intop) return XTENSA_UNDEFINED;
  920. return intop->num_regs;
  921. }
  922. int
  923. xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
  924. {
  925. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  926. xtensa_operand_internal *intop;
  927. intop = get_operand (intisa, opc, opnd);
  928. if (!intop) return XTENSA_UNDEFINED;
  929. if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
  930. return 1;
  931. return 0;
  932. }
  933. int
  934. xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
  935. {
  936. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  937. xtensa_operand_internal *intop;
  938. intop = get_operand (intisa, opc, opnd);
  939. if (!intop) return XTENSA_UNDEFINED;
  940. if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
  941. return 1;
  942. return 0;
  943. }
  944. int
  945. xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
  946. uint32 *valp, uint32 pc)
  947. {
  948. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  949. xtensa_operand_internal *intop;
  950. intop = get_operand (intisa, opc, opnd);
  951. if (!intop) return -1;
  952. if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
  953. return 0;
  954. if (!intop->do_reloc)
  955. {
  956. xtisa_errno = xtensa_isa_internal_error;
  957. strcpy (xtisa_error_msg, "operand missing do_reloc function");
  958. return -1;
  959. }
  960. if ((*intop->do_reloc) (valp, pc))
  961. {
  962. xtisa_errno = xtensa_isa_bad_value;
  963. sprintf (xtisa_error_msg,
  964. "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
  965. return -1;
  966. }
  967. return 0;
  968. }
  969. int
  970. xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
  971. uint32 *valp, uint32 pc)
  972. {
  973. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  974. xtensa_operand_internal *intop;
  975. intop = get_operand (intisa, opc, opnd);
  976. if (!intop) return -1;
  977. if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
  978. return 0;
  979. if (!intop->undo_reloc)
  980. {
  981. xtisa_errno = xtensa_isa_internal_error;
  982. strcpy (xtisa_error_msg, "operand missing undo_reloc function");
  983. return -1;
  984. }
  985. if ((*intop->undo_reloc) (valp, pc))
  986. {
  987. xtisa_errno = xtensa_isa_bad_value;
  988. sprintf (xtisa_error_msg,
  989. "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
  990. return -1;
  991. }
  992. return 0;
  993. }
  994. /* State Operands. */
  995. #define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
  996. do { \
  997. if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
  998. { \
  999. xtisa_errno = xtensa_isa_bad_operand; \
  1000. sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
  1001. "opcode \"%s\" has %d state operands", (STOP), \
  1002. (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
  1003. return (ERRVAL); \
  1004. } \
  1005. } while (0)
  1006. xtensa_state
  1007. xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
  1008. {
  1009. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1010. xtensa_iclass_internal *iclass;
  1011. int iclass_id;
  1012. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  1013. iclass_id = intisa->opcodes[opc].iclass_id;
  1014. iclass = &intisa->iclasses[iclass_id];
  1015. CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
  1016. return iclass->stateOperands[stOp].u.state;
  1017. }
  1018. char
  1019. xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
  1020. {
  1021. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1022. xtensa_iclass_internal *iclass;
  1023. int iclass_id;
  1024. CHECK_OPCODE (intisa, opc, 0);
  1025. iclass_id = intisa->opcodes[opc].iclass_id;
  1026. iclass = &intisa->iclasses[iclass_id];
  1027. CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
  1028. return iclass->stateOperands[stOp].inout;
  1029. }
  1030. /* Interface Operands. */
  1031. #define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
  1032. do { \
  1033. if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
  1034. { \
  1035. xtisa_errno = xtensa_isa_bad_operand; \
  1036. sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
  1037. "opcode \"%s\" has %d interface operands", (IFOP), \
  1038. (INTISA)->opcodes[(OPC)].name, \
  1039. (ICLASS)->num_interfaceOperands); \
  1040. return (ERRVAL); \
  1041. } \
  1042. } while (0)
  1043. xtensa_interface
  1044. xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
  1045. int ifOp)
  1046. {
  1047. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1048. xtensa_iclass_internal *iclass;
  1049. int iclass_id;
  1050. CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  1051. iclass_id = intisa->opcodes[opc].iclass_id;
  1052. iclass = &intisa->iclasses[iclass_id];
  1053. CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
  1054. return iclass->interfaceOperands[ifOp];
  1055. }
  1056. /* Register Files. */
  1057. #define CHECK_REGFILE(INTISA,RF,ERRVAL) \
  1058. do { \
  1059. if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
  1060. { \
  1061. xtisa_errno = xtensa_isa_bad_regfile; \
  1062. strcpy (xtisa_error_msg, "invalid regfile specifier"); \
  1063. return (ERRVAL); \
  1064. } \
  1065. } while (0)
  1066. xtensa_regfile
  1067. xtensa_regfile_lookup (xtensa_isa isa, const char *name)
  1068. {
  1069. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1070. int n;
  1071. if (!name || !*name)
  1072. {
  1073. xtisa_errno = xtensa_isa_bad_regfile;
  1074. strcpy (xtisa_error_msg, "invalid regfile name");
  1075. return XTENSA_UNDEFINED;
  1076. }
  1077. /* The expected number of regfiles is small; use a linear search. */
  1078. for (n = 0; n < intisa->num_regfiles; n++)
  1079. {
  1080. if (!filename_cmp (intisa->regfiles[n].name, name))
  1081. return n;
  1082. }
  1083. xtisa_errno = xtensa_isa_bad_regfile;
  1084. sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
  1085. return XTENSA_UNDEFINED;
  1086. }
  1087. xtensa_regfile
  1088. xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
  1089. {
  1090. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1091. int n;
  1092. if (!shortname || !*shortname)
  1093. {
  1094. xtisa_errno = xtensa_isa_bad_regfile;
  1095. strcpy (xtisa_error_msg, "invalid regfile shortname");
  1096. return XTENSA_UNDEFINED;
  1097. }
  1098. /* The expected number of regfiles is small; use a linear search. */
  1099. for (n = 0; n < intisa->num_regfiles; n++)
  1100. {
  1101. /* Ignore regfile views since they always have the same shortnames
  1102. as their parents. */
  1103. if (intisa->regfiles[n].parent != n)
  1104. continue;
  1105. if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
  1106. return n;
  1107. }
  1108. xtisa_errno = xtensa_isa_bad_regfile;
  1109. sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
  1110. shortname);
  1111. return XTENSA_UNDEFINED;
  1112. }
  1113. const char *
  1114. xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
  1115. {
  1116. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1117. CHECK_REGFILE (intisa, rf, NULL);
  1118. return intisa->regfiles[rf].name;
  1119. }
  1120. const char *
  1121. xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
  1122. {
  1123. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1124. CHECK_REGFILE (intisa, rf, NULL);
  1125. return intisa->regfiles[rf].shortname;
  1126. }
  1127. xtensa_regfile
  1128. xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
  1129. {
  1130. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1131. CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  1132. return intisa->regfiles[rf].parent;
  1133. }
  1134. int
  1135. xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
  1136. {
  1137. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1138. CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  1139. return intisa->regfiles[rf].num_bits;
  1140. }
  1141. int
  1142. xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
  1143. {
  1144. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1145. CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  1146. return intisa->regfiles[rf].num_entries;
  1147. }
  1148. /* Processor States. */
  1149. #define CHECK_STATE(INTISA,ST,ERRVAL) \
  1150. do { \
  1151. if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
  1152. { \
  1153. xtisa_errno = xtensa_isa_bad_state; \
  1154. strcpy (xtisa_error_msg, "invalid state specifier"); \
  1155. return (ERRVAL); \
  1156. } \
  1157. } while (0)
  1158. xtensa_state
  1159. xtensa_state_lookup (xtensa_isa isa, const char *name)
  1160. {
  1161. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1162. xtensa_lookup_entry entry, *result = 0;
  1163. if (!name || !*name)
  1164. {
  1165. xtisa_errno = xtensa_isa_bad_state;
  1166. strcpy (xtisa_error_msg, "invalid state name");
  1167. return XTENSA_UNDEFINED;
  1168. }
  1169. if (intisa->num_states != 0)
  1170. {
  1171. entry.key = name;
  1172. result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
  1173. sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
  1174. }
  1175. if (!result)
  1176. {
  1177. xtisa_errno = xtensa_isa_bad_state;
  1178. sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
  1179. return XTENSA_UNDEFINED;
  1180. }
  1181. return result->u.state;
  1182. }
  1183. const char *
  1184. xtensa_state_name (xtensa_isa isa, xtensa_state st)
  1185. {
  1186. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1187. CHECK_STATE (intisa, st, NULL);
  1188. return intisa->states[st].name;
  1189. }
  1190. int
  1191. xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
  1192. {
  1193. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1194. CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  1195. return intisa->states[st].num_bits;
  1196. }
  1197. int
  1198. xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
  1199. {
  1200. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1201. CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  1202. if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
  1203. return 1;
  1204. return 0;
  1205. }
  1206. int
  1207. xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
  1208. {
  1209. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1210. CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  1211. if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
  1212. return 1;
  1213. return 0;
  1214. }
  1215. /* Sysregs. */
  1216. #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
  1217. do { \
  1218. if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
  1219. { \
  1220. xtisa_errno = xtensa_isa_bad_sysreg; \
  1221. strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
  1222. return (ERRVAL); \
  1223. } \
  1224. } while (0)
  1225. xtensa_sysreg
  1226. xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
  1227. {
  1228. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1229. if (is_user != 0)
  1230. is_user = 1;
  1231. if (num < 0 || num > intisa->max_sysreg_num[is_user]
  1232. || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
  1233. {
  1234. xtisa_errno = xtensa_isa_bad_sysreg;
  1235. strcpy (xtisa_error_msg, "sysreg not recognized");
  1236. return XTENSA_UNDEFINED;
  1237. }
  1238. return intisa->sysreg_table[is_user][num];
  1239. }
  1240. xtensa_sysreg
  1241. xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
  1242. {
  1243. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1244. xtensa_lookup_entry entry, *result = 0;
  1245. if (!name || !*name)
  1246. {
  1247. xtisa_errno = xtensa_isa_bad_sysreg;
  1248. strcpy (xtisa_error_msg, "invalid sysreg name");
  1249. return XTENSA_UNDEFINED;
  1250. }
  1251. if (intisa->num_sysregs != 0)
  1252. {
  1253. entry.key = name;
  1254. result = bsearch (&entry, intisa->sysreg_lookup_table,
  1255. intisa->num_sysregs, sizeof (xtensa_lookup_entry),
  1256. xtensa_isa_name_compare);
  1257. }
  1258. if (!result)
  1259. {
  1260. xtisa_errno = xtensa_isa_bad_sysreg;
  1261. sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
  1262. return XTENSA_UNDEFINED;
  1263. }
  1264. return result->u.sysreg;
  1265. }
  1266. const char *
  1267. xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
  1268. {
  1269. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1270. CHECK_SYSREG (intisa, sysreg, NULL);
  1271. return intisa->sysregs[sysreg].name;
  1272. }
  1273. int
  1274. xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
  1275. {
  1276. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1277. CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  1278. return intisa->sysregs[sysreg].number;
  1279. }
  1280. int
  1281. xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
  1282. {
  1283. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1284. CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  1285. if (intisa->sysregs[sysreg].is_user)
  1286. return 1;
  1287. return 0;
  1288. }
  1289. /* Interfaces. */
  1290. #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
  1291. do { \
  1292. if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
  1293. { \
  1294. xtisa_errno = xtensa_isa_bad_interface; \
  1295. strcpy (xtisa_error_msg, "invalid interface specifier"); \
  1296. return (ERRVAL); \
  1297. } \
  1298. } while (0)
  1299. xtensa_interface
  1300. xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
  1301. {
  1302. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1303. xtensa_lookup_entry entry, *result = 0;
  1304. if (!ifname || !*ifname)
  1305. {
  1306. xtisa_errno = xtensa_isa_bad_interface;
  1307. strcpy (xtisa_error_msg, "invalid interface name");
  1308. return XTENSA_UNDEFINED;
  1309. }
  1310. if (intisa->num_interfaces != 0)
  1311. {
  1312. entry.key = ifname;
  1313. result = bsearch (&entry, intisa->interface_lookup_table,
  1314. intisa->num_interfaces, sizeof (xtensa_lookup_entry),
  1315. xtensa_isa_name_compare);
  1316. }
  1317. if (!result)
  1318. {
  1319. xtisa_errno = xtensa_isa_bad_interface;
  1320. sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
  1321. return XTENSA_UNDEFINED;
  1322. }
  1323. return result->u.intf;
  1324. }
  1325. const char *
  1326. xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
  1327. {
  1328. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1329. CHECK_INTERFACE (intisa, intf, NULL);
  1330. return intisa->interfaces[intf].name;
  1331. }
  1332. int
  1333. xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
  1334. {
  1335. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1336. CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  1337. return intisa->interfaces[intf].num_bits;
  1338. }
  1339. char
  1340. xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
  1341. {
  1342. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1343. CHECK_INTERFACE (intisa, intf, 0);
  1344. return intisa->interfaces[intf].inout;
  1345. }
  1346. int
  1347. xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
  1348. {
  1349. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1350. CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  1351. if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
  1352. return 1;
  1353. return 0;
  1354. }
  1355. int
  1356. xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
  1357. {
  1358. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1359. CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  1360. return intisa->interfaces[intf].class_id;
  1361. }
  1362. /* Functional Units. */
  1363. #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
  1364. do { \
  1365. if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
  1366. { \
  1367. xtisa_errno = xtensa_isa_bad_funcUnit; \
  1368. strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
  1369. return (ERRVAL); \
  1370. } \
  1371. } while (0)
  1372. xtensa_funcUnit
  1373. xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
  1374. {
  1375. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1376. xtensa_lookup_entry entry, *result = 0;
  1377. if (!fname || !*fname)
  1378. {
  1379. xtisa_errno = xtensa_isa_bad_funcUnit;
  1380. strcpy (xtisa_error_msg, "invalid functional unit name");
  1381. return XTENSA_UNDEFINED;
  1382. }
  1383. if (intisa->num_funcUnits != 0)
  1384. {
  1385. entry.key = fname;
  1386. result = bsearch (&entry, intisa->funcUnit_lookup_table,
  1387. intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
  1388. xtensa_isa_name_compare);
  1389. }
  1390. if (!result)
  1391. {
  1392. xtisa_errno = xtensa_isa_bad_funcUnit;
  1393. sprintf (xtisa_error_msg,
  1394. "functional unit \"%s\" not recognized", fname);
  1395. return XTENSA_UNDEFINED;
  1396. }
  1397. return result->u.fun;
  1398. }
  1399. const char *
  1400. xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
  1401. {
  1402. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1403. CHECK_FUNCUNIT (intisa, fun, NULL);
  1404. return intisa->funcUnits[fun].name;
  1405. }
  1406. int
  1407. xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
  1408. {
  1409. xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  1410. CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
  1411. return intisa->funcUnits[fun].num_copies;
  1412. }