PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/sdcc-290-pre1/binutils-avr/gas/config/m68k-parse.y

#
Happy | 1061 lines | 957 code | 104 blank | 0 comment | 0 complexity | 9c349d1fdfc29afcbe11cc3073ac91e7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, GPL-3.0
  1. /* m68k.y -- bison grammar for m68k operand parsing
  2. Copyright (C) 1995, 96, 1997, 1998 Free Software Foundation, Inc.
  3. Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
  4. This file is part of GAS, the GNU Assembler.
  5. GAS 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 2, or (at your option)
  8. any later version.
  9. GAS 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 GAS; see the file COPYING. If not, write to the Free
  15. Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  16. 02111-1307, USA. */
  17. /* This file holds a bison grammar to parse m68k operands. The m68k
  18. has a complicated operand syntax, and gas supports two main
  19. variations of it. Using a grammar is probably overkill, but at
  20. least it makes clear exactly what we do support. */
  21. %{
  22. #include "as.h"
  23. #include "tc-m68k.h"
  24. #include "m68k-parse.h"
  25. /* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
  26. etc), as well as gratuitiously global symbol names If other parser
  27. generators (bison, byacc, etc) produce additional global names that
  28. conflict at link time, then those parser generators need to be
  29. fixed instead of adding those names to this list. */
  30. #define yymaxdepth m68k_maxdepth
  31. #define yyparse m68k_parse
  32. #define yylex m68k_lex
  33. #define yyerror m68k_error
  34. #define yylval m68k_lval
  35. #define yychar m68k_char
  36. #define yydebug m68k_debug
  37. #define yypact m68k_pact
  38. #define yyr1 m68k_r1
  39. #define yyr2 m68k_r2
  40. #define yydef m68k_def
  41. #define yychk m68k_chk
  42. #define yypgo m68k_pgo
  43. #define yyact m68k_act
  44. #define yyexca m68k_exca
  45. #define yyerrflag m68k_errflag
  46. #define yynerrs m68k_nerrs
  47. #define yyps m68k_ps
  48. #define yypv m68k_pv
  49. #define yys m68k_s
  50. #define yy_yys m68k_yys
  51. #define yystate m68k_state
  52. #define yytmp m68k_tmp
  53. #define yyv m68k_v
  54. #define yy_yyv m68k_yyv
  55. #define yyval m68k_val
  56. #define yylloc m68k_lloc
  57. #define yyreds m68k_reds /* With YYDEBUG defined */
  58. #define yytoks m68k_toks /* With YYDEBUG defined */
  59. #define yylhs m68k_yylhs
  60. #define yylen m68k_yylen
  61. #define yydefred m68k_yydefred
  62. #define yydgoto m68k_yydgoto
  63. #define yysindex m68k_yysindex
  64. #define yyrindex m68k_yyrindex
  65. #define yygindex m68k_yygindex
  66. #define yytable m68k_yytable
  67. #define yycheck m68k_yycheck
  68. #ifndef YYDEBUG
  69. #define YYDEBUG 1
  70. #endif
  71. /* Internal functions. */
  72. static enum m68k_register m68k_reg_parse PARAMS ((char **));
  73. static int yylex PARAMS ((void));
  74. static void yyerror PARAMS ((const char *));
  75. /* The parser sets fields pointed to by this global variable. */
  76. static struct m68k_op *op;
  77. %}
  78. %union
  79. {
  80. struct m68k_indexreg indexreg;
  81. enum m68k_register reg;
  82. struct m68k_exp exp;
  83. unsigned long mask;
  84. int onereg;
  85. }
  86. %token <reg> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
  87. %token <indexreg> INDEXREG
  88. %token <exp> EXPR
  89. %type <indexreg> zireg zdireg
  90. %type <reg> zadr zdr apc zapc zpc optzapc optczapc
  91. %type <exp> optcexpr optexprc
  92. %type <mask> reglist ireglist reglistpair
  93. %type <onereg> reglistreg
  94. %%
  95. /* An operand. */
  96. operand:
  97. generic_operand
  98. | motorola_operand
  99. | mit_operand
  100. ;
  101. /* A generic operand. */
  102. generic_operand:
  103. DR
  104. {
  105. op->mode = DREG;
  106. op->reg = $1;
  107. }
  108. | AR
  109. {
  110. op->mode = AREG;
  111. op->reg = $1;
  112. }
  113. | FPR
  114. {
  115. op->mode = FPREG;
  116. op->reg = $1;
  117. }
  118. | FPCR
  119. {
  120. op->mode = CONTROL;
  121. op->reg = $1;
  122. }
  123. | CREG
  124. {
  125. op->mode = CONTROL;
  126. op->reg = $1;
  127. }
  128. | EXPR
  129. {
  130. op->mode = ABSL;
  131. op->disp = $1;
  132. }
  133. | '#' EXPR
  134. {
  135. op->mode = IMMED;
  136. op->disp = $2;
  137. }
  138. | '&' EXPR
  139. {
  140. op->mode = IMMED;
  141. op->disp = $2;
  142. }
  143. | reglist
  144. {
  145. op->mode = REGLST;
  146. op->mask = $1;
  147. }
  148. ;
  149. /* An operand in Motorola syntax. This includes MRI syntax as well,
  150. which may or may not be different in that it permits commutativity
  151. of index and base registers, and permits an offset expression to
  152. appear inside or outside of the parentheses. */
  153. motorola_operand:
  154. '(' AR ')'
  155. {
  156. op->mode = AINDR;
  157. op->reg = $2;
  158. }
  159. | '(' AR ')' '+'
  160. {
  161. op->mode = AINC;
  162. op->reg = $2;
  163. }
  164. | '-' '(' AR ')'
  165. {
  166. op->mode = ADEC;
  167. op->reg = $3;
  168. }
  169. | '(' EXPR ',' zapc ')'
  170. {
  171. op->reg = $4;
  172. op->disp = $2;
  173. if (($4 >= ZADDR0 && $4 <= ZADDR7)
  174. || $4 == ZPC)
  175. op->mode = BASE;
  176. else
  177. op->mode = DISP;
  178. }
  179. | '(' zapc ',' EXPR ')'
  180. {
  181. op->reg = $2;
  182. op->disp = $4;
  183. if (($2 >= ZADDR0 && $2 <= ZADDR7)
  184. || $2 == ZPC)
  185. op->mode = BASE;
  186. else
  187. op->mode = DISP;
  188. }
  189. | EXPR '(' zapc ')'
  190. {
  191. op->reg = $3;
  192. op->disp = $1;
  193. if (($3 >= ZADDR0 && $3 <= ZADDR7)
  194. || $3 == ZPC)
  195. op->mode = BASE;
  196. else
  197. op->mode = DISP;
  198. }
  199. | '(' LPC ')'
  200. {
  201. op->mode = DISP;
  202. op->reg = $2;
  203. }
  204. | '(' ZAR ')'
  205. {
  206. op->mode = BASE;
  207. op->reg = $2;
  208. }
  209. | '(' LZPC ')'
  210. {
  211. op->mode = BASE;
  212. op->reg = $2;
  213. }
  214. | '(' EXPR ',' zapc ',' zireg ')'
  215. {
  216. op->mode = BASE;
  217. op->reg = $4;
  218. op->disp = $2;
  219. op->index = $6;
  220. }
  221. | '(' EXPR ',' zapc ',' zpc ')'
  222. {
  223. if ($4 == PC || $4 == ZPC)
  224. yyerror (_("syntax error"));
  225. op->mode = BASE;
  226. op->reg = $6;
  227. op->disp = $2;
  228. op->index.reg = $4;
  229. op->index.size = SIZE_UNSPEC;
  230. op->index.scale = 1;
  231. }
  232. | '(' EXPR ',' zdireg optczapc ')'
  233. {
  234. op->mode = BASE;
  235. op->reg = $5;
  236. op->disp = $2;
  237. op->index = $4;
  238. }
  239. | '(' zdireg ',' EXPR ')'
  240. {
  241. op->mode = BASE;
  242. op->disp = $4;
  243. op->index = $2;
  244. }
  245. | EXPR '(' zapc ',' zireg ')'
  246. {
  247. op->mode = BASE;
  248. op->reg = $3;
  249. op->disp = $1;
  250. op->index = $5;
  251. }
  252. | '(' zapc ',' zireg ')'
  253. {
  254. op->mode = BASE;
  255. op->reg = $2;
  256. op->index = $4;
  257. }
  258. | EXPR '(' zapc ',' zpc ')'
  259. {
  260. if ($3 == PC || $3 == ZPC)
  261. yyerror (_("syntax error"));
  262. op->mode = BASE;
  263. op->reg = $5;
  264. op->disp = $1;
  265. op->index.reg = $3;
  266. op->index.size = SIZE_UNSPEC;
  267. op->index.scale = 1;
  268. }
  269. | '(' zapc ',' zpc ')'
  270. {
  271. if ($2 == PC || $2 == ZPC)
  272. yyerror (_("syntax error"));
  273. op->mode = BASE;
  274. op->reg = $4;
  275. op->index.reg = $2;
  276. op->index.size = SIZE_UNSPEC;
  277. op->index.scale = 1;
  278. }
  279. | EXPR '(' zdireg optczapc ')'
  280. {
  281. op->mode = BASE;
  282. op->reg = $4;
  283. op->disp = $1;
  284. op->index = $3;
  285. }
  286. | '(' zdireg optczapc ')'
  287. {
  288. op->mode = BASE;
  289. op->reg = $3;
  290. op->index = $2;
  291. }
  292. | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
  293. {
  294. op->mode = POST;
  295. op->reg = $4;
  296. op->disp = $3;
  297. op->index = $7;
  298. op->odisp = $8;
  299. }
  300. | '(' '[' EXPR optczapc ']' optcexpr ')'
  301. {
  302. op->mode = POST;
  303. op->reg = $4;
  304. op->disp = $3;
  305. op->odisp = $6;
  306. }
  307. | '(' '[' zapc ']' ',' zireg optcexpr ')'
  308. {
  309. op->mode = POST;
  310. op->reg = $3;
  311. op->index = $6;
  312. op->odisp = $7;
  313. }
  314. | '(' '[' zapc ']' optcexpr ')'
  315. {
  316. op->mode = POST;
  317. op->reg = $3;
  318. op->odisp = $5;
  319. }
  320. | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
  321. {
  322. op->mode = PRE;
  323. op->reg = $5;
  324. op->disp = $3;
  325. op->index = $7;
  326. op->odisp = $9;
  327. }
  328. | '(' '[' zapc ',' zireg ']' optcexpr ')'
  329. {
  330. op->mode = PRE;
  331. op->reg = $3;
  332. op->index = $5;
  333. op->odisp = $7;
  334. }
  335. | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
  336. {
  337. if ($5 == PC || $5 == ZPC)
  338. yyerror (_("syntax error"));
  339. op->mode = PRE;
  340. op->reg = $7;
  341. op->disp = $3;
  342. op->index.reg = $5;
  343. op->index.size = SIZE_UNSPEC;
  344. op->index.scale = 1;
  345. op->odisp = $9;
  346. }
  347. | '(' '[' zapc ',' zpc ']' optcexpr ')'
  348. {
  349. if ($3 == PC || $3 == ZPC)
  350. yyerror (_("syntax error"));
  351. op->mode = PRE;
  352. op->reg = $5;
  353. op->index.reg = $3;
  354. op->index.size = SIZE_UNSPEC;
  355. op->index.scale = 1;
  356. op->odisp = $7;
  357. }
  358. | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
  359. {
  360. op->mode = PRE;
  361. op->reg = $5;
  362. op->disp = $3;
  363. op->index = $4;
  364. op->odisp = $7;
  365. }
  366. ;
  367. /* An operand in MIT syntax. */
  368. mit_operand:
  369. optzapc '@'
  370. {
  371. /* We use optzapc to avoid a shift/reduce conflict. */
  372. if ($1 < ADDR0 || $1 > ADDR7)
  373. yyerror (_("syntax error"));
  374. op->mode = AINDR;
  375. op->reg = $1;
  376. }
  377. | optzapc '@' '+'
  378. {
  379. /* We use optzapc to avoid a shift/reduce conflict. */
  380. if ($1 < ADDR0 || $1 > ADDR7)
  381. yyerror (_("syntax error"));
  382. op->mode = AINC;
  383. op->reg = $1;
  384. }
  385. | optzapc '@' '-'
  386. {
  387. /* We use optzapc to avoid a shift/reduce conflict. */
  388. if ($1 < ADDR0 || $1 > ADDR7)
  389. yyerror (_("syntax error"));
  390. op->mode = ADEC;
  391. op->reg = $1;
  392. }
  393. | optzapc '@' '(' EXPR ')'
  394. {
  395. op->reg = $1;
  396. op->disp = $4;
  397. if (($1 >= ZADDR0 && $1 <= ZADDR7)
  398. || $1 == ZPC)
  399. op->mode = BASE;
  400. else
  401. op->mode = DISP;
  402. }
  403. | optzapc '@' '(' optexprc zireg ')'
  404. {
  405. op->mode = BASE;
  406. op->reg = $1;
  407. op->disp = $4;
  408. op->index = $5;
  409. }
  410. | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
  411. {
  412. op->mode = POST;
  413. op->reg = $1;
  414. op->disp = $4;
  415. op->index = $9;
  416. op->odisp = $8;
  417. }
  418. | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
  419. {
  420. op->mode = POST;
  421. op->reg = $1;
  422. op->disp = $4;
  423. op->odisp = $8;
  424. }
  425. | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
  426. {
  427. op->mode = PRE;
  428. op->reg = $1;
  429. op->disp = $4;
  430. op->index = $5;
  431. op->odisp = $9;
  432. }
  433. ;
  434. /* An index register, possibly suppressed, which need not have a size
  435. or scale. */
  436. zireg:
  437. INDEXREG
  438. | zadr
  439. {
  440. $$.reg = $1;
  441. $$.size = SIZE_UNSPEC;
  442. $$.scale = 1;
  443. }
  444. ;
  445. /* A register which may be an index register, but which may not be an
  446. address register. This nonterminal is used to avoid ambiguity when
  447. trying to parse something like (0,d5,a6) as compared to (0,a6,d5). */
  448. zdireg:
  449. INDEXREG
  450. | zdr
  451. {
  452. $$.reg = $1;
  453. $$.size = SIZE_UNSPEC;
  454. $$.scale = 1;
  455. }
  456. ;
  457. /* An address or data register, or a suppressed address or data
  458. register. */
  459. zadr:
  460. zdr
  461. | AR
  462. | ZAR
  463. ;
  464. /* A data register which may be suppressed. */
  465. zdr:
  466. DR
  467. | ZDR
  468. ;
  469. /* Either an address register or the PC. */
  470. apc:
  471. AR
  472. | LPC
  473. ;
  474. /* Either an address register, or the PC, or a suppressed address
  475. register, or a suppressed PC. */
  476. zapc:
  477. apc
  478. | LZPC
  479. | ZAR
  480. ;
  481. /* An optional zapc. */
  482. optzapc:
  483. /* empty */
  484. {
  485. $$ = ZADDR0;
  486. }
  487. | zapc
  488. ;
  489. /* The PC, optionally suppressed. */
  490. zpc:
  491. LPC
  492. | LZPC
  493. ;
  494. /* ',' zapc when it may be omitted. */
  495. optczapc:
  496. /* empty */
  497. {
  498. $$ = ZADDR0;
  499. }
  500. | ',' zapc
  501. {
  502. $$ = $2;
  503. }
  504. ;
  505. /* ',' EXPR when it may be omitted. */
  506. optcexpr:
  507. /* empty */
  508. {
  509. $$.exp.X_op = O_absent;
  510. $$.size = SIZE_UNSPEC;
  511. }
  512. | ',' EXPR
  513. {
  514. $$ = $2;
  515. }
  516. ;
  517. /* EXPR ',' when it may be omitted. */
  518. optexprc:
  519. /* empty */
  520. {
  521. $$.exp.X_op = O_absent;
  522. $$.size = SIZE_UNSPEC;
  523. }
  524. | EXPR ','
  525. {
  526. $$ = $1;
  527. }
  528. ;
  529. /* A register list for the movem instruction. */
  530. reglist:
  531. reglistpair
  532. | reglistpair '/' ireglist
  533. {
  534. $$ = $1 | $3;
  535. }
  536. | reglistreg '/' ireglist
  537. {
  538. $$ = (1 << $1) | $3;
  539. }
  540. ;
  541. /* We use ireglist when we know we are looking at a reglist, and we
  542. can safely reduce a simple register to reglistreg. If we permitted
  543. reglist to reduce to reglistreg, it would be ambiguous whether a
  544. plain register were a DREG/AREG/FPREG or a REGLST. */
  545. ireglist:
  546. reglistreg
  547. {
  548. $$ = 1 << $1;
  549. }
  550. | reglistpair
  551. | reglistpair '/' ireglist
  552. {
  553. $$ = $1 | $3;
  554. }
  555. | reglistreg '/' ireglist
  556. {
  557. $$ = (1 << $1) | $3;
  558. }
  559. ;
  560. reglistpair:
  561. reglistreg '-' reglistreg
  562. {
  563. if ($1 <= $3)
  564. $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
  565. else
  566. $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
  567. }
  568. ;
  569. reglistreg:
  570. DR
  571. {
  572. $$ = $1 - DATA0;
  573. }
  574. | AR
  575. {
  576. $$ = $1 - ADDR0 + 8;
  577. }
  578. | FPR
  579. {
  580. $$ = $1 - FP0 + 16;
  581. }
  582. | FPCR
  583. {
  584. if ($1 == FPI)
  585. $$ = 24;
  586. else if ($1 == FPS)
  587. $$ = 25;
  588. else
  589. $$ = 26;
  590. }
  591. ;
  592. %%
  593. /* The string to parse is stored here, and modified by yylex. */
  594. static char *str;
  595. /* The original string pointer. */
  596. static char *strorig;
  597. /* If *CCP could be a register, return the register number and advance
  598. *CCP. Otherwise don't change *CCP, and return 0. */
  599. static enum m68k_register
  600. m68k_reg_parse (ccp)
  601. register char **ccp;
  602. {
  603. char *start = *ccp;
  604. char c;
  605. char *p;
  606. symbolS *symbolp;
  607. if (flag_reg_prefix_optional)
  608. {
  609. if (*start == REGISTER_PREFIX)
  610. start++;
  611. p = start;
  612. }
  613. else
  614. {
  615. if (*start != REGISTER_PREFIX)
  616. return 0;
  617. p = start + 1;
  618. }
  619. if (! is_name_beginner (*p))
  620. return 0;
  621. p++;
  622. while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
  623. p++;
  624. c = *p;
  625. *p = 0;
  626. symbolp = symbol_find (start);
  627. *p = c;
  628. if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
  629. {
  630. *ccp = p;
  631. return S_GET_VALUE (symbolp);
  632. }
  633. /* In MRI mode, something like foo.bar can be equated to a register
  634. name. */
  635. while (flag_mri && c == '.')
  636. {
  637. ++p;
  638. while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
  639. p++;
  640. c = *p;
  641. *p = '\0';
  642. symbolp = symbol_find (start);
  643. *p = c;
  644. if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
  645. {
  646. *ccp = p;
  647. return S_GET_VALUE (symbolp);
  648. }
  649. }
  650. return 0;
  651. }
  652. /* The lexer. */
  653. static int
  654. yylex ()
  655. {
  656. enum m68k_register reg;
  657. char *s;
  658. int parens;
  659. int c = 0;
  660. int tail = 0;
  661. char *hold;
  662. if (*str == ' ')
  663. ++str;
  664. if (*str == '\0')
  665. return 0;
  666. /* Various special characters are just returned directly. */
  667. switch (*str)
  668. {
  669. case '@':
  670. /* In MRI mode, this can be the start of an octal number. */
  671. if (flag_mri)
  672. {
  673. if (isdigit (str[1])
  674. || ((str[1] == '+' || str[1] == '-')
  675. && isdigit (str[2])))
  676. break;
  677. }
  678. /* Fall through. */
  679. case '#':
  680. case '&':
  681. case ',':
  682. case ')':
  683. case '/':
  684. case '[':
  685. case ']':
  686. return *str++;
  687. case '+':
  688. /* It so happens that a '+' can only appear at the end of an
  689. operand. If it appears anywhere else, it must be a unary
  690. plus on an expression. */
  691. if (str[1] == '\0')
  692. return *str++;
  693. break;
  694. case '-':
  695. /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it
  696. appears anywhere else, it must be a unary minus on an
  697. expression. */
  698. if (str[1] == '\0')
  699. return *str++;
  700. s = str + 1;
  701. if (*s == '(')
  702. ++s;
  703. if (m68k_reg_parse (&s) != 0)
  704. return *str++;
  705. break;
  706. case '(':
  707. /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
  708. `)('. If it appears anywhere else, it must be starting an
  709. expression. */
  710. if (str[1] == '['
  711. || (str > strorig
  712. && (str[-1] == '@'
  713. || str[-1] == ')')))
  714. return *str++;
  715. s = str + 1;
  716. if (m68k_reg_parse (&s) != 0)
  717. return *str++;
  718. /* Check for the case of '(expr,...' by scanning ahead. If we
  719. find a comma outside of balanced parentheses, we return '('.
  720. If we find an unbalanced right parenthesis, then presumably
  721. the '(' really starts an expression. */
  722. parens = 0;
  723. for (s = str + 1; *s != '\0'; s++)
  724. {
  725. if (*s == '(')
  726. ++parens;
  727. else if (*s == ')')
  728. {
  729. if (parens == 0)
  730. break;
  731. --parens;
  732. }
  733. else if (*s == ',' && parens == 0)
  734. {
  735. /* A comma can not normally appear in an expression, so
  736. this is a case of '(expr,...'. */
  737. return *str++;
  738. }
  739. }
  740. }
  741. /* See if it's a register. */
  742. reg = m68k_reg_parse (&str);
  743. if (reg != 0)
  744. {
  745. int ret;
  746. yylval.reg = reg;
  747. if (reg >= DATA0 && reg <= DATA7)
  748. ret = DR;
  749. else if (reg >= ADDR0 && reg <= ADDR7)
  750. ret = AR;
  751. else if (reg >= FP0 && reg <= FP7)
  752. return FPR;
  753. else if (reg == FPI
  754. || reg == FPS
  755. || reg == FPC)
  756. return FPCR;
  757. else if (reg == PC)
  758. return LPC;
  759. else if (reg >= ZDATA0 && reg <= ZDATA7)
  760. ret = ZDR;
  761. else if (reg >= ZADDR0 && reg <= ZADDR7)
  762. ret = ZAR;
  763. else if (reg == ZPC)
  764. return LZPC;
  765. else
  766. return CREG;
  767. /* If we get here, we have a data or address register. We
  768. must check for a size or scale; if we find one, we must
  769. return INDEXREG. */
  770. s = str;
  771. if (*s != '.' && *s != ':' && *s != '*')
  772. return ret;
  773. yylval.indexreg.reg = reg;
  774. if (*s != '.' && *s != ':')
  775. yylval.indexreg.size = SIZE_UNSPEC;
  776. else
  777. {
  778. ++s;
  779. switch (*s)
  780. {
  781. case 'w':
  782. case 'W':
  783. yylval.indexreg.size = SIZE_WORD;
  784. ++s;
  785. break;
  786. case 'l':
  787. case 'L':
  788. yylval.indexreg.size = SIZE_LONG;
  789. ++s;
  790. break;
  791. default:
  792. yyerror (_("illegal size specification"));
  793. yylval.indexreg.size = SIZE_UNSPEC;
  794. break;
  795. }
  796. }
  797. yylval.indexreg.scale = 1;
  798. if (*s == '*' || *s == ':')
  799. {
  800. expressionS scale;
  801. ++s;
  802. hold = input_line_pointer;
  803. input_line_pointer = s;
  804. expression (&scale);
  805. s = input_line_pointer;
  806. input_line_pointer = hold;
  807. if (scale.X_op != O_constant)
  808. yyerror (_("scale specification must resolve to a number"));
  809. else
  810. {
  811. switch (scale.X_add_number)
  812. {
  813. case 1:
  814. case 2:
  815. case 4:
  816. case 8:
  817. yylval.indexreg.scale = scale.X_add_number;
  818. break;
  819. default:
  820. yyerror (_("invalid scale value"));
  821. break;
  822. }
  823. }
  824. }
  825. str = s;
  826. return INDEXREG;
  827. }
  828. /* It must be an expression. Before we call expression, we need to
  829. look ahead to see if there is a size specification. We must do
  830. that first, because otherwise foo.l will be treated as the symbol
  831. foo.l, rather than as the symbol foo with a long size
  832. specification. The grammar requires that all expressions end at
  833. the end of the operand, or with ',', '(', ']', ')'. */
  834. parens = 0;
  835. for (s = str; *s != '\0'; s++)
  836. {
  837. if (*s == '(')
  838. {
  839. if (parens == 0
  840. && s > str
  841. && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))
  842. break;
  843. ++parens;
  844. }
  845. else if (*s == ')')
  846. {
  847. if (parens == 0)
  848. break;
  849. --parens;
  850. }
  851. else if (parens == 0
  852. && (*s == ',' || *s == ']'))
  853. break;
  854. }
  855. yylval.exp.size = SIZE_UNSPEC;
  856. if (s <= str + 2
  857. || (s[-2] != '.' && s[-2] != ':'))
  858. tail = 0;
  859. else
  860. {
  861. switch (s[-1])
  862. {
  863. case 's':
  864. case 'S':
  865. case 'b':
  866. case 'B':
  867. yylval.exp.size = SIZE_BYTE;
  868. break;
  869. case 'w':
  870. case 'W':
  871. yylval.exp.size = SIZE_WORD;
  872. break;
  873. case 'l':
  874. case 'L':
  875. yylval.exp.size = SIZE_LONG;
  876. break;
  877. default:
  878. break;
  879. }
  880. if (yylval.exp.size != SIZE_UNSPEC)
  881. tail = 2;
  882. }
  883. #ifdef OBJ_ELF
  884. {
  885. /* Look for @PLTPC, etc. */
  886. char *cp;
  887. yylval.exp.pic_reloc = pic_none;
  888. cp = s - tail;
  889. if (cp - 6 > str && cp[-6] == '@')
  890. {
  891. if (strncmp (cp - 6, "@PLTPC", 6) == 0)
  892. {
  893. yylval.exp.pic_reloc = pic_plt_pcrel;
  894. tail += 6;
  895. }
  896. else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
  897. {
  898. yylval.exp.pic_reloc = pic_got_pcrel;
  899. tail += 6;
  900. }
  901. }
  902. else if (cp - 4 > str && cp[-4] == '@')
  903. {
  904. if (strncmp (cp - 4, "@PLT", 4) == 0)
  905. {
  906. yylval.exp.pic_reloc = pic_plt_off;
  907. tail += 4;
  908. }
  909. else if (strncmp (cp - 4, "@GOT", 4) == 0)
  910. {
  911. yylval.exp.pic_reloc = pic_got_off;
  912. tail += 4;
  913. }
  914. }
  915. }
  916. #endif
  917. if (tail != 0)
  918. {
  919. c = s[-tail];
  920. s[-tail] = 0;
  921. }
  922. hold = input_line_pointer;
  923. input_line_pointer = str;
  924. expression (&yylval.exp.exp);
  925. str = input_line_pointer;
  926. input_line_pointer = hold;
  927. if (tail != 0)
  928. {
  929. s[-tail] = c;
  930. str = s;
  931. }
  932. return EXPR;
  933. }
  934. /* Parse an m68k operand. This is the only function which is called
  935. from outside this file. */
  936. int
  937. m68k_ip_op (s, oparg)
  938. char *s;
  939. struct m68k_op *oparg;
  940. {
  941. memset (oparg, 0, sizeof *oparg);
  942. oparg->error = NULL;
  943. oparg->index.reg = ZDATA0;
  944. oparg->index.scale = 1;
  945. oparg->disp.exp.X_op = O_absent;
  946. oparg->odisp.exp.X_op = O_absent;
  947. str = strorig = s;
  948. op = oparg;
  949. return yyparse ();
  950. }
  951. /* The error handler. */
  952. static void
  953. yyerror (s)
  954. const char *s;
  955. {
  956. op->error = s;
  957. }