m32c.opc 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  1. /* m32c opcode support. -*- C -*-
  2. Copyright 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
  3. Contributed by Red Hat Inc; developed under contract from Renesas
  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, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. /* This file is an addendum to m32c.cpu. Heavy use of C code isn't
  18. appropriate in .cpu files, so it resides here. This especially applies
  19. to assembly/disassembly where parsing/printing can be quite involved.
  20. Such things aren't really part of the specification of the cpu, per se,
  21. so .cpu files provide the general framework and .opc files handle the
  22. nitty-gritty details as necessary.
  23. Each section is delimited with start and end markers.
  24. <arch>-opc.h additions use: "-- opc.h"
  25. <arch>-opc.c additions use: "-- opc.c"
  26. <arch>-asm.c additions use: "-- asm.c"
  27. <arch>-dis.c additions use: "-- dis.c"
  28. <arch>-ibd.h additions use: "-- ibd.h". */
  29. /* -- opc.h */
  30. /* Needed for RTL's 'ext' and 'trunc' operators. */
  31. #include "cgen/basic-modes.h"
  32. #include "cgen/basic-ops.h"
  33. /* We can't use the default hash size because many bits are used by
  34. operands. */
  35. #define CGEN_DIS_HASH_SIZE 1
  36. #define CGEN_DIS_HASH(buf, value) 0
  37. #define CGEN_VERBOSE_ASSEMBLER_ERRORS
  38. #define CGEN_VALIDATE_INSN_SUPPORTED
  39. extern int m32c_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
  40. #define CGEN_ASM_HASH_SIZE 0xffff
  41. #define CGEN_ASM_HASH(mnem) m32c_asm_hash ((mnem))
  42. /* -- */
  43. /* -- opc.c */
  44. static unsigned int
  45. m32c_asm_hash (const char *mnem)
  46. {
  47. unsigned int h;
  48. /* The length of the mnemonic for the Jcnd insns is 1. Hash jsri. */
  49. if (mnem[0] == 'j' && mnem[1] != 's')
  50. return 'j';
  51. /* Don't hash scCND */
  52. if (mnem[0] == 's' && mnem[1] == 'c')
  53. return 's';
  54. /* Don't hash bmCND */
  55. if (mnem[0] == 'b' && mnem[1] == 'm')
  56. return 'b';
  57. for (h = 0; *mnem && *mnem != ' ' && *mnem != ':'; ++mnem)
  58. h += *mnem;
  59. return h % CGEN_ASM_HASH_SIZE;
  60. }
  61. /* -- asm.c */
  62. #include "safe-ctype.h"
  63. #define MACH_M32C 5 /* Must match md_begin. */
  64. static int
  65. m32c_cgen_isa_register (const char **strp)
  66. {
  67. int u;
  68. const char *s = *strp;
  69. static char * m32c_register_names [] =
  70. {
  71. "r0", "r1", "r2", "r3", "r0l", "r0h", "r1l", "r1h",
  72. "a0", "a1", "r2r0", "r3r1", "sp", "fb", "dct0", "dct1", "flg", "svf",
  73. "drc0", "drc1", "dmd0", "dmd1", "intb", "svp", "vct", "isp", "dma0",
  74. "dma1", "dra0", "dra1", "dsa0", "dsa1", 0
  75. };
  76. for (u = 0; m32c_register_names[u]; u++)
  77. {
  78. int len = strlen (m32c_register_names[u]);
  79. if (memcmp (m32c_register_names[u], s, len) == 0
  80. && (s[len] == 0 || ! ISALNUM (s[len])))
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. #define PARSE_UNSIGNED \
  86. do \
  87. { \
  88. /* Don't successfully parse literals beginning with '['. */ \
  89. if (**strp == '[') \
  90. return "Invalid literal"; /* Anything -- will not be seen. */ \
  91. \
  92. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);\
  93. if (errmsg) \
  94. return errmsg; \
  95. } \
  96. while (0)
  97. #define PARSE_SIGNED \
  98. do \
  99. { \
  100. /* Don't successfully parse literals beginning with '['. */ \
  101. if (**strp == '[') \
  102. return "Invalid literal"; /* Anything -- will not be seen. */ \
  103. \
  104. errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); \
  105. if (errmsg) \
  106. return errmsg; \
  107. } \
  108. while (0)
  109. static const char *
  110. parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp,
  111. int opindex, unsigned long *valuep)
  112. {
  113. const char *errmsg = 0;
  114. unsigned long value;
  115. PARSE_UNSIGNED;
  116. if (value > 0x3f)
  117. return _("imm:6 immediate is out of range");
  118. *valuep = value;
  119. return 0;
  120. }
  121. static const char *
  122. parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp,
  123. int opindex, unsigned long *valuep)
  124. {
  125. const char *errmsg = 0;
  126. unsigned long value = 0;
  127. long have_zero = 0;
  128. if (strncasecmp (*strp, "%dsp8(", 6) == 0)
  129. {
  130. enum cgen_parse_operand_result result_type;
  131. bfd_vma val;
  132. *strp += 6;
  133. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_8,
  134. & result_type, & val);
  135. if (**strp != ')')
  136. return _("missing `)'");
  137. (*strp) ++;
  138. if (errmsg == NULL
  139. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  140. return _("%dsp8() takes a symbolic address, not a number");
  141. value = val;
  142. *valuep = value;
  143. return errmsg;
  144. }
  145. if (strncmp (*strp, "0x0", 3) == 0
  146. || (**strp == '0' && *(*strp + 1) != 'x'))
  147. have_zero = 1;
  148. PARSE_UNSIGNED;
  149. if (value > 0xff)
  150. return _("dsp:8 immediate is out of range");
  151. /* If this field may require a relocation then use larger dsp16. */
  152. if (! have_zero && value == 0)
  153. return _("dsp:8 immediate is out of range");
  154. *valuep = value;
  155. return 0;
  156. }
  157. static const char *
  158. parse_signed4 (CGEN_CPU_DESC cd, const char **strp,
  159. int opindex, signed long *valuep)
  160. {
  161. const char *errmsg = 0;
  162. signed long value;
  163. long have_zero = 0;
  164. if (strncmp (*strp, "0x0", 3) == 0
  165. || (**strp == '0' && *(*strp + 1) != 'x'))
  166. have_zero = 1;
  167. PARSE_SIGNED;
  168. if (value < -8 || value > 7)
  169. return _("Immediate is out of range -8 to 7");
  170. /* If this field may require a relocation then use larger dsp16. */
  171. if (! have_zero && value == 0)
  172. return _("Immediate is out of range -8 to 7");
  173. *valuep = value;
  174. return 0;
  175. }
  176. static const char *
  177. parse_signed4n (CGEN_CPU_DESC cd, const char **strp,
  178. int opindex, signed long *valuep)
  179. {
  180. const char *errmsg = 0;
  181. signed long value;
  182. long have_zero = 0;
  183. if (strncmp (*strp, "0x0", 3) == 0
  184. || (**strp == '0' && *(*strp + 1) != 'x'))
  185. have_zero = 1;
  186. PARSE_SIGNED;
  187. if (value < -7 || value > 8)
  188. return _("Immediate is out of range -7 to 8");
  189. /* If this field may require a relocation then use larger dsp16. */
  190. if (! have_zero && value == 0)
  191. return _("Immediate is out of range -7 to 8");
  192. *valuep = -value;
  193. return 0;
  194. }
  195. static const char *
  196. parse_signed8 (CGEN_CPU_DESC cd, const char **strp,
  197. int opindex, signed long *valuep)
  198. {
  199. const char *errmsg = 0;
  200. signed long value = 0;
  201. if (strncasecmp (*strp, "%hi8(", 5) == 0)
  202. {
  203. enum cgen_parse_operand_result result_type;
  204. bfd_vma val;
  205. *strp += 5;
  206. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32C_HI8,
  207. & result_type, & val);
  208. if (**strp != ')')
  209. return _("missing `)'");
  210. (*strp) ++;
  211. if (errmsg == NULL
  212. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  213. val >>= 16;
  214. value = val;
  215. *valuep = value;
  216. return errmsg;
  217. }
  218. PARSE_SIGNED;
  219. if (value <= 255 && value > 127)
  220. value -= 0x100;
  221. if (value < -128 || value > 127)
  222. return _("dsp:8 immediate is out of range");
  223. *valuep = value;
  224. return 0;
  225. }
  226. static const char *
  227. parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp,
  228. int opindex, unsigned long *valuep)
  229. {
  230. const char *errmsg = 0;
  231. unsigned long value = 0;
  232. long have_zero = 0;
  233. if (strncasecmp (*strp, "%dsp16(", 7) == 0)
  234. {
  235. enum cgen_parse_operand_result result_type;
  236. bfd_vma val;
  237. *strp += 7;
  238. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_16,
  239. & result_type, & val);
  240. if (**strp != ')')
  241. return _("missing `)'");
  242. (*strp) ++;
  243. if (errmsg == NULL
  244. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  245. return _("%dsp16() takes a symbolic address, not a number");
  246. value = val;
  247. *valuep = value;
  248. return errmsg;
  249. }
  250. /* Don't successfully parse literals beginning with '['. */
  251. if (**strp == '[')
  252. return "Invalid literal"; /* Anything -- will not be seen. */
  253. /* Don't successfully parse register names. */
  254. if (m32c_cgen_isa_register (strp))
  255. return "Invalid literal"; /* Anything -- will not be seen. */
  256. if (strncmp (*strp, "0x0", 3) == 0
  257. || (**strp == '0' && *(*strp + 1) != 'x'))
  258. have_zero = 1;
  259. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
  260. if (errmsg)
  261. return errmsg;
  262. if (value > 0xffff)
  263. return _("dsp:16 immediate is out of range");
  264. /* If this field may require a relocation then use larger dsp24. */
  265. if (cd->machs == MACH_M32C && ! have_zero && value == 0
  266. && (strncmp (*strp, "[a", 2) == 0
  267. || **strp == ','
  268. || **strp == 0))
  269. return _("dsp:16 immediate is out of range");
  270. *valuep = value;
  271. return 0;
  272. }
  273. static const char *
  274. parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
  275. int opindex, signed long *valuep)
  276. {
  277. const char *errmsg = 0;
  278. signed long value = 0;
  279. if (strncasecmp (*strp, "%lo16(", 6) == 0)
  280. {
  281. enum cgen_parse_operand_result result_type;
  282. bfd_vma val;
  283. *strp += 6;
  284. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
  285. & result_type, & val);
  286. if (**strp != ')')
  287. return _("missing `)'");
  288. (*strp) ++;
  289. if (errmsg == NULL
  290. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  291. val &= 0xffff;
  292. value = val;
  293. *valuep = value;
  294. return errmsg;
  295. }
  296. if (strncasecmp (*strp, "%hi16(", 6) == 0)
  297. {
  298. enum cgen_parse_operand_result result_type;
  299. bfd_vma val;
  300. *strp += 6;
  301. errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
  302. & result_type, & val);
  303. if (**strp != ')')
  304. return _("missing `)'");
  305. (*strp) ++;
  306. if (errmsg == NULL
  307. && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
  308. val >>= 16;
  309. value = val;
  310. *valuep = value;
  311. return errmsg;
  312. }
  313. PARSE_SIGNED;
  314. if (value <= 65535 && value > 32767)
  315. value -= 0x10000;
  316. if (value < -32768 || value > 32767)
  317. return _("dsp:16 immediate is out of range");
  318. *valuep = value;
  319. return 0;
  320. }
  321. static const char *
  322. parse_unsigned20 (CGEN_CPU_DESC cd, const char **strp,
  323. int opindex, unsigned long *valuep)
  324. {
  325. const char *errmsg = 0;
  326. unsigned long value;
  327. /* Don't successfully parse literals beginning with '['. */
  328. if (**strp == '[')
  329. return "Invalid literal"; /* Anything -- will not be seen. */
  330. /* Don't successfully parse register names. */
  331. if (m32c_cgen_isa_register (strp))
  332. return "Invalid literal"; /* Anything -- will not be seen. */
  333. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
  334. if (errmsg)
  335. return errmsg;
  336. if (value > 0xfffff)
  337. return _("dsp:20 immediate is out of range");
  338. *valuep = value;
  339. return 0;
  340. }
  341. static const char *
  342. parse_unsigned24 (CGEN_CPU_DESC cd, const char **strp,
  343. int opindex, unsigned long *valuep)
  344. {
  345. const char *errmsg = 0;
  346. unsigned long value;
  347. /* Don't successfully parse literals beginning with '['. */
  348. if (**strp == '[')
  349. return "Invalid literal"; /* Anything -- will not be seen. */
  350. /* Don't successfully parse register names. */
  351. if (m32c_cgen_isa_register (strp))
  352. return "Invalid literal"; /* Anything -- will not be seen. */
  353. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
  354. if (errmsg)
  355. return errmsg;
  356. if (value > 0xffffff)
  357. return _("dsp:24 immediate is out of range");
  358. *valuep = value;
  359. return 0;
  360. }
  361. /* This should only be used for #imm->reg. */
  362. static const char *
  363. parse_signed24 (CGEN_CPU_DESC cd, const char **strp,
  364. int opindex, signed long *valuep)
  365. {
  366. const char *errmsg = 0;
  367. signed long value;
  368. PARSE_SIGNED;
  369. if (value <= 0xffffff && value > 0x7fffff)
  370. value -= 0x1000000;
  371. if (value > 0xffffff)
  372. return _("dsp:24 immediate is out of range");
  373. *valuep = value;
  374. return 0;
  375. }
  376. static const char *
  377. parse_signed32 (CGEN_CPU_DESC cd, const char **strp,
  378. int opindex, signed long *valuep)
  379. {
  380. const char *errmsg = 0;
  381. signed long value;
  382. errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  383. if (errmsg)
  384. return errmsg;
  385. *valuep = value;
  386. return 0;
  387. }
  388. static const char *
  389. parse_imm1_S (CGEN_CPU_DESC cd, const char **strp,
  390. int opindex, signed long *valuep)
  391. {
  392. const char *errmsg = 0;
  393. signed long value;
  394. errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  395. if (errmsg)
  396. return errmsg;
  397. if (value < 1 || value > 2)
  398. return _("immediate is out of range 1-2");
  399. *valuep = value;
  400. return 0;
  401. }
  402. static const char *
  403. parse_imm3_S (CGEN_CPU_DESC cd, const char **strp,
  404. int opindex, signed long *valuep)
  405. {
  406. const char *errmsg = 0;
  407. signed long value;
  408. errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  409. if (errmsg)
  410. return errmsg;
  411. if (value < 1 || value > 8)
  412. return _("immediate is out of range 1-8");
  413. *valuep = value;
  414. return 0;
  415. }
  416. static const char *
  417. parse_bit3_S (CGEN_CPU_DESC cd, const char **strp,
  418. int opindex, signed long *valuep)
  419. {
  420. const char *errmsg = 0;
  421. signed long value;
  422. errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
  423. if (errmsg)
  424. return errmsg;
  425. if (value < 0 || value > 7)
  426. return _("immediate is out of range 0-7");
  427. *valuep = value;
  428. return 0;
  429. }
  430. static const char *
  431. parse_lab_5_3 (CGEN_CPU_DESC cd,
  432. const char **strp,
  433. int opindex ATTRIBUTE_UNUSED,
  434. int opinfo,
  435. enum cgen_parse_operand_result *type_addr,
  436. bfd_vma *valuep)
  437. {
  438. const char *errmsg = 0;
  439. bfd_vma value;
  440. enum cgen_parse_operand_result op_res;
  441. errmsg = cgen_parse_address (cd, strp, M32C_OPERAND_LAB_5_3,
  442. opinfo, & op_res, & value);
  443. if (type_addr)
  444. *type_addr = op_res;
  445. if (op_res == CGEN_PARSE_OPERAND_RESULT_QUEUED)
  446. {
  447. /* This is a hack; the field cannot handle near-zero signed
  448. offsets that CGEN wants to put in to indicate an "empty"
  449. operand at first. */
  450. *valuep = 2;
  451. return 0;
  452. }
  453. if (errmsg)
  454. return errmsg;
  455. if (value < 2 || value > 9)
  456. return _("immediate is out of range 2-9");
  457. *valuep = value;
  458. return 0;
  459. }
  460. static const char *
  461. parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp,
  462. int opindex, unsigned long *valuep)
  463. {
  464. const char *errmsg = 0;
  465. unsigned long value;
  466. errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
  467. if (errmsg)
  468. return errmsg;
  469. if (value > 15)
  470. return _("Bit number for indexing general register is out of range 0-15");
  471. *valuep = value;
  472. return 0;
  473. }
  474. static const char *
  475. parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
  476. int opindex, unsigned long *valuep,
  477. unsigned bits, int allow_syms)
  478. {
  479. const char *errmsg = 0;
  480. unsigned long bit;
  481. unsigned long base;
  482. const char *newp = *strp;
  483. unsigned long long bitbase;
  484. long have_zero = 0;
  485. errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
  486. if (errmsg)
  487. return errmsg;
  488. if (*newp != ',')
  489. return "Missing base for bit,base:8";
  490. ++newp;
  491. if (strncmp (newp, "0x0", 3) == 0
  492. || (newp[0] == '0' && newp[1] != 'x'))
  493. have_zero = 1;
  494. errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base);
  495. if (errmsg)
  496. return errmsg;
  497. bitbase = (unsigned long long) bit + ((unsigned long long) base * 8);
  498. if (bitbase >= (1ull << bits))
  499. return _("bit,base is out of range");
  500. /* If this field may require a relocation then use larger displacement. */
  501. if (! have_zero && base == 0)
  502. {
  503. switch (allow_syms) {
  504. case 0:
  505. return _("bit,base out of range for symbol");
  506. case 1:
  507. break;
  508. case 2:
  509. if (strncmp (newp, "[sb]", 4) != 0)
  510. return _("bit,base out of range for symbol");
  511. break;
  512. }
  513. }
  514. *valuep = bitbase;
  515. *strp = newp;
  516. return 0;
  517. }
  518. static const char *
  519. parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
  520. int opindex, signed long *valuep,
  521. unsigned bits, int allow_syms)
  522. {
  523. const char *errmsg = 0;
  524. unsigned long bit;
  525. signed long base;
  526. const char *newp = *strp;
  527. long long bitbase;
  528. long long limit;
  529. long have_zero = 0;
  530. errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
  531. if (errmsg)
  532. return errmsg;
  533. if (*newp != ',')
  534. return "Missing base for bit,base:8";
  535. ++newp;
  536. if (strncmp (newp, "0x0", 3) == 0
  537. || (newp[0] == '0' && newp[1] != 'x'))
  538. have_zero = 1;
  539. errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base);
  540. if (errmsg)
  541. return errmsg;
  542. bitbase = (long long)bit + ((long long)base * 8);
  543. limit = 1ll << (bits - 1);
  544. if (bitbase < -limit || bitbase >= limit)
  545. return _("bit,base is out of range");
  546. /* If this field may require a relocation then use larger displacement. */
  547. if (! have_zero && base == 0 && ! allow_syms)
  548. return _("bit,base out of range for symbol");
  549. *valuep = bitbase;
  550. *strp = newp;
  551. return 0;
  552. }
  553. static const char *
  554. parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
  555. int opindex, unsigned long *valuep)
  556. {
  557. return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8, 0);
  558. }
  559. static const char *
  560. parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
  561. int opindex, unsigned long *valuep)
  562. {
  563. return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11, 0);
  564. }
  565. static const char *
  566. parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp,
  567. int opindex, unsigned long *valuep)
  568. {
  569. return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16, 1);
  570. }
  571. static const char *
  572. parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
  573. int opindex, unsigned long *valuep)
  574. {
  575. return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19, 2);
  576. }
  577. static const char *
  578. parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp,
  579. int opindex, unsigned long *valuep)
  580. {
  581. return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27, 1);
  582. }
  583. static const char *
  584. parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
  585. int opindex, signed long *valuep)
  586. {
  587. return parse_signed_bitbase (cd, strp, opindex, valuep, 8, 1);
  588. }
  589. static const char *
  590. parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
  591. int opindex, signed long *valuep)
  592. {
  593. return parse_signed_bitbase (cd, strp, opindex, valuep, 11, 0);
  594. }
  595. static const char *
  596. parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
  597. int opindex, signed long *valuep)
  598. {
  599. return parse_signed_bitbase (cd, strp, opindex, valuep, 19, 1);
  600. }
  601. /* Parse the suffix as :<char> or as nothing followed by a whitespace. */
  602. static const char *
  603. parse_suffix (const char **strp, char suffix)
  604. {
  605. const char *newp = *strp;
  606. if (**strp == ':' && TOLOWER (*(*strp + 1)) == suffix)
  607. newp = *strp + 2;
  608. if (ISSPACE (*newp))
  609. {
  610. *strp = newp;
  611. return 0;
  612. }
  613. return "Invalid suffix"; /* Anything -- will not be seen. */
  614. }
  615. static const char *
  616. parse_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  617. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  618. {
  619. return parse_suffix (strp, 's');
  620. }
  621. static const char *
  622. parse_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  623. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  624. {
  625. return parse_suffix (strp, 'g');
  626. }
  627. static const char *
  628. parse_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  629. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  630. {
  631. return parse_suffix (strp, 'q');
  632. }
  633. static const char *
  634. parse_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  635. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  636. {
  637. return parse_suffix (strp, 'z');
  638. }
  639. /* Parse an empty suffix. Fail if the next char is ':'. */
  640. static const char *
  641. parse_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  642. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  643. {
  644. if (**strp == ':')
  645. return "Unexpected suffix";
  646. return 0;
  647. }
  648. static const char *
  649. parse_r0l_r0h (CGEN_CPU_DESC cd, const char **strp,
  650. int opindex ATTRIBUTE_UNUSED, signed long *valuep)
  651. {
  652. const char *errmsg;
  653. signed long value;
  654. signed long junk;
  655. const char *newp = *strp;
  656. /* Parse r0[hl]. */
  657. errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l_r0h, & value);
  658. if (errmsg)
  659. return errmsg;
  660. if (*newp != ',')
  661. return _("not a valid r0l/r0h pair");
  662. ++newp;
  663. /* Parse the second register in the pair. */
  664. if (value == 0) /* r0l */
  665. errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0h, & junk);
  666. else
  667. errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l, & junk);
  668. if (errmsg)
  669. return errmsg;
  670. *strp = newp;
  671. *valuep = ! value;
  672. return 0;
  673. }
  674. /* Accept .b or .w in any case. */
  675. static const char *
  676. parse_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
  677. int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
  678. {
  679. if (**strp == '.'
  680. && (*(*strp + 1) == 'b' || *(*strp + 1) == 'B'
  681. || *(*strp + 1) == 'w' || *(*strp + 1) == 'W'))
  682. {
  683. *strp += 2;
  684. return NULL;
  685. }
  686. return _("Invalid size specifier");
  687. }
  688. /* Special check to ensure that instruction exists for given machine. */
  689. int
  690. m32c_cgen_insn_supported (CGEN_CPU_DESC cd,
  691. const CGEN_INSN *insn)
  692. {
  693. int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
  694. CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
  695. /* If attributes are absent, assume no restriction. */
  696. if (machs == 0)
  697. machs = ~0;
  698. return ((machs & cd->machs)
  699. && cgen_bitset_intersect_p (& isas, cd->isas));
  700. }
  701. /* Parse a set of registers, R0,R1,A0,A1,SB,FB. */
  702. static const char *
  703. parse_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  704. const char **strp,
  705. int opindex ATTRIBUTE_UNUSED,
  706. unsigned long *valuep,
  707. int push)
  708. {
  709. const char *errmsg = 0;
  710. int regno = 0;
  711. *valuep = 0;
  712. while (**strp && **strp != ')')
  713. {
  714. if (**strp == 'r' || **strp == 'R')
  715. {
  716. ++*strp;
  717. regno = **strp - '0';
  718. if (regno > 4)
  719. errmsg = _("Register number is not valid");
  720. }
  721. else if (**strp == 'a' || **strp == 'A')
  722. {
  723. ++*strp;
  724. regno = **strp - '0';
  725. if (regno > 2)
  726. errmsg = _("Register number is not valid");
  727. regno = **strp - '0' + 4;
  728. }
  729. else if (strncasecmp (*strp, "sb", 2) == 0 || strncasecmp (*strp, "SB", 2) == 0)
  730. {
  731. regno = 6;
  732. ++*strp;
  733. }
  734. else if (strncasecmp (*strp, "fb", 2) == 0 || strncasecmp (*strp, "FB", 2) == 0)
  735. {
  736. regno = 7;
  737. ++*strp;
  738. }
  739. if (push) /* Mask is reversed for push. */
  740. *valuep |= 0x80 >> regno;
  741. else
  742. *valuep |= 1 << regno;
  743. ++*strp;
  744. if (**strp == ',')
  745. {
  746. if (*(*strp + 1) == ')')
  747. break;
  748. ++*strp;
  749. }
  750. }
  751. if (!*strp)
  752. errmsg = _("Register list is not valid");
  753. return errmsg;
  754. }
  755. #define POP 0
  756. #define PUSH 1
  757. static const char *
  758. parse_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  759. const char **strp,
  760. int opindex ATTRIBUTE_UNUSED,
  761. unsigned long *valuep)
  762. {
  763. return parse_regset (cd, strp, opindex, valuep, POP);
  764. }
  765. static const char *
  766. parse_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  767. const char **strp,
  768. int opindex ATTRIBUTE_UNUSED,
  769. unsigned long *valuep)
  770. {
  771. return parse_regset (cd, strp, opindex, valuep, PUSH);
  772. }
  773. /* -- dis.c */
  774. #include "elf/m32c.h"
  775. #include "elf-bfd.h"
  776. /* Always print the short insn format suffix as ':<char>'. */
  777. static void
  778. print_suffix (void * dis_info, char suffix)
  779. {
  780. disassemble_info *info = dis_info;
  781. (*info->fprintf_func) (info->stream, ":%c", suffix);
  782. }
  783. static void
  784. print_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  785. void * dis_info,
  786. long value ATTRIBUTE_UNUSED,
  787. unsigned int attrs ATTRIBUTE_UNUSED,
  788. bfd_vma pc ATTRIBUTE_UNUSED,
  789. int length ATTRIBUTE_UNUSED)
  790. {
  791. print_suffix (dis_info, 's');
  792. }
  793. static void
  794. print_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  795. void * dis_info,
  796. long value ATTRIBUTE_UNUSED,
  797. unsigned int attrs ATTRIBUTE_UNUSED,
  798. bfd_vma pc ATTRIBUTE_UNUSED,
  799. int length ATTRIBUTE_UNUSED)
  800. {
  801. print_suffix (dis_info, 'g');
  802. }
  803. static void
  804. print_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  805. void * dis_info,
  806. long value ATTRIBUTE_UNUSED,
  807. unsigned int attrs ATTRIBUTE_UNUSED,
  808. bfd_vma pc ATTRIBUTE_UNUSED,
  809. int length ATTRIBUTE_UNUSED)
  810. {
  811. print_suffix (dis_info, 'q');
  812. }
  813. static void
  814. print_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  815. void * dis_info,
  816. long value ATTRIBUTE_UNUSED,
  817. unsigned int attrs ATTRIBUTE_UNUSED,
  818. bfd_vma pc ATTRIBUTE_UNUSED,
  819. int length ATTRIBUTE_UNUSED)
  820. {
  821. print_suffix (dis_info, 'z');
  822. }
  823. /* Print the empty suffix. */
  824. static void
  825. print_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  826. void * dis_info ATTRIBUTE_UNUSED,
  827. long value ATTRIBUTE_UNUSED,
  828. unsigned int attrs ATTRIBUTE_UNUSED,
  829. bfd_vma pc ATTRIBUTE_UNUSED,
  830. int length ATTRIBUTE_UNUSED)
  831. {
  832. return;
  833. }
  834. static void
  835. print_r0l_r0h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  836. void * dis_info,
  837. long value,
  838. unsigned int attrs ATTRIBUTE_UNUSED,
  839. bfd_vma pc ATTRIBUTE_UNUSED,
  840. int length ATTRIBUTE_UNUSED)
  841. {
  842. disassemble_info *info = dis_info;
  843. if (value == 0)
  844. (*info->fprintf_func) (info->stream, "r0h,r0l");
  845. else
  846. (*info->fprintf_func) (info->stream, "r0l,r0h");
  847. }
  848. static void
  849. print_unsigned_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  850. void * dis_info,
  851. unsigned long value,
  852. unsigned int attrs ATTRIBUTE_UNUSED,
  853. bfd_vma pc ATTRIBUTE_UNUSED,
  854. int length ATTRIBUTE_UNUSED)
  855. {
  856. disassemble_info *info = dis_info;
  857. (*info->fprintf_func) (info->stream, "%ld,0x%lx", value & 0x7, value >> 3);
  858. }
  859. static void
  860. print_signed_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  861. void * dis_info,
  862. signed long value,
  863. unsigned int attrs ATTRIBUTE_UNUSED,
  864. bfd_vma pc ATTRIBUTE_UNUSED,
  865. int length ATTRIBUTE_UNUSED)
  866. {
  867. disassemble_info *info = dis_info;
  868. (*info->fprintf_func) (info->stream, "%ld,%ld", value & 0x7, value >> 3);
  869. }
  870. static void
  871. print_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  872. void * dis_info,
  873. long value ATTRIBUTE_UNUSED,
  874. unsigned int attrs ATTRIBUTE_UNUSED,
  875. bfd_vma pc ATTRIBUTE_UNUSED,
  876. int length ATTRIBUTE_UNUSED)
  877. {
  878. /* Always print the size as '.w'. */
  879. disassemble_info *info = dis_info;
  880. (*info->fprintf_func) (info->stream, ".w");
  881. }
  882. #define POP 0
  883. #define PUSH 1
  884. static void print_pop_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
  885. static void print_push_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
  886. /* Print a set of registers, R0,R1,A0,A1,SB,FB. */
  887. static void
  888. print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  889. void * dis_info,
  890. long value,
  891. unsigned int attrs ATTRIBUTE_UNUSED,
  892. bfd_vma pc ATTRIBUTE_UNUSED,
  893. int length ATTRIBUTE_UNUSED,
  894. int push)
  895. {
  896. static char * m16c_register_names [] =
  897. {
  898. "r0", "r1", "r2", "r3", "a0", "a1", "sb", "fb"
  899. };
  900. disassemble_info *info = dis_info;
  901. int mask;
  902. int reg_index = 0;
  903. char* comma = "";
  904. if (push)
  905. mask = 0x80;
  906. else
  907. mask = 1;
  908. if (value & mask)
  909. {
  910. (*info->fprintf_func) (info->stream, "%s", m16c_register_names [0]);
  911. comma = ",";
  912. }
  913. for (reg_index = 1; reg_index <= 7; ++reg_index)
  914. {
  915. if (push)
  916. mask >>= 1;
  917. else
  918. mask <<= 1;
  919. if (value & mask)
  920. {
  921. (*info->fprintf_func) (info->stream, "%s%s", comma,
  922. m16c_register_names [reg_index]);
  923. comma = ",";
  924. }
  925. }
  926. }
  927. static void
  928. print_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  929. void * dis_info,
  930. long value,
  931. unsigned int attrs ATTRIBUTE_UNUSED,
  932. bfd_vma pc ATTRIBUTE_UNUSED,
  933. int length ATTRIBUTE_UNUSED)
  934. {
  935. print_regset (cd, dis_info, value, attrs, pc, length, POP);
  936. }
  937. static void
  938. print_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  939. void * dis_info,
  940. long value,
  941. unsigned int attrs ATTRIBUTE_UNUSED,
  942. bfd_vma pc ATTRIBUTE_UNUSED,
  943. int length ATTRIBUTE_UNUSED)
  944. {
  945. print_regset (cd, dis_info, value, attrs, pc, length, PUSH);
  946. }
  947. static void
  948. print_signed4n (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  949. void * dis_info,
  950. signed long value,
  951. unsigned int attrs ATTRIBUTE_UNUSED,
  952. bfd_vma pc ATTRIBUTE_UNUSED,
  953. int length ATTRIBUTE_UNUSED)
  954. {
  955. disassemble_info *info = dis_info;
  956. (*info->fprintf_func) (info->stream, "%ld", -value);
  957. }