or1k.opc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /* OpenRISC 1000 opcode support. -*- C -*-
  2. Copyright 2000-2014 Free Software Foundation, Inc.
  3. Originally ontributed for OR32 by Red Hat Inc;
  4. This file is part of the GNU Binutils.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, see <http://www.gnu.org/licenses/>. */
  15. /* This file is an addendum to or1k.cpu. Heavy use of C code isn't
  16. appropriate in .cpu files, so it resides here. This especially applies
  17. to assembly/disassembly where parsing/printing can be quite involved.
  18. Such things aren't really part of the specification of the cpu, per se,
  19. so .cpu files provide the general framework and .opc files handle the
  20. nitty-gritty details as necessary.
  21. Each section is delimited with start and end markers.
  22. <arch>-opc.h additions use: "-- opc.h"
  23. <arch>-opc.c additions use: "-- opc.c"
  24. <arch>-asm.c additions use: "-- asm.c"
  25. <arch>-dis.c additions use: "-- dis.c"
  26. <arch>-ibd.h additions use: "-- ibd.h" */
  27. /* -- opc.h */
  28. #undef CGEN_DIS_HASH_SIZE
  29. #define CGEN_DIS_HASH_SIZE 256
  30. #undef CGEN_DIS_HASH
  31. #define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2)
  32. /* -- */
  33. /* -- opc.c */
  34. /* -- */
  35. /* -- asm.c */
  36. static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
  37. #define CGEN_VERBOSE_ASSEMBLER_ERRORS
  38. static const char *
  39. parse_disp26 (CGEN_CPU_DESC cd,
  40. const char ** strp,
  41. int opindex,
  42. int opinfo,
  43. enum cgen_parse_operand_result * resultp,
  44. bfd_vma * valuep)
  45. {
  46. const char *errmsg = NULL;
  47. enum cgen_parse_operand_result result_type;
  48. if (strncasecmp (*strp, "plt(", 4) == 0)
  49. {
  50. bfd_vma value;
  51. *strp += 4;
  52. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
  53. & result_type, & value);
  54. if (**strp != ')')
  55. return MISSING_CLOSING_PARENTHESIS;
  56. ++*strp;
  57. if (errmsg == NULL
  58. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  59. value = (value >> 2) & 0xffff;
  60. *valuep = value;
  61. return errmsg;
  62. }
  63. return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
  64. }
  65. static const char *
  66. parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
  67. {
  68. const char *errmsg;
  69. enum cgen_parse_operand_result result_type;
  70. long ret;
  71. if (**strp == '#')
  72. ++*strp;
  73. if (strncasecmp (*strp, "hi(", 3) == 0)
  74. {
  75. bfd_vma value;
  76. *strp += 3;
  77. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
  78. & result_type, & value);
  79. if (**strp != ')')
  80. errmsg = MISSING_CLOSING_PARENTHESIS;
  81. ++*strp;
  82. ret = value;
  83. if (errmsg == NULL
  84. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  85. {
  86. ret >>= 16;
  87. ret &= 0xffff;
  88. ret = (ret ^ 0x8000) - 0x8000;
  89. }
  90. }
  91. else if (strncasecmp (*strp, "lo(", 3) == 0)
  92. {
  93. bfd_vma value;
  94. *strp += 3;
  95. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
  96. & result_type, & value);
  97. if (**strp != ')')
  98. return MISSING_CLOSING_PARENTHESIS;
  99. ++*strp;
  100. ret = value;
  101. if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  102. {
  103. ret &= 0xffff;
  104. ret = (ret ^ 0x8000) - 0x8000;
  105. }
  106. }
  107. else if (strncasecmp (*strp, "got(", 4) == 0)
  108. {
  109. bfd_vma value;
  110. *strp += 4;
  111. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
  112. & result_type, & value);
  113. if (**strp != ')')
  114. return MISSING_CLOSING_PARENTHESIS;
  115. ++*strp;
  116. if (errmsg == NULL
  117. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  118. value &= 0xffff;
  119. *valuep = value;
  120. return errmsg;
  121. }
  122. else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
  123. {
  124. bfd_vma value;
  125. *strp += 8;
  126. errmsg = cgen_parse_address (cd, strp, opindex,
  127. BFD_RELOC_OR1K_GOTPC_HI16,
  128. & result_type, & value);
  129. if (**strp != ')')
  130. return MISSING_CLOSING_PARENTHESIS;
  131. ++*strp;
  132. if (errmsg == NULL
  133. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  134. value = (value >> 16) & 0xffff;
  135. *valuep = value;
  136. return errmsg;
  137. }
  138. else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
  139. {
  140. bfd_vma value;
  141. *strp += 8;
  142. errmsg = cgen_parse_address (cd, strp, opindex,
  143. BFD_RELOC_OR1K_GOTPC_LO16,
  144. &result_type, &value);
  145. if (**strp != ')')
  146. return MISSING_CLOSING_PARENTHESIS;
  147. ++*strp;
  148. if (errmsg == NULL
  149. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  150. value &= 0xffff;
  151. *valuep = value;
  152. return errmsg;
  153. }
  154. else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
  155. {
  156. bfd_vma value;
  157. *strp += 9;
  158. errmsg = cgen_parse_address (cd, strp, opindex,
  159. BFD_RELOC_OR1K_GOTOFF_HI16,
  160. & result_type, & value);
  161. if (**strp != ')')
  162. return MISSING_CLOSING_PARENTHESIS;
  163. ++*strp;
  164. if (errmsg == NULL
  165. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  166. value = (value >> 16) & 0xffff;
  167. *valuep = value;
  168. return errmsg;
  169. }
  170. else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
  171. {
  172. bfd_vma value;
  173. *strp += 9;
  174. errmsg = cgen_parse_address (cd, strp, opindex,
  175. BFD_RELOC_OR1K_GOTOFF_LO16,
  176. &result_type, &value);
  177. if (**strp != ')')
  178. return MISSING_CLOSING_PARENTHESIS;
  179. ++*strp;
  180. if (errmsg == NULL
  181. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  182. value &= 0xffff;
  183. *valuep = value;
  184. return errmsg;
  185. }
  186. else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
  187. {
  188. bfd_vma value;
  189. *strp += 8;
  190. errmsg = cgen_parse_address (cd, strp, opindex,
  191. BFD_RELOC_OR1K_TLS_GD_HI16,
  192. & result_type, & value);
  193. if (**strp != ')')
  194. return MISSING_CLOSING_PARENTHESIS;
  195. ++*strp;
  196. if (errmsg == NULL
  197. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  198. value = (value >> 16) & 0xffff;
  199. *valuep = value;
  200. return errmsg;
  201. }
  202. else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
  203. {
  204. bfd_vma value;
  205. *strp += 8;
  206. errmsg = cgen_parse_address (cd, strp, opindex,
  207. BFD_RELOC_OR1K_TLS_GD_LO16,
  208. &result_type, &value);
  209. if (**strp != ')')
  210. return MISSING_CLOSING_PARENTHESIS;
  211. ++*strp;
  212. if (errmsg == NULL
  213. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  214. value &= 0xffff;
  215. *valuep = value;
  216. return errmsg;
  217. }
  218. else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
  219. {
  220. bfd_vma value;
  221. *strp += 9;
  222. errmsg = cgen_parse_address (cd, strp, opindex,
  223. BFD_RELOC_OR1K_TLS_LDM_HI16,
  224. & result_type, & value);
  225. if (**strp != ')')
  226. return MISSING_CLOSING_PARENTHESIS;
  227. ++*strp;
  228. if (errmsg == NULL
  229. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  230. value = (value >> 16) & 0xffff;
  231. *valuep = value;
  232. return errmsg;
  233. }
  234. else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
  235. {
  236. bfd_vma value;
  237. *strp += 9;
  238. errmsg = cgen_parse_address (cd, strp, opindex,
  239. BFD_RELOC_OR1K_TLS_LDM_LO16,
  240. &result_type, &value);
  241. if (**strp != ')')
  242. return MISSING_CLOSING_PARENTHESIS;
  243. ++*strp;
  244. if (errmsg == NULL
  245. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  246. value &= 0xffff;
  247. *valuep = value;
  248. return errmsg;
  249. }
  250. else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
  251. {
  252. bfd_vma value;
  253. *strp += 9;
  254. errmsg = cgen_parse_address (cd, strp, opindex,
  255. BFD_RELOC_OR1K_TLS_LDO_HI16,
  256. & result_type, & value);
  257. if (**strp != ')')
  258. return MISSING_CLOSING_PARENTHESIS;
  259. ++*strp;
  260. if (errmsg == NULL
  261. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  262. value = (value >> 16) & 0xffff;
  263. *valuep = value;
  264. return errmsg;
  265. }
  266. else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
  267. {
  268. bfd_vma value;
  269. *strp += 9;
  270. errmsg = cgen_parse_address (cd, strp, opindex,
  271. BFD_RELOC_OR1K_TLS_LDO_LO16,
  272. &result_type, &value);
  273. if (**strp != ')')
  274. return MISSING_CLOSING_PARENTHESIS;
  275. ++*strp;
  276. if (errmsg == NULL
  277. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  278. value &= 0xffff;
  279. *valuep = value;
  280. return errmsg;
  281. }
  282. else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
  283. {
  284. bfd_vma value;
  285. *strp += 11;
  286. errmsg = cgen_parse_address (cd, strp, opindex,
  287. BFD_RELOC_OR1K_TLS_IE_HI16,
  288. & result_type, & value);
  289. if (**strp != ')')
  290. return MISSING_CLOSING_PARENTHESIS;
  291. ++*strp;
  292. if (errmsg == NULL
  293. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  294. value = (value >> 16) & 0xffff;
  295. *valuep = value;
  296. return errmsg;
  297. }
  298. else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
  299. {
  300. bfd_vma value;
  301. *strp += 11;
  302. errmsg = cgen_parse_address (cd, strp, opindex,
  303. BFD_RELOC_OR1K_TLS_IE_LO16,
  304. &result_type, &value);
  305. if (**strp != ')')
  306. return MISSING_CLOSING_PARENTHESIS;
  307. ++*strp;
  308. if (errmsg == NULL
  309. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  310. value &= 0xffff;
  311. *valuep = value;
  312. return errmsg;
  313. }
  314. else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
  315. {
  316. bfd_vma value;
  317. *strp += 8;
  318. errmsg = cgen_parse_address (cd, strp, opindex,
  319. BFD_RELOC_OR1K_TLS_LE_HI16,
  320. & result_type, & value);
  321. if (**strp != ')')
  322. return MISSING_CLOSING_PARENTHESIS;
  323. ++*strp;
  324. if (errmsg == NULL
  325. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  326. value = (value >> 16) & 0xffff;
  327. *valuep = value;
  328. return errmsg;
  329. }
  330. else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
  331. {
  332. bfd_vma value;
  333. *strp += 8;
  334. errmsg = cgen_parse_address (cd, strp, opindex,
  335. BFD_RELOC_OR1K_TLS_LE_LO16,
  336. &result_type, &value);
  337. if (**strp != ')')
  338. return MISSING_CLOSING_PARENTHESIS;
  339. ++*strp;
  340. if (errmsg == NULL
  341. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  342. value &= 0xffff;
  343. *valuep = value;
  344. return errmsg;
  345. }
  346. else
  347. {
  348. long value;
  349. errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
  350. ret = value;
  351. }
  352. if (errmsg == NULL)
  353. *valuep = ret;
  354. return errmsg;
  355. }
  356. static const char *
  357. parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
  358. {
  359. const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
  360. if (errmsg == NULL)
  361. *valuep &= 0xffff;
  362. return errmsg;
  363. }
  364. /* -- */
  365. /* -- ibd.h */
  366. /* -- */