[BACK]Return to m68k-parse.y CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / gas / config

Annotation of src/external/gpl3/binutils.old/dist/gas/config/m68k-parse.y, Revision 1.5

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

CVSweb <webmaster@jp.NetBSD.org>