xtensa-isa.c 44 KB

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