OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [m68k-parse.y] - Diff between revs 38 and 156

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 156
/* m68k.y -- bison grammar for m68k operand parsing
/* m68k.y -- bison grammar for m68k operand parsing
   Copyright 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005, 2007
   Copyright 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005, 2007
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
   Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
   Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
   This file is part of GAS, the GNU Assembler.
   This file is part of GAS, the GNU Assembler.
   GAS is free software; you can redistribute it and/or modify
   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   the Free Software Foundation; either version 3, or (at your option)
   any later version.
   any later version.
   GAS is distributed in the hope that it will be useful,
   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the Free
   along with GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */
   02110-1301, USA.  */
/* This file holds a bison grammar to parse m68k operands.  The m68k
/* This file holds a bison grammar to parse m68k operands.  The m68k
   has a complicated operand syntax, and gas supports two main
   has a complicated operand syntax, and gas supports two main
   variations of it.  Using a grammar is probably overkill, but at
   variations of it.  Using a grammar is probably overkill, but at
   least it makes clear exactly what we do support.  */
   least it makes clear exactly what we do support.  */
%{
%{
#include "as.h"
#include "as.h"
#include "tc-m68k.h"
#include "tc-m68k.h"
#include "m68k-parse.h"
#include "m68k-parse.h"
#include "safe-ctype.h"
#include "safe-ctype.h"
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
   etc), as well as gratuitously global symbol names If other parser
   etc), as well as gratuitously global symbol names If other parser
   generators (bison, byacc, etc) produce additional global names that
   generators (bison, byacc, etc) produce additional global names that
   conflict at link time, then those parser generators need to be
   conflict at link time, then those parser generators need to be
   fixed instead of adding those names to this list.  */
   fixed instead of adding those names to this list.  */
#define yymaxdepth m68k_maxdepth
#define yymaxdepth m68k_maxdepth
#define yyparse m68k_parse
#define yyparse m68k_parse
#define yylex   m68k_lex
#define yylex   m68k_lex
#define yyerror m68k_error
#define yyerror m68k_error
#define yylval  m68k_lval
#define yylval  m68k_lval
#define yychar  m68k_char
#define yychar  m68k_char
#define yydebug m68k_debug
#define yydebug m68k_debug
#define yypact  m68k_pact
#define yypact  m68k_pact
#define yyr1    m68k_r1
#define yyr1    m68k_r1
#define yyr2    m68k_r2
#define yyr2    m68k_r2
#define yydef   m68k_def
#define yydef   m68k_def
#define yychk   m68k_chk
#define yychk   m68k_chk
#define yypgo   m68k_pgo
#define yypgo   m68k_pgo
#define yyact   m68k_act
#define yyact   m68k_act
#define yyexca  m68k_exca
#define yyexca  m68k_exca
#define yyerrflag m68k_errflag
#define yyerrflag m68k_errflag
#define yynerrs m68k_nerrs
#define yynerrs m68k_nerrs
#define yyps    m68k_ps
#define yyps    m68k_ps
#define yypv    m68k_pv
#define yypv    m68k_pv
#define yys     m68k_s
#define yys     m68k_s
#define yy_yys  m68k_yys
#define yy_yys  m68k_yys
#define yystate m68k_state
#define yystate m68k_state
#define yytmp   m68k_tmp
#define yytmp   m68k_tmp
#define yyv     m68k_v
#define yyv     m68k_v
#define yy_yyv  m68k_yyv
#define yy_yyv  m68k_yyv
#define yyval   m68k_val
#define yyval   m68k_val
#define yylloc  m68k_lloc
#define yylloc  m68k_lloc
#define yyreds  m68k_reds               /* With YYDEBUG defined */
#define yyreds  m68k_reds               /* With YYDEBUG defined */
#define yytoks  m68k_toks               /* With YYDEBUG defined */
#define yytoks  m68k_toks               /* With YYDEBUG defined */
#define yylhs   m68k_yylhs
#define yylhs   m68k_yylhs
#define yylen   m68k_yylen
#define yylen   m68k_yylen
#define yydefred m68k_yydefred
#define yydefred m68k_yydefred
#define yydgoto m68k_yydgoto
#define yydgoto m68k_yydgoto
#define yysindex m68k_yysindex
#define yysindex m68k_yysindex
#define yyrindex m68k_yyrindex
#define yyrindex m68k_yyrindex
#define yygindex m68k_yygindex
#define yygindex m68k_yygindex
#define yytable  m68k_yytable
#define yytable  m68k_yytable
#define yycheck  m68k_yycheck
#define yycheck  m68k_yycheck
#ifndef YYDEBUG
#ifndef YYDEBUG
#define YYDEBUG 1
#define YYDEBUG 1
#endif
#endif
/* Internal functions.  */
/* Internal functions.  */
static enum m68k_register m68k_reg_parse (char **);
static enum m68k_register m68k_reg_parse (char **);
static int yylex (void);
static int yylex (void);
static void yyerror (const char *);
static void yyerror (const char *);
/* The parser sets fields pointed to by this global variable.  */
/* The parser sets fields pointed to by this global variable.  */
static struct m68k_op *op;
static struct m68k_op *op;
%}
%}
%union
%union
{
{
  struct m68k_indexreg indexreg;
  struct m68k_indexreg indexreg;
  enum m68k_register reg;
  enum m68k_register reg;
  struct m68k_exp exp;
  struct m68k_exp exp;
  unsigned long mask;
  unsigned long mask;
  int onereg;
  int onereg;
  int trailing_ampersand;
  int trailing_ampersand;
}
}
%token  DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
%token  DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
%token  INDEXREG
%token  INDEXREG
%token  EXPR
%token  EXPR
%type  zireg zdireg
%type  zireg zdireg
%type  zadr zdr apc zapc zpc optzapc optczapc
%type  zadr zdr apc zapc zpc optzapc optczapc
%type  optcexpr optexprc
%type  optcexpr optexprc
%type  reglist ireglist reglistpair
%type  reglist ireglist reglistpair
%type  reglistreg
%type  reglistreg
%type  optional_ampersand
%type  optional_ampersand
%%
%%
/* An operand.  */
/* An operand.  */
operand:
operand:
          generic_operand
          generic_operand
        | motorola_operand optional_ampersand
        | motorola_operand optional_ampersand
                {
                {
                  op->trailing_ampersand = $2;
                  op->trailing_ampersand = $2;
                }
                }
        | mit_operand optional_ampersand
        | mit_operand optional_ampersand
                {
                {
                  op->trailing_ampersand = $2;
                  op->trailing_ampersand = $2;
                }
                }
        ;
        ;
/* A trailing ampersand(for MAC/EMAC mask addressing).  */
/* A trailing ampersand(for MAC/EMAC mask addressing).  */
optional_ampersand:
optional_ampersand:
        /* empty */
        /* empty */
                { $$ = 0; }
                { $$ = 0; }
        | '&'
        | '&'
                { $$ = 1; }
                { $$ = 1; }
        ;
        ;
/* A generic operand.  */
/* A generic operand.  */
generic_operand:
generic_operand:
          '<' '<'
          '<' '<'
                {
                {
                  op->mode = LSH;
                  op->mode = LSH;
                }
                }
        | '>' '>'
        | '>' '>'
                {
                {
                  op->mode = RSH;
                  op->mode = RSH;
                }
                }
        | DR
        | DR
                {
                {
                  op->mode = DREG;
                  op->mode = DREG;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | AR
        | AR
                {
                {
                  op->mode = AREG;
                  op->mode = AREG;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | FPR
        | FPR
                {
                {
                  op->mode = FPREG;
                  op->mode = FPREG;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | FPCR
        | FPCR
                {
                {
                  op->mode = CONTROL;
                  op->mode = CONTROL;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | CREG
        | CREG
                {
                {
                  op->mode = CONTROL;
                  op->mode = CONTROL;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | EXPR
        | EXPR
                {
                {
                  op->mode = ABSL;
                  op->mode = ABSL;
                  op->disp = $1;
                  op->disp = $1;
                }
                }
        | '#' EXPR
        | '#' EXPR
                {
                {
                  op->mode = IMMED;
                  op->mode = IMMED;
                  op->disp = $2;
                  op->disp = $2;
                }
                }
        | '&' EXPR
        | '&' EXPR
                {
                {
                  op->mode = IMMED;
                  op->mode = IMMED;
                  op->disp = $2;
                  op->disp = $2;
                }
                }
        | reglist
        | reglist
                {
                {
                  op->mode = REGLST;
                  op->mode = REGLST;
                  op->mask = $1;
                  op->mask = $1;
                }
                }
        ;
        ;
/* An operand in Motorola syntax.  This includes MRI syntax as well,
/* An operand in Motorola syntax.  This includes MRI syntax as well,
   which may or may not be different in that it permits commutativity
   which may or may not be different in that it permits commutativity
   of index and base registers, and permits an offset expression to
   of index and base registers, and permits an offset expression to
   appear inside or outside of the parentheses.  */
   appear inside or outside of the parentheses.  */
motorola_operand:
motorola_operand:
          '(' AR ')'
          '(' AR ')'
                {
                {
                  op->mode = AINDR;
                  op->mode = AINDR;
                  op->reg = $2;
                  op->reg = $2;
                }
                }
        | '(' AR ')' '+'
        | '(' AR ')' '+'
                {
                {
                  op->mode = AINC;
                  op->mode = AINC;
                  op->reg = $2;
                  op->reg = $2;
                }
                }
        | '-' '(' AR ')'
        | '-' '(' AR ')'
                {
                {
                  op->mode = ADEC;
                  op->mode = ADEC;
                  op->reg = $3;
                  op->reg = $3;
                }
                }
        | '(' EXPR ',' zapc ')'
        | '(' EXPR ',' zapc ')'
                {
                {
                  op->reg = $4;
                  op->reg = $4;
                  op->disp = $2;
                  op->disp = $2;
                  if (($4 >= ZADDR0 && $4 <= ZADDR7)
                  if (($4 >= ZADDR0 && $4 <= ZADDR7)
                      || $4 == ZPC)
                      || $4 == ZPC)
                    op->mode = BASE;
                    op->mode = BASE;
                  else
                  else
                    op->mode = DISP;
                    op->mode = DISP;
                }
                }
        | '(' zapc ',' EXPR ')'
        | '(' zapc ',' EXPR ')'
                {
                {
                  op->reg = $2;
                  op->reg = $2;
                  op->disp = $4;
                  op->disp = $4;
                  if (($2 >= ZADDR0 && $2 <= ZADDR7)
                  if (($2 >= ZADDR0 && $2 <= ZADDR7)
                      || $2 == ZPC)
                      || $2 == ZPC)
                    op->mode = BASE;
                    op->mode = BASE;
                  else
                  else
                    op->mode = DISP;
                    op->mode = DISP;
                }
                }
        | EXPR '(' zapc ')'
        | EXPR '(' zapc ')'
                {
                {
                  op->reg = $3;
                  op->reg = $3;
                  op->disp = $1;
                  op->disp = $1;
                  if (($3 >= ZADDR0 && $3 <= ZADDR7)
                  if (($3 >= ZADDR0 && $3 <= ZADDR7)
                      || $3 == ZPC)
                      || $3 == ZPC)
                    op->mode = BASE;
                    op->mode = BASE;
                  else
                  else
                    op->mode = DISP;
                    op->mode = DISP;
                }
                }
        | '(' LPC ')'
        | '(' LPC ')'
                {
                {
                  op->mode = DISP;
                  op->mode = DISP;
                  op->reg = $2;
                  op->reg = $2;
                }
                }
        | '(' ZAR ')'
        | '(' ZAR ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $2;
                  op->reg = $2;
                }
                }
        | '(' LZPC ')'
        | '(' LZPC ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $2;
                  op->reg = $2;
                }
                }
        | '(' EXPR ',' zapc ',' zireg ')'
        | '(' EXPR ',' zapc ',' zireg ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $4;
                  op->reg = $4;
                  op->disp = $2;
                  op->disp = $2;
                  op->index = $6;
                  op->index = $6;
                }
                }
        | '(' EXPR ',' zapc ',' zpc ')'
        | '(' EXPR ',' zapc ',' zpc ')'
                {
                {
                  if ($4 == PC || $4 == ZPC)
                  if ($4 == PC || $4 == ZPC)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $6;
                  op->reg = $6;
                  op->disp = $2;
                  op->disp = $2;
                  op->index.reg = $4;
                  op->index.reg = $4;
                  op->index.size = SIZE_UNSPEC;
                  op->index.size = SIZE_UNSPEC;
                  op->index.scale = 1;
                  op->index.scale = 1;
                }
                }
        | '(' EXPR ',' zdireg optczapc ')'
        | '(' EXPR ',' zdireg optczapc ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $5;
                  op->reg = $5;
                  op->disp = $2;
                  op->disp = $2;
                  op->index = $4;
                  op->index = $4;
                }
                }
        | '(' zdireg ',' EXPR ')'
        | '(' zdireg ',' EXPR ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->disp = $4;
                  op->disp = $4;
                  op->index = $2;
                  op->index = $2;
                }
                }
        | EXPR '(' zapc ',' zireg ')'
        | EXPR '(' zapc ',' zireg ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $3;
                  op->reg = $3;
                  op->disp = $1;
                  op->disp = $1;
                  op->index = $5;
                  op->index = $5;
                }
                }
        | '(' zapc ',' zireg ')'
        | '(' zapc ',' zireg ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $2;
                  op->reg = $2;
                  op->index = $4;
                  op->index = $4;
                }
                }
        | EXPR '(' zapc ',' zpc ')'
        | EXPR '(' zapc ',' zpc ')'
                {
                {
                  if ($3 == PC || $3 == ZPC)
                  if ($3 == PC || $3 == ZPC)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $5;
                  op->reg = $5;
                  op->disp = $1;
                  op->disp = $1;
                  op->index.reg = $3;
                  op->index.reg = $3;
                  op->index.size = SIZE_UNSPEC;
                  op->index.size = SIZE_UNSPEC;
                  op->index.scale = 1;
                  op->index.scale = 1;
                }
                }
        | '(' zapc ',' zpc ')'
        | '(' zapc ',' zpc ')'
                {
                {
                  if ($2 == PC || $2 == ZPC)
                  if ($2 == PC || $2 == ZPC)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $4;
                  op->reg = $4;
                  op->index.reg = $2;
                  op->index.reg = $2;
                  op->index.size = SIZE_UNSPEC;
                  op->index.size = SIZE_UNSPEC;
                  op->index.scale = 1;
                  op->index.scale = 1;
                }
                }
        | EXPR '(' zdireg optczapc ')'
        | EXPR '(' zdireg optczapc ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $4;
                  op->reg = $4;
                  op->disp = $1;
                  op->disp = $1;
                  op->index = $3;
                  op->index = $3;
                }
                }
        | '(' zdireg optczapc ')'
        | '(' zdireg optczapc ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $3;
                  op->reg = $3;
                  op->index = $2;
                  op->index = $2;
                }
                }
        | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
        | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $4;
                  op->reg = $4;
                  op->disp = $3;
                  op->disp = $3;
                  op->index = $7;
                  op->index = $7;
                  op->odisp = $8;
                  op->odisp = $8;
                }
                }
        | '(' '[' EXPR optczapc ']' optcexpr ')'
        | '(' '[' EXPR optczapc ']' optcexpr ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $4;
                  op->reg = $4;
                  op->disp = $3;
                  op->disp = $3;
                  op->odisp = $6;
                  op->odisp = $6;
                }
                }
        | '(' '[' zapc ']' ',' zireg optcexpr ')'
        | '(' '[' zapc ']' ',' zireg optcexpr ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $3;
                  op->reg = $3;
                  op->index = $6;
                  op->index = $6;
                  op->odisp = $7;
                  op->odisp = $7;
                }
                }
        | '(' '[' zapc ']' optcexpr ')'
        | '(' '[' zapc ']' optcexpr ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $3;
                  op->reg = $3;
                  op->odisp = $5;
                  op->odisp = $5;
                }
                }
        | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
        | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
                {
                {
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $5;
                  op->reg = $5;
                  op->disp = $3;
                  op->disp = $3;
                  op->index = $7;
                  op->index = $7;
                  op->odisp = $9;
                  op->odisp = $9;
                }
                }
        | '(' '[' zapc ',' zireg ']' optcexpr ')'
        | '(' '[' zapc ',' zireg ']' optcexpr ')'
                {
                {
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $3;
                  op->reg = $3;
                  op->index = $5;
                  op->index = $5;
                  op->odisp = $7;
                  op->odisp = $7;
                }
                }
        | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
        | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
                {
                {
                  if ($5 == PC || $5 == ZPC)
                  if ($5 == PC || $5 == ZPC)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $7;
                  op->reg = $7;
                  op->disp = $3;
                  op->disp = $3;
                  op->index.reg = $5;
                  op->index.reg = $5;
                  op->index.size = SIZE_UNSPEC;
                  op->index.size = SIZE_UNSPEC;
                  op->index.scale = 1;
                  op->index.scale = 1;
                  op->odisp = $9;
                  op->odisp = $9;
                }
                }
        | '(' '[' zapc ',' zpc ']' optcexpr ')'
        | '(' '[' zapc ',' zpc ']' optcexpr ')'
                {
                {
                  if ($3 == PC || $3 == ZPC)
                  if ($3 == PC || $3 == ZPC)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $5;
                  op->reg = $5;
                  op->index.reg = $3;
                  op->index.reg = $3;
                  op->index.size = SIZE_UNSPEC;
                  op->index.size = SIZE_UNSPEC;
                  op->index.scale = 1;
                  op->index.scale = 1;
                  op->odisp = $7;
                  op->odisp = $7;
                }
                }
        | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
        | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
                {
                {
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $5;
                  op->reg = $5;
                  op->disp = $3;
                  op->disp = $3;
                  op->index = $4;
                  op->index = $4;
                  op->odisp = $7;
                  op->odisp = $7;
                }
                }
        ;
        ;
/* An operand in MIT syntax.  */
/* An operand in MIT syntax.  */
mit_operand:
mit_operand:
          optzapc '@'
          optzapc '@'
                {
                {
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  if ($1 < ADDR0 || $1 > ADDR7)
                  if ($1 < ADDR0 || $1 > ADDR7)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = AINDR;
                  op->mode = AINDR;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | optzapc '@' '+'
        | optzapc '@' '+'
                {
                {
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  if ($1 < ADDR0 || $1 > ADDR7)
                  if ($1 < ADDR0 || $1 > ADDR7)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = AINC;
                  op->mode = AINC;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | optzapc '@' '-'
        | optzapc '@' '-'
                {
                {
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  /* We use optzapc to avoid a shift/reduce conflict.  */
                  if ($1 < ADDR0 || $1 > ADDR7)
                  if ($1 < ADDR0 || $1 > ADDR7)
                    yyerror (_("syntax error"));
                    yyerror (_("syntax error"));
                  op->mode = ADEC;
                  op->mode = ADEC;
                  op->reg = $1;
                  op->reg = $1;
                }
                }
        | optzapc '@' '(' EXPR ')'
        | optzapc '@' '(' EXPR ')'
                {
                {
                  op->reg = $1;
                  op->reg = $1;
                  op->disp = $4;
                  op->disp = $4;
                  if (($1 >= ZADDR0 && $1 <= ZADDR7)
                  if (($1 >= ZADDR0 && $1 <= ZADDR7)
                      || $1 == ZPC)
                      || $1 == ZPC)
                    op->mode = BASE;
                    op->mode = BASE;
                  else
                  else
                    op->mode = DISP;
                    op->mode = DISP;
                }
                }
        | optzapc '@' '(' optexprc zireg ')'
        | optzapc '@' '(' optexprc zireg ')'
                {
                {
                  op->mode = BASE;
                  op->mode = BASE;
                  op->reg = $1;
                  op->reg = $1;
                  op->disp = $4;
                  op->disp = $4;
                  op->index = $5;
                  op->index = $5;
                }
                }
        | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
        | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $1;
                  op->reg = $1;
                  op->disp = $4;
                  op->disp = $4;
                  op->index = $9;
                  op->index = $9;
                  op->odisp = $8;
                  op->odisp = $8;
                }
                }
        | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
        | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
                {
                {
                  op->mode = POST;
                  op->mode = POST;
                  op->reg = $1;
                  op->reg = $1;
                  op->disp = $4;
                  op->disp = $4;
                  op->odisp = $8;
                  op->odisp = $8;
                }
                }
        | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
        | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
                {
                {
                  op->mode = PRE;
                  op->mode = PRE;
                  op->reg = $1;
                  op->reg = $1;
                  op->disp = $4;
                  op->disp = $4;
                  op->index = $5;
                  op->index = $5;
                  op->odisp = $9;
                  op->odisp = $9;
                }
                }
        ;
        ;
/* An index register, possibly suppressed, which need not have a size
/* An index register, possibly suppressed, which need not have a size
   or scale.  */
   or scale.  */
zireg:
zireg:
          INDEXREG
          INDEXREG
        | zadr
        | zadr
                {
                {
                  $$.reg = $1;
                  $$.reg = $1;
                  $$.size = SIZE_UNSPEC;
                  $$.size = SIZE_UNSPEC;
                  $$.scale = 1;
                  $$.scale = 1;
                }
                }
        ;
        ;
/* A register which may be an index register, but which may not be an
/* A register which may be an index register, but which may not be an
   address register.  This nonterminal is used to avoid ambiguity when
   address register.  This nonterminal is used to avoid ambiguity when
   trying to parse something like (0,d5,a6) as compared to (0,a6,d5).  */
   trying to parse something like (0,d5,a6) as compared to (0,a6,d5).  */
zdireg:
zdireg:
          INDEXREG
          INDEXREG
        | zdr
        | zdr
                {
                {
                  $$.reg = $1;
                  $$.reg = $1;
                  $$.size = SIZE_UNSPEC;
                  $$.size = SIZE_UNSPEC;
                  $$.scale = 1;
                  $$.scale = 1;
                }
                }
        ;
        ;
/* An address or data register, or a suppressed address or data
/* An address or data register, or a suppressed address or data
   register.  */
   register.  */
zadr:
zadr:
          zdr
          zdr
        | AR
        | AR
        | ZAR
        | ZAR
        ;
        ;
/* A data register which may be suppressed.  */
/* A data register which may be suppressed.  */
zdr:
zdr:
          DR
          DR
        | ZDR
        | ZDR
        ;
        ;
/* Either an address register or the PC.  */
/* Either an address register or the PC.  */
apc:
apc:
          AR
          AR
        | LPC
        | LPC
        ;
        ;
/* Either an address register, or the PC, or a suppressed address
/* Either an address register, or the PC, or a suppressed address
   register, or a suppressed PC.  */
   register, or a suppressed PC.  */
zapc:
zapc:
          apc
          apc
        | LZPC
        | LZPC
        | ZAR
        | ZAR
        ;
        ;
/* An optional zapc.  */
/* An optional zapc.  */
optzapc:
optzapc:
          /* empty */
          /* empty */
                {
                {
                  $$ = ZADDR0;
                  $$ = ZADDR0;
                }
                }
        | zapc
        | zapc
        ;
        ;
/* The PC, optionally suppressed.  */
/* The PC, optionally suppressed.  */
zpc:
zpc:
          LPC
          LPC
        | LZPC
        | LZPC
        ;
        ;
/* ',' zapc when it may be omitted.  */
/* ',' zapc when it may be omitted.  */
optczapc:
optczapc:
          /* empty */
          /* empty */
                {
                {
                  $$ = ZADDR0;
                  $$ = ZADDR0;
                }
                }
        | ',' zapc
        | ',' zapc
                {
                {
                  $$ = $2;
                  $$ = $2;
                }
                }
        ;
        ;
/* ',' EXPR when it may be omitted.  */
/* ',' EXPR when it may be omitted.  */
optcexpr:
optcexpr:
          /* empty */
          /* empty */
                {
                {
                  $$.exp.X_op = O_absent;
                  $$.exp.X_op = O_absent;
                  $$.size = SIZE_UNSPEC;
                  $$.size = SIZE_UNSPEC;
                }
                }
        | ',' EXPR
        | ',' EXPR
                {
                {
                  $$ = $2;
                  $$ = $2;
                }
                }
        ;
        ;
/* EXPR ',' when it may be omitted.  */
/* EXPR ',' when it may be omitted.  */
optexprc:
optexprc:
          /* empty */
          /* empty */
                {
                {
                  $$.exp.X_op = O_absent;
                  $$.exp.X_op = O_absent;
                  $$.size = SIZE_UNSPEC;
                  $$.size = SIZE_UNSPEC;
                }
                }
        | EXPR ','
        | EXPR ','
                {
                {
                  $$ = $1;
                  $$ = $1;
                }
                }
        ;
        ;
/* A register list for the movem instruction.  */
/* A register list for the movem instruction.  */
reglist:
reglist:
          reglistpair
          reglistpair
        | reglistpair '/' ireglist
        | reglistpair '/' ireglist
                {
                {
                  $$ = $1 | $3;
                  $$ = $1 | $3;
                }
                }
        | reglistreg '/' ireglist
        | reglistreg '/' ireglist
                {
                {
                  $$ = (1 << $1) | $3;
                  $$ = (1 << $1) | $3;
                }
                }
        ;
        ;
/* We use ireglist when we know we are looking at a reglist, and we
/* We use ireglist when we know we are looking at a reglist, and we
   can safely reduce a simple register to reglistreg.  If we permitted
   can safely reduce a simple register to reglistreg.  If we permitted
   reglist to reduce to reglistreg, it would be ambiguous whether a
   reglist to reduce to reglistreg, it would be ambiguous whether a
   plain register were a DREG/AREG/FPREG or a REGLST.  */
   plain register were a DREG/AREG/FPREG or a REGLST.  */
ireglist:
ireglist:
          reglistreg
          reglistreg
                {
                {
                  $$ = 1 << $1;
                  $$ = 1 << $1;
                }
                }
        | reglistpair
        | reglistpair
        | reglistpair '/' ireglist
        | reglistpair '/' ireglist
                {
                {
                  $$ = $1 | $3;
                  $$ = $1 | $3;
                }
                }
        | reglistreg '/' ireglist
        | reglistreg '/' ireglist
                {
                {
                  $$ = (1 << $1) | $3;
                  $$ = (1 << $1) | $3;
                }
                }
        ;
        ;
reglistpair:
reglistpair:
          reglistreg '-' reglistreg
          reglistreg '-' reglistreg
                {
                {
                  if ($1 <= $3)
                  if ($1 <= $3)
                    $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
                    $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
                  else
                  else
                    $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
                    $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
                }
                }
        ;
        ;
reglistreg:
reglistreg:
          DR
          DR
                {
                {
                  $$ = $1 - DATA0;
                  $$ = $1 - DATA0;
                }
                }
        | AR
        | AR
                {
                {
                  $$ = $1 - ADDR0 + 8;
                  $$ = $1 - ADDR0 + 8;
                }
                }
        | FPR
        | FPR
                {
                {
                  $$ = $1 - FP0 + 16;
                  $$ = $1 - FP0 + 16;
                }
                }
        | FPCR
        | FPCR
                {
                {
                  if ($1 == FPI)
                  if ($1 == FPI)
                    $$ = 24;
                    $$ = 24;
                  else if ($1 == FPS)
                  else if ($1 == FPS)
                    $$ = 25;
                    $$ = 25;
                  else
                  else
                    $$ = 26;
                    $$ = 26;
                }
                }
        ;
        ;
%%
%%
/* The string to parse is stored here, and modified by yylex.  */
/* The string to parse is stored here, and modified by yylex.  */
static char *str;
static char *str;
/* The original string pointer.  */
/* The original string pointer.  */
static char *strorig;
static char *strorig;
/* If *CCP could be a register, return the register number and advance
/* If *CCP could be a register, return the register number and advance
   *CCP.  Otherwise don't change *CCP, and return 0.  */
   *CCP.  Otherwise don't change *CCP, and return 0.  */
static enum m68k_register
static enum m68k_register
m68k_reg_parse (ccp)
m68k_reg_parse (ccp)
     register char **ccp;
     register char **ccp;
{
{
  char *start = *ccp;
  char *start = *ccp;
  char c;
  char c;
  char *p;
  char *p;
  symbolS *symbolp;
  symbolS *symbolp;
  if (flag_reg_prefix_optional)
  if (flag_reg_prefix_optional)
    {
    {
      if (*start == REGISTER_PREFIX)
      if (*start == REGISTER_PREFIX)
        start++;
        start++;
      p = start;
      p = start;
    }
    }
  else
  else
    {
    {
      if (*start != REGISTER_PREFIX)
      if (*start != REGISTER_PREFIX)
        return 0;
        return 0;
      p = start + 1;
      p = start + 1;
    }
    }
  if (! is_name_beginner (*p))
  if (! is_name_beginner (*p))
    return 0;
    return 0;
  p++;
  p++;
  while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
  while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
    p++;
    p++;
  c = *p;
  c = *p;
  *p = 0;
  *p = 0;
  symbolp = symbol_find (start);
  symbolp = symbol_find (start);
  *p = c;
  *p = c;
  if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
  if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
    {
    {
      *ccp = p;
      *ccp = p;
      return S_GET_VALUE (symbolp);
      return S_GET_VALUE (symbolp);
    }
    }
  /* In MRI mode, something like foo.bar can be equated to a register
  /* In MRI mode, something like foo.bar can be equated to a register
     name.  */
     name.  */
  while (flag_mri && c == '.')
  while (flag_mri && c == '.')
    {
    {
      ++p;
      ++p;
      while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
      while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
        p++;
        p++;
      c = *p;
      c = *p;
      *p = '\0';
      *p = '\0';
      symbolp = symbol_find (start);
      symbolp = symbol_find (start);
      *p = c;
      *p = c;
      if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
      if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
        {
        {
          *ccp = p;
          *ccp = p;
          return S_GET_VALUE (symbolp);
          return S_GET_VALUE (symbolp);
        }
        }
    }
    }
  return 0;
  return 0;
}
}
/* The lexer.  */
/* The lexer.  */
static int
static int
yylex ()
yylex ()
{
{
  enum m68k_register reg;
  enum m68k_register reg;
  char *s;
  char *s;
  int parens;
  int parens;
  int c = 0;
  int c = 0;
  int tail = 0;
  int tail = 0;
  char *hold;
  char *hold;
  if (*str == ' ')
  if (*str == ' ')
    ++str;
    ++str;
  if (*str == '\0')
  if (*str == '\0')
    return 0;
    return 0;
  /* Various special characters are just returned directly.  */
  /* Various special characters are just returned directly.  */
  switch (*str)
  switch (*str)
    {
    {
    case '@':
    case '@':
      /* In MRI mode, this can be the start of an octal number.  */
      /* In MRI mode, this can be the start of an octal number.  */
      if (flag_mri)
      if (flag_mri)
        {
        {
          if (ISDIGIT (str[1])
          if (ISDIGIT (str[1])
              || ((str[1] == '+' || str[1] == '-')
              || ((str[1] == '+' || str[1] == '-')
                  && ISDIGIT (str[2])))
                  && ISDIGIT (str[2])))
            break;
            break;
        }
        }
      /* Fall through.  */
      /* Fall through.  */
    case '#':
    case '#':
    case '&':
    case '&':
    case ',':
    case ',':
    case ')':
    case ')':
    case '/':
    case '/':
    case '[':
    case '[':
    case ']':
    case ']':
    case '<':
    case '<':
    case '>':
    case '>':
      return *str++;
      return *str++;
    case '+':
    case '+':
      /* It so happens that a '+' can only appear at the end of an
      /* It so happens that a '+' can only appear at the end of an
         operand, or if it is trailed by an '&'(see mac load insn).
         operand, or if it is trailed by an '&'(see mac load insn).
         If it appears anywhere else, it must be a unary.  */
         If it appears anywhere else, it must be a unary.  */
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
        return *str++;
        return *str++;
      break;
      break;
    case '-':
    case '-':
      /* A '-' can only appear in -(ar), rn-rn, or ar@-.  If it
      /* A '-' can only appear in -(ar), rn-rn, or ar@-.  If it
         appears anywhere else, it must be a unary minus on an
         appears anywhere else, it must be a unary minus on an
         expression, unless it it trailed by a '&'(see mac load insn).  */
         expression, unless it it trailed by a '&'(see mac load insn).  */
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
        return *str++;
        return *str++;
      s = str + 1;
      s = str + 1;
      if (*s == '(')
      if (*s == '(')
        ++s;
        ++s;
      if (m68k_reg_parse (&s) != 0)
      if (m68k_reg_parse (&s) != 0)
        return *str++;
        return *str++;
      break;
      break;
    case '(':
    case '(':
      /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
      /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
         `)('.  If it appears anywhere else, it must be starting an
         `)('.  If it appears anywhere else, it must be starting an
         expression.  */
         expression.  */
      if (str[1] == '['
      if (str[1] == '['
          || (str > strorig
          || (str > strorig
              && (str[-1] == '@'
              && (str[-1] == '@'
                  || str[-1] == ')')))
                  || str[-1] == ')')))
        return *str++;
        return *str++;
      s = str + 1;
      s = str + 1;
      if (m68k_reg_parse (&s) != 0)
      if (m68k_reg_parse (&s) != 0)
        return *str++;
        return *str++;
      /* Check for the case of '(expr,...' by scanning ahead.  If we
      /* Check for the case of '(expr,...' by scanning ahead.  If we
         find a comma outside of balanced parentheses, we return '('.
         find a comma outside of balanced parentheses, we return '('.
         If we find an unbalanced right parenthesis, then presumably
         If we find an unbalanced right parenthesis, then presumably
         the '(' really starts an expression.  */
         the '(' really starts an expression.  */
      parens = 0;
      parens = 0;
      for (s = str + 1; *s != '\0'; s++)
      for (s = str + 1; *s != '\0'; s++)
        {
        {
          if (*s == '(')
          if (*s == '(')
            ++parens;
            ++parens;
          else if (*s == ')')
          else if (*s == ')')
            {
            {
              if (parens == 0)
              if (parens == 0)
                break;
                break;
              --parens;
              --parens;
            }
            }
          else if (*s == ',' && parens == 0)
          else if (*s == ',' && parens == 0)
            {
            {
              /* A comma can not normally appear in an expression, so
              /* A comma can not normally appear in an expression, so
                 this is a case of '(expr,...'.  */
                 this is a case of '(expr,...'.  */
              return *str++;
              return *str++;
            }
            }
        }
        }
    }
    }
  /* See if it's a register.  */
  /* See if it's a register.  */
  reg = m68k_reg_parse (&str);
  reg = m68k_reg_parse (&str);
  if (reg != 0)
  if (reg != 0)
    {
    {
      int ret;
      int ret;
      yylval.reg = reg;
      yylval.reg = reg;
      if (reg >= DATA0 && reg <= DATA7)
      if (reg >= DATA0 && reg <= DATA7)
        ret = DR;
        ret = DR;
      else if (reg >= ADDR0 && reg <= ADDR7)
      else if (reg >= ADDR0 && reg <= ADDR7)
        ret = AR;
        ret = AR;
      else if (reg >= FP0 && reg <= FP7)
      else if (reg >= FP0 && reg <= FP7)
        return FPR;
        return FPR;
      else if (reg == FPI
      else if (reg == FPI
               || reg == FPS
               || reg == FPS
               || reg == FPC)
               || reg == FPC)
        return FPCR;
        return FPCR;
      else if (reg == PC)
      else if (reg == PC)
        return LPC;
        return LPC;
      else if (reg >= ZDATA0 && reg <= ZDATA7)
      else if (reg >= ZDATA0 && reg <= ZDATA7)
        ret = ZDR;
        ret = ZDR;
      else if (reg >= ZADDR0 && reg <= ZADDR7)
      else if (reg >= ZADDR0 && reg <= ZADDR7)
        ret = ZAR;
        ret = ZAR;
      else if (reg == ZPC)
      else if (reg == ZPC)
        return LZPC;
        return LZPC;
      else
      else
        return CREG;
        return CREG;
      /* If we get here, we have a data or address register.  We
      /* If we get here, we have a data or address register.  We
         must check for a size or scale; if we find one, we must
         must check for a size or scale; if we find one, we must
         return INDEXREG.  */
         return INDEXREG.  */
      s = str;
      s = str;
      if (*s != '.' && *s != ':' && *s != '*')
      if (*s != '.' && *s != ':' && *s != '*')
        return ret;
        return ret;
      yylval.indexreg.reg = reg;
      yylval.indexreg.reg = reg;
      if (*s != '.' && *s != ':')
      if (*s != '.' && *s != ':')
        yylval.indexreg.size = SIZE_UNSPEC;
        yylval.indexreg.size = SIZE_UNSPEC;
      else
      else
        {
        {
          ++s;
          ++s;
          switch (*s)
          switch (*s)
            {
            {
            case 'w':
            case 'w':
            case 'W':
            case 'W':
              yylval.indexreg.size = SIZE_WORD;
              yylval.indexreg.size = SIZE_WORD;
              ++s;
              ++s;
              break;
              break;
            case 'l':
            case 'l':
            case 'L':
            case 'L':
              yylval.indexreg.size = SIZE_LONG;
              yylval.indexreg.size = SIZE_LONG;
              ++s;
              ++s;
              break;
              break;
            default:
            default:
              yyerror (_("illegal size specification"));
              yyerror (_("illegal size specification"));
              yylval.indexreg.size = SIZE_UNSPEC;
              yylval.indexreg.size = SIZE_UNSPEC;
              break;
              break;
            }
            }
        }
        }
      yylval.indexreg.scale = 1;
      yylval.indexreg.scale = 1;
      if (*s == '*' || *s == ':')
      if (*s == '*' || *s == ':')
        {
        {
          expressionS scale;
          expressionS scale;
          ++s;
          ++s;
          hold = input_line_pointer;
          hold = input_line_pointer;
          input_line_pointer = s;
          input_line_pointer = s;
          expression (&scale);
          expression (&scale);
          s = input_line_pointer;
          s = input_line_pointer;
          input_line_pointer = hold;
          input_line_pointer = hold;
          if (scale.X_op != O_constant)
          if (scale.X_op != O_constant)
            yyerror (_("scale specification must resolve to a number"));
            yyerror (_("scale specification must resolve to a number"));
          else
          else
            {
            {
              switch (scale.X_add_number)
              switch (scale.X_add_number)
                {
                {
                case 1:
                case 1:
                case 2:
                case 2:
                case 4:
                case 4:
                case 8:
                case 8:
                  yylval.indexreg.scale = scale.X_add_number;
                  yylval.indexreg.scale = scale.X_add_number;
                  break;
                  break;
                default:
                default:
                  yyerror (_("invalid scale value"));
                  yyerror (_("invalid scale value"));
                  break;
                  break;
                }
                }
            }
            }
        }
        }
      str = s;
      str = s;
      return INDEXREG;
      return INDEXREG;
    }
    }
  /* It must be an expression.  Before we call expression, we need to
  /* It must be an expression.  Before we call expression, we need to
     look ahead to see if there is a size specification.  We must do
     look ahead to see if there is a size specification.  We must do
     that first, because otherwise foo.l will be treated as the symbol
     that first, because otherwise foo.l will be treated as the symbol
     foo.l, rather than as the symbol foo with a long size
     foo.l, rather than as the symbol foo with a long size
     specification.  The grammar requires that all expressions end at
     specification.  The grammar requires that all expressions end at
     the end of the operand, or with ',', '(', ']', ')'.  */
     the end of the operand, or with ',', '(', ']', ')'.  */
  parens = 0;
  parens = 0;
  for (s = str; *s != '\0'; s++)
  for (s = str; *s != '\0'; s++)
    {
    {
      if (*s == '(')
      if (*s == '(')
        {
        {
          if (parens == 0
          if (parens == 0
              && s > str
              && s > str
              && (s[-1] == ')' || ISALNUM (s[-1])))
              && (s[-1] == ')' || ISALNUM (s[-1])))
            break;
            break;
          ++parens;
          ++parens;
        }
        }
      else if (*s == ')')
      else if (*s == ')')
        {
        {
          if (parens == 0)
          if (parens == 0)
            break;
            break;
          --parens;
          --parens;
        }
        }
      else if (parens == 0
      else if (parens == 0
               && (*s == ',' || *s == ']'))
               && (*s == ',' || *s == ']'))
        break;
        break;
    }
    }
  yylval.exp.size = SIZE_UNSPEC;
  yylval.exp.size = SIZE_UNSPEC;
  if (s <= str + 2
  if (s <= str + 2
      || (s[-2] != '.' && s[-2] != ':'))
      || (s[-2] != '.' && s[-2] != ':'))
    tail = 0;
    tail = 0;
  else
  else
    {
    {
      switch (s[-1])
      switch (s[-1])
        {
        {
        case 's':
        case 's':
        case 'S':
        case 'S':
        case 'b':
        case 'b':
        case 'B':
        case 'B':
          yylval.exp.size = SIZE_BYTE;
          yylval.exp.size = SIZE_BYTE;
          break;
          break;
        case 'w':
        case 'w':
        case 'W':
        case 'W':
          yylval.exp.size = SIZE_WORD;
          yylval.exp.size = SIZE_WORD;
          break;
          break;
        case 'l':
        case 'l':
        case 'L':
        case 'L':
          yylval.exp.size = SIZE_LONG;
          yylval.exp.size = SIZE_LONG;
          break;
          break;
        default:
        default:
          break;
          break;
        }
        }
      if (yylval.exp.size != SIZE_UNSPEC)
      if (yylval.exp.size != SIZE_UNSPEC)
        tail = 2;
        tail = 2;
    }
    }
#ifdef OBJ_ELF
#ifdef OBJ_ELF
  {
  {
    /* Look for @PLTPC, etc.  */
    /* Look for @PLTPC, etc.  */
    char *cp;
    char *cp;
    yylval.exp.pic_reloc = pic_none;
    yylval.exp.pic_reloc = pic_none;
    cp = s - tail;
    cp = s - tail;
    if (cp - 6 > str && cp[-6] == '@')
    if (cp - 6 > str && cp[-6] == '@')
      {
      {
        if (strncmp (cp - 6, "@PLTPC", 6) == 0)
        if (strncmp (cp - 6, "@PLTPC", 6) == 0)
          {
          {
            yylval.exp.pic_reloc = pic_plt_pcrel;
            yylval.exp.pic_reloc = pic_plt_pcrel;
            tail += 6;
            tail += 6;
          }
          }
        else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
        else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
          {
          {
            yylval.exp.pic_reloc = pic_got_pcrel;
            yylval.exp.pic_reloc = pic_got_pcrel;
            tail += 6;
            tail += 6;
          }
          }
      }
      }
    else if (cp - 4 > str && cp[-4] == '@')
    else if (cp - 4 > str && cp[-4] == '@')
      {
      {
        if (strncmp (cp - 4, "@PLT", 4) == 0)
        if (strncmp (cp - 4, "@PLT", 4) == 0)
          {
          {
            yylval.exp.pic_reloc = pic_plt_off;
            yylval.exp.pic_reloc = pic_plt_off;
            tail += 4;
            tail += 4;
          }
          }
        else if (strncmp (cp - 4, "@GOT", 4) == 0)
        else if (strncmp (cp - 4, "@GOT", 4) == 0)
          {
          {
            yylval.exp.pic_reloc = pic_got_off;
            yylval.exp.pic_reloc = pic_got_off;
            tail += 4;
            tail += 4;
          }
          }
      }
      }
  }
  }
#endif
#endif
  if (tail != 0)
  if (tail != 0)
    {
    {
      c = s[-tail];
      c = s[-tail];
      s[-tail] = 0;
      s[-tail] = 0;
    }
    }
  hold = input_line_pointer;
  hold = input_line_pointer;
  input_line_pointer = str;
  input_line_pointer = str;
  expression (&yylval.exp.exp);
  expression (&yylval.exp.exp);
  str = input_line_pointer;
  str = input_line_pointer;
  input_line_pointer = hold;
  input_line_pointer = hold;
  if (tail != 0)
  if (tail != 0)
    {
    {
      s[-tail] = c;
      s[-tail] = c;
      str = s;
      str = s;
    }
    }
  return EXPR;
  return EXPR;
}
}
/* Parse an m68k operand.  This is the only function which is called
/* Parse an m68k operand.  This is the only function which is called
   from outside this file.  */
   from outside this file.  */
int
int
m68k_ip_op (s, oparg)
m68k_ip_op (s, oparg)
     char *s;
     char *s;
     struct m68k_op *oparg;
     struct m68k_op *oparg;
{
{
  memset (oparg, 0, sizeof *oparg);
  memset (oparg, 0, sizeof *oparg);
  oparg->error = NULL;
  oparg->error = NULL;
  oparg->index.reg = ZDATA0;
  oparg->index.reg = ZDATA0;
  oparg->index.scale = 1;
  oparg->index.scale = 1;
  oparg->disp.exp.X_op = O_absent;
  oparg->disp.exp.X_op = O_absent;
  oparg->odisp.exp.X_op = O_absent;
  oparg->odisp.exp.X_op = O_absent;
  str = strorig = s;
  str = strorig = s;
  op = oparg;
  op = oparg;
  return yyparse ();
  return yyparse ();
}
}
/* The error handler.  */
/* The error handler.  */
static void
static void
yyerror (s)
yyerror (s)
     const char *s;
     const char *s;
{
{
  op->error = s;
  op->error = s;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.