loongarch-coder.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* LoongArch opcode support.
  2. Copyright (C) 2021-2022 Free Software Foundation, Inc.
  3. Contributed by Loongson Ltd.
  4. This file is part of the GNU opcodes library.
  5. This library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. It is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; see the file COPYING3. If not,
  15. see <http://www.gnu.org/licenses/>. */
  16. #include "sysdep.h"
  17. #include "opcode/loongarch.h"
  18. int
  19. is_unsigned (const char *c_str)
  20. {
  21. if (c_str[0] == '0' && (c_str[1] == 'x' || c_str[1] == 'X'))
  22. {
  23. c_str += 2;
  24. while (('a' <= *c_str && *c_str <= 'f')
  25. || ('A' <= *c_str && *c_str <= 'F')
  26. || ('0' <= *c_str && *c_str <= '9'))
  27. c_str++;
  28. }
  29. else if (*c_str == '\0')
  30. return 0;
  31. else
  32. while ('0' <= *c_str && *c_str <= '9')
  33. c_str++;
  34. return *c_str == '\0';
  35. }
  36. int
  37. is_signed (const char *c_str)
  38. {
  39. return *c_str == '-' ? is_unsigned (c_str + 1) : is_unsigned (c_str);
  40. }
  41. int
  42. loongarch_get_bit_field_width (const char *bit_field, char **end)
  43. {
  44. int width = 0;
  45. char has_specify = 0, *bit_field_1 = (char *) bit_field;
  46. if (bit_field_1 && *bit_field_1 != '\0')
  47. while (1)
  48. {
  49. strtol (bit_field_1, &bit_field_1, 10);
  50. if (*bit_field_1 != ':')
  51. break;
  52. bit_field_1++;
  53. width += strtol (bit_field_1, &bit_field_1, 10);
  54. has_specify = 1;
  55. if (*bit_field_1 != '|')
  56. break;
  57. bit_field_1++;
  58. }
  59. if (end)
  60. *end = bit_field_1;
  61. return has_specify ? width : -1;
  62. }
  63. int32_t
  64. loongarch_decode_imm (const char *bit_field, insn_t insn, int si)
  65. {
  66. int32_t ret = 0;
  67. uint32_t t;
  68. int len = 0, width, b_start;
  69. char *bit_field_1 = (char *) bit_field;
  70. while (1)
  71. {
  72. b_start = strtol (bit_field_1, &bit_field_1, 10);
  73. if (*bit_field_1 != ':')
  74. break;
  75. width = strtol (bit_field_1 + 1, &bit_field_1, 10);
  76. len += width;
  77. t = insn;
  78. t <<= sizeof (t) * 8 - width - b_start;
  79. t >>= sizeof (t) * 8 - width;
  80. ret <<= width;
  81. ret |= t;
  82. if (*bit_field_1 != '|')
  83. break;
  84. bit_field_1++;
  85. }
  86. if (*bit_field_1 == '<' && *(++bit_field_1) == '<')
  87. {
  88. width = atoi (bit_field_1 + 1);
  89. ret <<= width;
  90. len += width;
  91. }
  92. else if (*bit_field_1 == '+')
  93. ret += atoi (bit_field_1 + 1);
  94. /* Extend signed bit. */
  95. if (si)
  96. {
  97. uint32_t sign = 1u << (len - 1);
  98. ret = (ret ^ sign) - sign;
  99. }
  100. return ret;
  101. }
  102. static insn_t
  103. loongarch_encode_imm (const char *bit_field, int32_t imm)
  104. {
  105. char *bit_field_1 = (char *) bit_field;
  106. char *t = bit_field_1;
  107. int width, b_start;
  108. insn_t ret = 0;
  109. uint32_t i;
  110. uint32_t uimm = (uint32_t)imm;
  111. width = loongarch_get_bit_field_width (t, &t);
  112. if (width == -1)
  113. return ret;
  114. if (*t == '<' && *(++t) == '<')
  115. width += atoi (t + 1);
  116. else if (*t == '+')
  117. uimm -= atoi (t + 1);
  118. uimm = width ? (uimm << (sizeof (uimm) * 8 - width)) : 0;
  119. while (1)
  120. {
  121. b_start = strtol (bit_field_1, &bit_field_1, 10);
  122. if (*bit_field_1 != ':')
  123. break;
  124. width = strtol (bit_field_1 + 1, &bit_field_1, 10);
  125. i = uimm;
  126. i = width ? (i >> (sizeof (i) * 8 - width)) : 0;
  127. i = (b_start == 32) ? 0 : (i << b_start);
  128. ret |= i;
  129. uimm = (width == 32) ? 0 : (uimm << width);
  130. if (*bit_field_1 != '|')
  131. break;
  132. bit_field_1++;
  133. }
  134. return ret;
  135. }
  136. /* Parse such FORMAT
  137. ""
  138. "u"
  139. "v0:5,r5:5,s10:10<<2"
  140. "r0:5,r5:5,r10:5,u15:2+1"
  141. "r,r,u0:5+32,u0:5+1"
  142. */
  143. static int
  144. loongarch_parse_format (const char *format, char *esc1s, char *esc2s,
  145. const char **bit_fields)
  146. {
  147. size_t arg_num = 0;
  148. if (*format == '\0')
  149. goto end;
  150. while (1)
  151. {
  152. /* esc1 esc2
  153. for "[a-zA-Z][a-zA-Z]?" */
  154. if (('a' <= *format && *format <= 'z')
  155. || ('A' <= *format && *format <= 'Z'))
  156. {
  157. *esc1s++ = *format++;
  158. if (('a' <= *format && *format <= 'z')
  159. || ('A' <= *format && *format <= 'Z'))
  160. *esc2s++ = *format++;
  161. else
  162. *esc2s++ = '\0';
  163. }
  164. else
  165. return -1;
  166. arg_num++;
  167. if (MAX_ARG_NUM_PLUS_2 - 2 < arg_num)
  168. /* Need larger MAX_ARG_NUM_PLUS_2. */
  169. return -1;
  170. *bit_fields++ = format;
  171. if ('0' <= *format && *format <= '9')
  172. {
  173. /* For "[0-9]+:[0-9]+(\|[0-9]+:[0-9]+)*". */
  174. while (1)
  175. {
  176. while ('0' <= *format && *format <= '9')
  177. format++;
  178. if (*format != ':')
  179. return -1;
  180. format++;
  181. if (!('0' <= *format && *format <= '9'))
  182. return -1;
  183. while ('0' <= *format && *format <= '9')
  184. format++;
  185. if (*format != '|')
  186. break;
  187. format++;
  188. }
  189. /* For "((\+|<<)[1-9][0-9]*)?". */
  190. do
  191. {
  192. if (*format == '+')
  193. format++;
  194. else if (format[0] == '<' && format[1] == '<')
  195. format += 2;
  196. else
  197. break;
  198. if (!('1' <= *format && *format <= '9'))
  199. return -1;
  200. while ('0' <= *format && *format <= '9')
  201. format++;
  202. }
  203. while (0);
  204. }
  205. if (*format == ',')
  206. format++;
  207. else if (*format == '\0')
  208. break;
  209. else
  210. return -1;
  211. }
  212. end:
  213. *esc1s = '\0';
  214. return 0;
  215. }
  216. size_t
  217. loongarch_split_args_by_comma (char *args, const char *arg_strs[])
  218. {
  219. size_t num = 0;
  220. if (*args)
  221. arg_strs[num++] = args;
  222. for (; *args; args++)
  223. if (*args == ',')
  224. {
  225. if (MAX_ARG_NUM_PLUS_2 - 1 == num)
  226. break;
  227. else
  228. *args = '\0', arg_strs[num++] = args + 1;
  229. }
  230. arg_strs[num] = NULL;
  231. return num;
  232. }
  233. char *
  234. loongarch_cat_splited_strs (const char *arg_strs[])
  235. {
  236. char *ret;
  237. size_t n, l;
  238. for (l = 0, n = 0; arg_strs[n]; n++)
  239. l += strlen (arg_strs[n]);
  240. ret = malloc (l + n + 1);
  241. if (!ret)
  242. return ret;
  243. ret[0] = '\0';
  244. if (0 < n)
  245. strcat (ret, arg_strs[0]);
  246. for (l = 1; l < n; l++)
  247. strcat (ret, ","), strcat (ret, arg_strs[l]);
  248. return ret;
  249. }
  250. insn_t
  251. loongarch_foreach_args (const char *format, const char *arg_strs[],
  252. int32_t (*helper) (char esc1, char esc2,
  253. const char *bit_field,
  254. const char *arg, void *context),
  255. void *context)
  256. {
  257. char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
  258. const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
  259. size_t i;
  260. insn_t ret = 0;
  261. int ok;
  262. ok = loongarch_parse_format (format, esc1s, esc2s, bit_fields) == 0;
  263. /* Make sure the num of actual args is equal to the num of escape. */
  264. for (i = 0; esc1s[i] && arg_strs[i]; i++)
  265. ;
  266. ok = ok && !esc1s[i] && !arg_strs[i];
  267. if (ok && helper)
  268. {
  269. for (i = 0; arg_strs[i]; i++)
  270. ret |= loongarch_encode_imm (bit_fields[i],
  271. helper (esc1s[i], esc2s[i],
  272. bit_fields[i], arg_strs[i],
  273. context));
  274. ret |= helper ('\0', '\0', NULL, NULL, context);
  275. }
  276. return ret;
  277. }
  278. int
  279. loongarch_check_format (const char *format)
  280. {
  281. char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
  282. const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
  283. if (!format)
  284. return -1;
  285. return loongarch_parse_format (format, esc1s, esc2s, bit_fields);
  286. }
  287. int
  288. loongarch_check_macro (const char *format, const char *macro)
  289. {
  290. int num_of_args;
  291. char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
  292. const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
  293. if (!format || !macro
  294. || loongarch_parse_format (format, esc1s, esc2s, bit_fields) != 0)
  295. return -1;
  296. for (num_of_args = 0; esc1s[num_of_args]; num_of_args++)
  297. ;
  298. for (; macro[0]; macro++)
  299. if (macro[0] == '%')
  300. {
  301. macro++;
  302. if ('1' <= macro[0] && macro[0] <= '9')
  303. {
  304. if (num_of_args < macro[0] - '0')
  305. /* Out of args num. */
  306. return -1;
  307. }
  308. else if (macro[0] == 'f')
  309. ;
  310. else if (macro[0] == '%')
  311. ;
  312. else
  313. return -1;
  314. }
  315. return 0;
  316. }
  317. static const char *
  318. I (char esc_ch1 ATTRIBUTE_UNUSED, char esc_ch2 ATTRIBUTE_UNUSED,
  319. const char *c_str)
  320. {
  321. return c_str;
  322. }
  323. char *
  324. loongarch_expand_macro_with_format_map (
  325. const char *format, const char *macro, const char *const arg_strs[],
  326. const char *(*map) (char esc1, char esc2, const char *arg),
  327. char *(*helper) (const char *const arg_strs[], void *context), void *context,
  328. size_t len_str)
  329. {
  330. char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
  331. const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
  332. const char *src;
  333. char *dest;
  334. /* The expanded macro character length does not exceed 1000, and number of
  335. label is 6 at most in the expanded macro. The len_str is the length of
  336. str. */
  337. char *buffer =(char *) malloc(1024 + 6 * len_str);
  338. if (format)
  339. loongarch_parse_format (format, esc1s, esc2s, bit_fields);
  340. src = macro;
  341. dest = buffer;
  342. while (*src)
  343. if (*src == '%')
  344. {
  345. src++;
  346. if ('1' <= *src && *src <= '9')
  347. {
  348. size_t i = *src - '1';
  349. const char *t = map (esc1s[i], esc2s[i], arg_strs[i]);
  350. while (*t)
  351. *dest++ = *t++;
  352. }
  353. else if (*src == '%')
  354. *dest++ = '%';
  355. else if (*src == 'f' && helper)
  356. {
  357. char *b, *t;
  358. t = b = (*helper) (arg_strs, context);
  359. if (b)
  360. {
  361. while (*t)
  362. *dest++ = *t++;
  363. free (b);
  364. }
  365. }
  366. src++;
  367. }
  368. else
  369. *dest++ = *src++;
  370. *dest = '\0';
  371. return buffer;
  372. }
  373. char *
  374. loongarch_expand_macro (const char *macro, const char *const arg_strs[],
  375. char *(*helper) (const char *const arg_strs[],
  376. void *context),
  377. void *context, size_t len_str)
  378. {
  379. return loongarch_expand_macro_with_format_map (NULL, macro, arg_strs, I,
  380. helper, context, len_str);
  381. }
  382. size_t
  383. loongarch_bits_imm_needed (int64_t imm, int si)
  384. {
  385. size_t ret;
  386. if (si)
  387. {
  388. if (imm < 0)
  389. {
  390. uint64_t uimm = (uint64_t) imm;
  391. uint64_t uimax = UINT64_C (1) << 63;
  392. for (ret = 0; (uimm & uimax) != 0; uimm <<= 1, ret++)
  393. ;
  394. ret = 64 - ret + 1;
  395. }
  396. else
  397. ret = loongarch_bits_imm_needed (imm, 0) + 1;
  398. }
  399. else
  400. {
  401. uint64_t t = imm;
  402. for (ret = 0; t; t >>= 1, ret++)
  403. ;
  404. }
  405. return ret;
  406. }
  407. void
  408. loongarch_eliminate_adjacent_repeat_char (char *dest, char c)
  409. {
  410. if (c == '\0')
  411. return;
  412. char *src = dest;
  413. while (*dest)
  414. {
  415. while (src[0] == c && src[0] == src[1])
  416. src++;
  417. *dest++ = *src++;
  418. }
  419. }