home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / gas / config / m68k-parse.y < prev    next >
Text File  |  1996-09-28  |  20KB  |  1,045 lines

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