Remove all Bison supporting struts as we no longer need Bison.
svn path=/trunk/yasm/; revision=1724
EXTRA_DIST += Mkfiles/vc/re2c/run.bat
EXTRA_DIST += Mkfiles/vc/gap/gap.vcproj
EXTRA_DIST += Mkfiles/vc/gap/run.bat
-EXTRA_DIST += Mkfiles/vc8/bison.rules
EXTRA_DIST += Mkfiles/vc8/crt_secure_no_deprecate.vsprops
EXTRA_DIST += Mkfiles/vc8/yasm.sln
EXTRA_DIST += Mkfiles/vc8/yasm.vcproj
modules/parsers/nasm/nasm-parse.o \
nasm-token.o \
modules/parsers/gas/gas-parser.o \
- gas-bison.o \
+ modules/parsers/gas/gas-parse.o \
gas-token.o
YASM_MODULES+=parser_nasm
YASM_MODULES+=parser_gas
modules/parsers/nasm/nasm-parse.o \
nasm-token.o \
modules/parsers/gas/gas-parser.o \
- gas-bison.o \
+ modules/parsers/gas/gas-parse.o \
gas-token.o
YASM_MODULES+=parser_nasm
YASM_MODULES+=parser_gas
Name="parsers"\r
Filter="">\r
<File\r
- RelativePath="..\..\..\gas-bison.c">\r
- </File>\r
- <File\r
- RelativePath="..\..\..\gas-bison.h">\r
- </File>\r
- <File\r
- RelativePath="..\..\..\modules\parsers\gas\gas-defs.h">\r
+ RelativePath="..\..\..\modules\parsers\gas\gas-parse.c">\r
</File>\r
<File\r
RelativePath="..\..\..\modules\parsers\gas\gas-parser.c">\r
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<VisualStudioToolFile\r
- Name="Bison"\r
- Version="8.00"\r
- >\r
- <Rules>\r
- <CustomBuildRule\r
- Name="Bison"\r
- DisplayName="Compiler compiler - bison"\r
- CommandLine="bison [AllOptions] [AdditionalOptions] [inputs]"\r
- Outputs="[$OutputStem].c;[$OutputStem].h"\r
- FileExtensions="*.y"\r
- ExecutionDescription="Executing bison..."\r
- ShowOnlyRuleProperties="false"\r
- >\r
- <Properties>\r
- <BooleanProperty\r
- Name="OutputDefs"\r
- DisplayName="Genereate extra .h file with parser defines"\r
- Switch="-d"\r
- DefaultValue="true"\r
- />\r
- <StringProperty\r
- Name="OutputStem"\r
- DisplayName="Output Stem"\r
- Switch="-o "[value].c""\r
- DefaultValue="$(InputDir)$(InputName)"\r
- />\r
- </Properties>\r
- </CustomBuildRule>\r
- </Rules>\r
-</VisualStudioToolFile>\r
/>\r
</Platforms>\r
<ToolFiles>\r
- <ToolFile\r
- RelativePath="..\bison.rules"\r
- />\r
</ToolFiles>\r
<Configurations>\r
<Configuration\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
Name="parsers"\r
>\r
<File\r
- RelativePath="..\..\..\gas-bison.c"\r
- >\r
- </File>\r
- <File\r
- RelativePath="..\..\..\gas-bison.h"\r
- >\r
- </File>\r
- <File\r
- RelativePath="..\..\..\modules\parsers\gas\gas-bison.y"\r
- >\r
- <FileConfiguration\r
- Name="Release|Win32"\r
- ExcludedFromBuild="true"\r
- >\r
- <Tool\r
- Name="Bison"\r
- OutputStem="../../../gas-bison"\r
- />\r
- </FileConfiguration>\r
- <FileConfiguration\r
- Name="Release|x64"\r
- ExcludedFromBuild="true"\r
- >\r
- <Tool\r
- Name="Bison"\r
- />\r
- </FileConfiguration>\r
- <FileConfiguration\r
- Name="Debug|Win32"\r
- ExcludedFromBuild="true"\r
- >\r
- <Tool\r
- Name="Bison"\r
- OutputStem="../../../gas-bison"\r
- />\r
- </FileConfiguration>\r
- <FileConfiguration\r
- Name="Debug|x64"\r
- ExcludedFromBuild="true"\r
- >\r
- <Tool\r
- Name="Bison"\r
- />\r
- </FileConfiguration>\r
- </File>\r
- <File\r
- RelativePath="..\..\..\modules\parsers\gas\gas-defs.h"\r
+ RelativePath="..\..\..\modules\parsers\gas\gas-parse.c"\r
>\r
</File>\r
<File\r
/>\r
</Platforms>\r
<ToolFiles>\r
- <ToolFile\r
- RelativePath="..\bison.rules"\r
- />\r
</ToolFiles>\r
<Configurations>\r
<Configuration\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
<Tool\r
Name="VCCustomBuildTool"\r
/>\r
- <Tool\r
- Name="Bison"\r
- />\r
<Tool\r
Name="VCXMLDataGeneratorTool"\r
/>\r
2. YASM Download\r
----------------\r
\r
-The following files are not built by default on VC++ and are not contained\r
-in the YASM subversion repository (but they are included in the nightly\r
-YASM snapshots):\r
-\r
- gas-bison.c\r
- gas-bison.h\r
-\r
-However, if you want to build these files from source, follow these step:\r
- 1) Install bison. This can be done in a number of ways, the easiest is\r
- probably to download and run the Win32 Bison Setup program from\r
- http://gnuwin32.sourceforge.net/packages/bison.htm\r
- 2) In Visual Studio, go to Tools|Options,\r
- Projects and Solutions|VC++ Directories, and add the directory where\r
- you installed Bison to the list of directories.\r
- 3) For each of the .y files in the build, right click, select Properties,\r
- and change the "Excluded From Build" setting to No. These files are:\r
- modules/Source Files/gas-bison.y\r
-\r
-If you wish to build from the latest files in the subversion repository,\r
-you will need to add these files from the latest snapshot to the repository\r
-files. They should be placed in the YASM root directory.\r
-\r
-3. Building YASM with Microsoft VC8\r
------------------------------------\r
-\r
First YASM needs to be downloaded and the files placed within a suitable\r
directory, which will be called <yasm> here but can be named and located\r
-as you wish. If the Visual Studio 2005 project files have been obtained\r
-seperately the subdirectory 'vc8' and its subdirectories and files need to\r
-be placed in the 'Mkfiles' subdirectory within the YASM root directory.\r
+as you wish.\r
\r
-If building from the subversion repository, obtain the additional files\r
-discussed above and place them in the YASM root directory.\r
+3. Building YASM with Microsoft VC8\r
+-----------------------------------\r
\r
Now locate and double click on the yasm.sln solution file in the 'Mkfiles/vc8'\r
subdirectory to open the build project in the Visual Studio 2005 IDE and then\r
+++ /dev/null
-#! /bin/sh
-# ylwrap - wrapper for lex/yacc invocations.
-# Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
-# Written by Tom Tromey <tromey@cygnus.com>.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Usage:
-# ylwrap INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
-# * INPUT is the input file
-# * OUTPUT is file PROG generates
-# * DESIRED is file we actually want
-# * PROGRAM is program to run
-# * ARGS are passed to PROG
-# Any number of OUTPUT,DESIRED pairs may be used.
-
-# The input.
-input="$1"
-shift
-case "$input" in
- [\\/]* | ?:[\\/]*)
- # Absolute path; do nothing.
- ;;
- *)
- # Relative path. Make it absolute.
- input="`pwd`/$input"
- ;;
-esac
-
-# The directory holding the input.
-input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
-# Quote $INPUT_DIR so we can use it in a regexp.
-# FIXME: really we should care about more than `.' and `\'.
-input_rx=`echo "$input_dir" | sed -e 's,\\\\,\\\\\\\\,g' -e 's,\\.,\\\\.,g'`
-
-echo "got $input_rx"
-
-pairlist=
-while test "$#" -ne 0; do
- if test "$1" = "--"; then
- shift
- break
- fi
- pairlist="$pairlist $1"
- shift
-done
-
-# The program to run.
-prog="$1"
-shift
-# Make any relative path in $prog absolute.
-case "$prog" in
- [\\/]* | ?:[\\/]*) ;;
- *[\\/]*) prog="`pwd`/$prog" ;;
-esac
-
-# FIXME: add hostname here for parallel makes that run commands on
-# other machines. But that might take us over the 14-char limit.
-dirname=ylwrap$$
-trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
-mkdir $dirname || exit 1
-
-cd $dirname
-
-$prog ${1+"$@"} "$input"
-status=$?
-
-if test $status -eq 0; then
- set X $pairlist
- shift
- first=yes
- # Since DOS filename conventions don't allow two dots,
- # the DOS version of Bison writes out y_tab.c instead of y.tab.c
- # and y_tab.h instead of y.tab.h. Test to see if this is the case.
- y_tab_nodot="no"
- if test -f y_tab.c || test -f y_tab.h; then
- y_tab_nodot="yes"
- fi
-
- while test "$#" -ne 0; do
- from="$1"
- # Handle y_tab.c and y_tab.h output by DOS
- if test $y_tab_nodot = "yes"; then
- if test $from = "y.tab.c"; then
- from="y_tab.c"
- else
- if test $from = "y.tab.h"; then
- from="y_tab.h"
- fi
- fi
- fi
- if test -f "$from"; then
- # If $2 is an absolute path name, then just use that,
- # otherwise prepend `../'.
- case "$2" in
- [\\/]* | ?:[\\/]*) target="$2";;
- *) target="../$2";;
- esac
- from_rx=`echo "$from" | sed -e 's,\\\\,\\\\\\\\,g' -e 's,\\.,\\\\.,g'`
-
- # Edit out `#line' or `#' directives. We don't want the
- # resulting debug information to point at an absolute srcdir;
- # it is better for it to just mention the .y file with no
- # path.
- sed -e "/^#/ s,$input_rx,," -e "/^#/ s,$from_rx,$2," "$from" > "$target" || status=$?
- else
- # A missing file is only an error for the first file. This
- # is a blatant hack to let us support using "yacc -d". If -d
- # is not specified, we don't want an error when the header
- # file is "missing".
- if test $first = yes; then
- status=1
- fi
- fi
- shift
- shift
- first=no
- done
-else
- status=$?
-fi
-
-# Remove the directory.
-cd ..
-rm -rf $dirname
-
-exit $status
#
# Checks for programs.
#
-AC_PROG_YACC
-# check for Bison in particular
-if test "$YACC" != "bison -y"; then
- AC_MSG_WARN([You will need GNU Bison if you want to regenerate parsers.])
- YACC=
-else
- AC_MSG_CHECKING([bison version])
- set `bison --version | grep 'GNU Bison' | sed -e 's/^@<:@A-Za-z() @:>@*//g' -e 's/\./ /'`
- if test -z "$1" -o -z "$2"; then
- AC_MSG_RESULT([unknown])
- AC_MSG_WARN([You will need GNU Bison 1.25 or better if you want to regenerate parsers.])
- YACC=
- else
- if test "$1" = "1" -a "$2" -lt "25"; then
- AC_MSG_RESULT([$1.$2])
- AC_MSG_WARN([You will need GNU Bison 1.25 or better if you want to regenerate parsers (found $1.$2).])
- YACC=
- else
- AC_MSG_RESULT([$1.$2 (ok)])
- fi
- fi
-fi
AC_PROG_CC_STDC
AC_PROG_INSTALL
AC_PROG_LN_S
libyasm_a_SOURCES += modules/parsers/gas/gas-parser.c
libyasm_a_SOURCES += modules/parsers/gas/gas-parser.h
-libyasm_a_SOURCES += modules/parsers/gas/gas-defs.h
-libyasm_a_SOURCES += modules/parsers/gas/gas-bison.y
-libyasm_a_SOURCES += gas-bison.h
+libyasm_a_SOURCES += modules/parsers/gas/gas-parse.c
libyasm_a_SOURCES += gas-token.c
YASM_MODULES += parser_gas
gas-token.c: $(srcdir)/modules/parsers/gas/gas-token.re re2c$(EXEEXT)
$(top_builddir)/re2c$(EXEEXT) -b -o $@ $(srcdir)/modules/parsers/gas/gas-token.re
-BUILT_SOURCES += gas-bison.c
-BUILT_SOURCES += gas-bison.h
BUILT_SOURCES += gas-token.c
-CLEANFILES += gas-bison.c
-CLEANFILES += gas-bison.h
CLEANFILES += gas-token.c
EXTRA_DIST += modules/parsers/gas/tests/Makefile.inc
+++ /dev/null
-/*
- * GAS-compatible bison parser
- *
- * Copyright (C) 2005 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of other contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-%{
-#include <util.h>
-RCSID("$Id$");
-
-#define YASM_LIB_INTERNAL
-#define YASM_EXPR_INTERNAL
-#include <libyasm.h>
-
-#ifdef STDC_HEADERS
-# include <math.h>
-#endif
-
-#include "modules/parsers/gas/gas-parser.h"
-#include "modules/parsers/gas/gas-defs.h"
-
-static void define_label(yasm_parser_gas *parser_gas, char *name, int local);
-static void define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
- yasm_expr *size, /*@null@*/ yasm_expr *align);
-static yasm_section *gas_get_section
- (yasm_parser_gas *parser_gas, /*@only@*/ char *name, /*@null@*/ char *flags,
- /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams,
- int builtin);
-static void gas_switch_section
- (yasm_parser_gas *parser_gas, /*@only@*/ char *name, /*@null@*/ char *flags,
- /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams,
- int builtin);
-static yasm_bytecode *gas_parser_align
- (yasm_parser_gas *parser_gas, yasm_section *sect, yasm_expr *boundval,
- /*@null@*/ yasm_expr *fillval, /*@null@*/ yasm_expr *maxskipval,
- int power2);
-static yasm_bytecode *gas_parser_dir_align(yasm_parser_gas *parser_gas,
- yasm_valparamhead *valparams,
- int power2);
-static yasm_bytecode *gas_parser_dir_fill
- (yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat,
- /*@only@*/ /*@null@*/ yasm_expr *size,
- /*@only@*/ /*@null@*/ yasm_expr *value);
-static void gas_parser_directive
- (yasm_parser_gas *parser_gas, const char *name,
- yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams);
-
-#define gas_parser_error(s) \
- yasm_error_set(YASM_ERROR_PARSE, "%s", s)
-#define YYPARSE_PARAM parser_gas_arg
-#define YYLEX_PARAM parser_gas_arg
-#define parser_gas ((yasm_parser_gas *)parser_gas_arg)
-#define gas_parser_debug (parser_gas->debug)
-
-/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
-%}
-
-%pure_parser
-
-%union {
- unsigned int int_info;
- char *str_val;
- yasm_intnum *intn;
- yasm_floatnum *flt;
- yasm_symrec *sym;
- unsigned long arch_data[4];
- yasm_effaddr *ea;
- yasm_expr *exp;
- yasm_bytecode *bc;
- yasm_valparamhead valparams;
- yasm_datavalhead datavals;
- yasm_dataval *dv;
- struct {
- yasm_insn_operands operands;
- int num_operands;
- } insn_operands;
- yasm_insn_operand *insn_operand;
- struct {
- char *contents;
- size_t len;
- } str;
-}
-
-%token <intn> INTNUM
-%token <flt> FLTNUM
-%token <str> STRING
-%token <int_info> SIZE_OVERRIDE
-%token <int_info> DECLARE_DATA
-%token <int_info> RESERVE_SPACE
-%token <arch_data> INSN PREFIX REG REGGROUP SEGREG TARGETMOD
-%token LEFT_OP RIGHT_OP
-%token <str_val> ID DIR_ID LABEL
-%token LINE
-%token DIR_2BYTE DIR_4BYTE DIR_ALIGN DIR_ASCII DIR_ASCIZ DIR_BALIGN
-%token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN
-%token DIR_EQU DIR_FILE DIR_FILL DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT
-%token DIR_LINE DIR_LOC DIR_LOCAL DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN
-%token DIR_REPT DIR_SECTION DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING
-%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_ULEB128 DIR_VALUE DIR_WEAK
-%token DIR_WORD DIR_ZERO
-
-%type <bc> lineexp instr
-
-%type <str_val> expr_id label_id
-%type <ea> memaddr
-%type <exp> expr regmemexpr
-%type <sym> explabel
-%type <valparams> dirvals dirvals2 dirstrvals dirstrvals2
-%type <datavals> strvals datavals strvals2 datavals2
-%type <insn_operands> operands
-%type <insn_operand> operand
-
-%left '-' '+'
-%left '|' '&' '^' '!'
-%left '*' '/' '%' LEFT_OP RIGHT_OP
-%nonassoc UNARYOP
-
-%%
-input: /* empty */
- | input line {
- yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
- if (parser_gas->save_input)
- yasm_linemap_add_source(parser_gas->linemap,
- parser_gas->prev_bc,
- (char *)parser_gas->save_line[parser_gas->save_last ^ 1]);
- yasm_linemap_goto_next(parser_gas->linemap);
- parser_gas->dir_line++; /* keep track for .line followed by .file */
- }
-;
-
-line: '\n'
- | linebcs '\n'
- | error '\n' {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("label or instruction expected at start of line"));
- yyerrok;
- }
-;
-
-linebcs: linebc
- | linebc ';' linebcs
-;
-
-linebc: lineexp {
- parser_gas->temp_bc =
- yasm_section_bcs_append(parser_gas->cur_section, $1);
- if (parser_gas->temp_bc)
- parser_gas->prev_bc = parser_gas->temp_bc;
- }
-;
-
-lineexp: instr
- | label_id ':' {
- $$ = (yasm_bytecode *)NULL;
- define_label(parser_gas, $1, 0);
- }
- | label_id ':' instr {
- $$ = $3;
- define_label(parser_gas, $1, 0);
- }
- | LABEL {
- $$ = (yasm_bytecode *)NULL;
- define_label(parser_gas, $1, 0);
- }
- | LABEL instr {
- $$ = $2;
- define_label(parser_gas, $1, 0);
- }
- /* Line directive */
- | DIR_LINE INTNUM {
- $$ = (yasm_bytecode *)NULL;
- if (yasm_intnum_sign($2) < 0)
- yasm_error_set(YASM_ERROR_SYNTAX, N_("line number is negative"));
- else {
- parser_gas->dir_line = yasm_intnum_get_uint($2);
- yasm_intnum_destroy($2);
-
- if (parser_gas->dir_fileline == 3) {
- /* Have both file and line */
- yasm_linemap_set(parser_gas->linemap, NULL,
- parser_gas->dir_line, 1);
- } else if (parser_gas->dir_fileline == 1) {
- /* Had previous file directive only */
- parser_gas->dir_fileline = 3;
- yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file,
- parser_gas->dir_line, 1);
- } else {
- /* Didn't see file yet */
- parser_gas->dir_fileline = 2;
- }
- }
- }
- /* Macro directives */
- | DIR_REPT expr {
- yasm_intnum *intn = yasm_expr_get_intnum(&$2, 0);
-
- $$ = (yasm_bytecode *)NULL;
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
- N_("rept expression not absolute"));
- } else if (yasm_intnum_sign(intn) < 0) {
- yasm_error_set(YASM_ERROR_VALUE,
- N_("rept expression is negative"));
- } else {
- gas_rept *rept = yasm_xmalloc(sizeof(gas_rept));
- STAILQ_INIT(&rept->lines);
- rept->startline = cur_line;
- rept->numrept = yasm_intnum_get_uint(intn);
- rept->numdone = 0;
- rept->line = NULL;
- rept->linepos = 0;
- rept->ended = 0;
- rept->oldbuf = NULL;
- rept->oldbuflen = 0;
- rept->oldbufpos = 0;
- parser_gas->rept = rept;
- }
- }
- | DIR_ENDR {
- $$ = (yasm_bytecode *)NULL;
- /* Shouldn't ever get here unless we didn't get a DIR_REPT first */
- yasm_error_set(YASM_ERROR_SYNTAX, N_("endr without matching rept"));
- }
- /* Alignment directives */
- | DIR_ALIGN dirvals2 {
- /* FIXME: Whether this is power-of-two or not depends on arch and
- * objfmt.
- */
- $$ = gas_parser_dir_align(parser_gas, &$2, 0);
- }
- | DIR_P2ALIGN dirvals2 {
- $$ = gas_parser_dir_align(parser_gas, &$2, 1);
- }
- | DIR_BALIGN dirvals2 {
- $$ = gas_parser_dir_align(parser_gas, &$2, 0);
- }
- | DIR_ORG INTNUM {
- /* TODO: support expr instead of intnum */
- $$ = yasm_bc_create_org(yasm_intnum_get_uint($2), cur_line);
- }
- /* Data visibility directives */
- | DIR_LOCAL label_id {
- yasm_symtab_declare(parser_gas->symtab, $2, YASM_SYM_DLOCAL, cur_line);
- yasm_xfree($2);
- $$ = NULL;
- }
- | DIR_GLOBAL label_id {
- yasm_objfmt_global_declare(parser_gas->objfmt, $2, NULL, cur_line);
- yasm_xfree($2);
- $$ = NULL;
- }
- | DIR_COMM label_id ',' expr {
- /* If already explicitly declared local, treat like LCOMM */
- /*@null@*/ /*@dependent@*/ yasm_symrec *sym =
- yasm_symtab_get(parser_gas->symtab, $2);
- if (sym && yasm_symrec_get_visibility(sym) == YASM_SYM_DLOCAL) {
- define_lcomm(parser_gas, $2, $4, NULL);
- } else {
- yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, NULL,
- cur_line);
- yasm_xfree($2);
- }
- $$ = NULL;
- }
- | DIR_COMM label_id ',' expr ',' expr {
- /* If already explicitly declared local, treat like LCOMM */
- /*@null@*/ /*@dependent@*/ yasm_symrec *sym =
- yasm_symtab_get(parser_gas->symtab, $2);
- if (sym && yasm_symrec_get_visibility(sym)) {
- define_lcomm(parser_gas, $2, $4, $6);
- } else {
- /* Give third parameter as objext valparam for use as alignment */
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create(NULL, $6);
- yasm_vps_append(&vps, vp);
-
- yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, &vps,
- cur_line);
-
- yasm_vps_delete(&vps);
- yasm_xfree($2);
- }
- $$ = NULL;
- }
- | DIR_EXTERN label_id {
- /* Go ahead and do it, even though all undef become extern */
- yasm_objfmt_extern_declare(parser_gas->objfmt, $2, NULL, cur_line);
- yasm_xfree($2);
- $$ = NULL;
- }
- | DIR_WEAK label_id {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create($2, NULL);
- yasm_vps_append(&vps, vp);
-
- yasm_objfmt_directive(parser_gas->objfmt, "weak", &vps, NULL,
- cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_LCOMM label_id ',' expr {
- define_lcomm(parser_gas, $2, $4, NULL);
- $$ = NULL;
- }
- | DIR_LCOMM label_id ',' expr ',' expr {
- define_lcomm(parser_gas, $2, $4, $6);
- $$ = NULL;
- }
- /* Integer data definition directives */
- | DIR_ASCII strvals {
- $$ = yasm_bc_create_data(&$2, 1, 0, parser_gas->arch, cur_line);
- }
- | DIR_ASCIZ strvals {
- $$ = yasm_bc_create_data(&$2, 1, 1, parser_gas->arch, cur_line);
- }
- | DIR_BYTE datavals {
- $$ = yasm_bc_create_data(&$2, 1, 0, parser_gas->arch, cur_line);
- }
- | DIR_SHORT datavals {
- /* TODO: This should depend on arch */
- $$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
- }
- | DIR_WORD datavals {
- $$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch)/8, 0,
- parser_gas->arch, cur_line);
- }
- | DIR_INT datavals {
- /* TODO: This should depend on arch */
- $$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
- }
- | DIR_VALUE datavals {
- /* XXX: At least on x86, this is two bytes */
- $$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
- }
- | DIR_2BYTE datavals {
- $$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
- }
- | DIR_4BYTE datavals {
- $$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
- }
- | DIR_QUAD datavals {
- $$ = yasm_bc_create_data(&$2, 8, 0, parser_gas->arch, cur_line);
- }
- | DIR_OCTA datavals {
- $$ = yasm_bc_create_data(&$2, 16, 0, parser_gas->arch, cur_line);
- }
- | DIR_ZERO expr {
- yasm_datavalhead dvs;
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_expr(
- p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
- $$ = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
-
- yasm_bc_set_multiple($$, $2);
- }
- | DIR_SLEB128 datavals {
- $$ = yasm_bc_create_leb128(&$2, 1, cur_line);
- }
- | DIR_ULEB128 datavals {
- $$ = yasm_bc_create_leb128(&$2, 0, cur_line);
- }
- /* Floating point data definition directives */
- | DIR_FLOAT datavals {
- $$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
- }
- | DIR_DOUBLE datavals {
- $$ = yasm_bc_create_data(&$2, 8, 0, parser_gas->arch, cur_line);
- }
- | DIR_TFLOAT datavals {
- $$ = yasm_bc_create_data(&$2, 10, 0, parser_gas->arch, cur_line);
- }
- /* Empty space / fill data definition directives */
- | DIR_SKIP expr {
- $$ = yasm_bc_create_reserve($2, 1, cur_line);
- }
- | DIR_SKIP expr ',' expr {
- yasm_datavalhead dvs;
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_expr($4));
- $$ = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
-
- yasm_bc_set_multiple($$, $2);
- }
- /* fill data definition directive */
- | DIR_FILL expr {
- $$ = gas_parser_dir_fill(parser_gas, $2, NULL, NULL);
- }
- | DIR_FILL expr ',' expr {
- $$ = gas_parser_dir_fill(parser_gas, $2, $4, NULL);
- }
- | DIR_FILL expr ',' expr ',' expr {
- $$ = gas_parser_dir_fill(parser_gas, $2, $4, $6);
- }
- /* Section directives */
- | DIR_TEXT {
- gas_switch_section(parser_gas, yasm__xstrdup(".text"), NULL, NULL,
- NULL, 1);
- $$ = NULL;
- }
- | DIR_DATA {
- gas_switch_section(parser_gas, yasm__xstrdup(".data"), NULL, NULL,
- NULL, 1);
- $$ = NULL;
- }
- | DIR_BSS {
- gas_switch_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL, NULL,
- 1);
- $$ = NULL;
- }
- | DIR_SECTION label_id {
- gas_switch_section(parser_gas, $2, NULL, NULL, NULL, 0);
- $$ = NULL;
- }
- | DIR_SECTION label_id ',' STRING {
- gas_switch_section(parser_gas, $2, $4.contents, NULL, NULL, 0);
- yasm_xfree($4.contents);
- $$ = NULL;
- }
- | DIR_SECTION label_id ',' STRING ',' '@' label_id {
- gas_switch_section(parser_gas, $2, $4.contents, $7, NULL, 0);
- yasm_xfree($4.contents);
- $$ = NULL;
- }
- | DIR_SECTION label_id ',' STRING ',' '@' label_id ',' dirvals {
- gas_switch_section(parser_gas, $2, $4.contents, $7, &$9, 0);
- yasm_xfree($4.contents);
- $$ = NULL;
- }
- /* Other directives */
- | DIR_IDENT dirstrvals {
- yasm_objfmt_directive(parser_gas->objfmt, "ident", &$2, NULL,
- cur_line);
- yasm_vps_delete(&$2);
- $$ = NULL;
- }
- | DIR_FILE INTNUM STRING {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($2)));
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create($3.contents, NULL);
- yasm_vps_append(&vps, vp);
-
- yasm_dbgfmt_directive(parser_gas->dbgfmt, "file",
- parser_gas->cur_section, &vps, cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_FILE STRING {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- /* This form also sets the assembler's internal line number */
- if (parser_gas->dir_fileline == 3) {
- /* Have both file and line */
- const char *old_fn;
- unsigned long old_line;
-
- yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn,
- &old_line);
- yasm_linemap_set(parser_gas->linemap, $2.contents,
- old_line, 1);
- } else if (parser_gas->dir_fileline == 2) {
- /* Had previous line directive only */
- parser_gas->dir_fileline = 3;
- yasm_linemap_set(parser_gas->linemap, $2.contents,
- parser_gas->dir_line, 1);
- } else {
- /* Didn't see line yet, save file */
- parser_gas->dir_fileline = 1;
- if (parser_gas->dir_file)
- yasm_xfree(parser_gas->dir_file);
- parser_gas->dir_file = yasm__xstrdup($2.contents);
- }
-
- /* Pass change along to debug format */
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create($2.contents, NULL);
- yasm_vps_append(&vps, vp);
-
- yasm_dbgfmt_directive(parser_gas->dbgfmt, "file",
- parser_gas->cur_section, &vps, cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_LOC INTNUM INTNUM {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($2)));
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($3)));
- yasm_vps_append(&vps, vp);
-
- yasm_dbgfmt_directive(parser_gas->dbgfmt, "loc",
- parser_gas->cur_section, &vps, cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_LOC INTNUM INTNUM INTNUM {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($2)));
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($3)));
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create(NULL, p_expr_new_ident(yasm_expr_int($4)));
- yasm_vps_append(&vps, vp);
-
- yasm_dbgfmt_directive(parser_gas->dbgfmt, "loc",
- parser_gas->cur_section, &vps, cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_TYPE label_id ',' '@' label_id {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create($2, NULL);
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create($5, NULL);
- yasm_vps_append(&vps, vp);
-
- yasm_objfmt_directive(parser_gas->objfmt, "type", &vps, NULL,
- cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_SIZE label_id ',' expr {
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create($2, NULL);
- yasm_vps_append(&vps, vp);
- vp = yasm_vp_create(NULL, $4);
- yasm_vps_append(&vps, vp);
-
- yasm_objfmt_directive(parser_gas->objfmt, "size", &vps, NULL,
- cur_line);
-
- yasm_vps_delete(&vps);
- $$ = NULL;
- }
- | DIR_ID dirvals {
- yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
- $1);
- $$ = (yasm_bytecode *)NULL;
- yasm_xfree($1);
- yasm_vps_delete(&$2);
- }
- | DIR_ID error {
- yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
- $1);
- $$ = (yasm_bytecode *)NULL;
- yasm_xfree($1);
- }
- | label_id '=' expr {
- $$ = (yasm_bytecode *)NULL;
- yasm_symtab_define_equ(p_symtab, $1, $3, cur_line);
- yasm_xfree($1);
- }
-;
-
-instr: INSN {
- $$ = yasm_bc_create_insn(parser_gas->arch, $1, 0, NULL, cur_line);
- }
- | INSN operands {
- $$ = yasm_bc_create_insn(parser_gas->arch, $1, $2.num_operands,
- &$2.operands, cur_line);
- }
- | INSN error {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
- $$ = NULL;
- }
- | PREFIX instr {
- $$ = $2;
- yasm_bc_insn_add_prefix($$, $1);
- }
- | SEGREG instr {
- $$ = $2;
- yasm_bc_insn_add_seg_prefix($$, $1[0]);
- }
- | PREFIX {
- $$ = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
- yasm_bc_insn_add_prefix($$, $1);
- }
- | SEGREG {
- $$ = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
- yasm_bc_insn_add_seg_prefix($$, $1[0]);
- }
- | ID {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("instruction not recognized: `%s'"), $1);
- $$ = NULL;
- }
- | ID operands {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("instruction not recognized: `%s'"), $1);
- $$ = NULL;
- }
- | ID error {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("instruction not recognized: `%s'"), $1);
- $$ = NULL;
- }
-;
-
-dirvals: /* empty */ { yasm_vps_initialize(&$$); }
- | dirvals2
-;
-
-dirvals2: expr {
- yasm_valparam *vp = yasm_vp_create(NULL, $1);
- yasm_vps_initialize(&$$);
- yasm_vps_append(&$$, vp);
- }
- | dirvals2 ',' expr {
- yasm_valparam *vp = yasm_vp_create(NULL, $3);
- yasm_vps_append(&$1, vp);
- $$ = $1;
- }
- | dirvals2 ',' ',' expr {
- yasm_valparam *vp = yasm_vp_create(NULL, NULL);
- yasm_vps_append(&$1, vp);
- vp = yasm_vp_create(NULL, $4);
- yasm_vps_append(&$1, vp);
- $$ = $1;
- }
-;
-
-dirstrvals: /* empty */ { yasm_vps_initialize(&$$); }
- | dirstrvals2
-;
-
-dirstrvals2: STRING {
- yasm_valparam *vp = yasm_vp_create($1.contents, NULL);
- yasm_vps_initialize(&$$);
- yasm_vps_append(&$$, vp);
- }
- | dirstrvals2 ',' STRING {
- yasm_valparam *vp = yasm_vp_create($3.contents, NULL);
- yasm_vps_append(&$1, vp);
- $$ = $1;
- }
-;
-
-strvals: /* empty */ { yasm_dvs_initialize(&$$); }
- | strvals2
-;
-
-strvals2: STRING {
- yasm_dataval *dv = yasm_dv_create_string($1.contents, $1.len);
- yasm_dvs_initialize(&$$);
- yasm_dvs_append(&$$, dv);
- }
- | strvals2 ',' STRING {
- yasm_dataval *dv = yasm_dv_create_string($3.contents, $3.len);
- yasm_dvs_append(&$1, dv);
- $$ = $1;
- }
-;
-
-datavals: /* empty */ { yasm_dvs_initialize(&$$); }
- | datavals2
-;
-
-datavals2: expr {
- yasm_dataval *dv = yasm_dv_create_expr($1);
- yasm_dvs_initialize(&$$);
- yasm_dvs_append(&$$, dv);
- }
- | datavals2 ',' expr {
- yasm_dataval *dv = yasm_dv_create_expr($3);
- yasm_dvs_append(&$1, dv);
- $$ = $1;
- }
-;
-
-/* instruction operands */
-operands: operand {
- yasm_ops_initialize(&$$.operands);
- yasm_ops_append(&$$.operands, $1);
- $$.num_operands = 1;
- }
- | operands ',' operand {
- yasm_ops_append(&$1.operands, $3);
- $$.operands = $1.operands;
- $$.num_operands = $1.num_operands+1;
- }
-;
-
-regmemexpr: '(' REG ')' {
- $$ = p_expr_new_ident(yasm_expr_reg($2[0]));
- }
- | '(' ',' REG ')' {
- $$ = p_expr_new(yasm_expr_reg($3[0]), YASM_EXPR_MUL,
- yasm_expr_int(yasm_intnum_create_uint(1)));
- }
- | '(' ',' INTNUM ')' {
- if (yasm_intnum_get_uint($3) != 1)
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("scale factor of %u without an index register"),
- yasm_intnum_get_uint($3));
- $$ = p_expr_new(yasm_expr_int(yasm_intnum_create_uint(0)),
- YASM_EXPR_MUL, yasm_expr_int($3));
- }
- | '(' REG ',' REG ')' {
- $$ = p_expr_new(yasm_expr_reg($2[0]), YASM_EXPR_ADD,
- yasm_expr_expr(p_expr_new(yasm_expr_reg($4[0]), YASM_EXPR_MUL,
- yasm_expr_int(yasm_intnum_create_uint(1)))));
- }
- | '(' ',' REG ',' INTNUM ')' {
- $$ = p_expr_new(yasm_expr_reg($3[0]), YASM_EXPR_MUL,
- yasm_expr_int($5));
- }
- | '(' REG ',' REG ',' INTNUM ')' {
- $$ = p_expr_new(yasm_expr_reg($2[0]), YASM_EXPR_ADD,
- yasm_expr_expr(p_expr_new(yasm_expr_reg($4[0]), YASM_EXPR_MUL,
- yasm_expr_int($6))));
- }
-;
-
-/* memory addresses */
-memaddr: expr {
- $$ = yasm_arch_ea_create(parser_gas->arch, $1);
- }
- | regmemexpr {
- $$ = yasm_arch_ea_create(parser_gas->arch, $1);
- yasm_ea_set_strong($$, 1);
- }
- | expr regmemexpr {
- $$ = yasm_arch_ea_create(parser_gas->arch,
- p_expr_new_tree($2, YASM_EXPR_ADD, $1));
- yasm_ea_set_strong($$, 1);
- }
- | SEGREG ':' memaddr {
- $$ = $3;
- yasm_ea_set_segreg($$, $1[0]);
- }
-;
-
-operand: memaddr { $$ = yasm_operand_create_mem($1); }
- | REG { $$ = yasm_operand_create_reg($1[0]); }
- | SEGREG { $$ = yasm_operand_create_segreg($1[0]); }
- | REGGROUP { $$ = yasm_operand_create_reg($1[0]); }
- | REGGROUP '(' INTNUM ')' {
- unsigned long reg =
- yasm_arch_reggroup_get_reg(parser_gas->arch, $1[0],
- yasm_intnum_get_uint($3));
- if (reg == 0) {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"),
- yasm_intnum_get_uint($3));
- $$ = yasm_operand_create_reg($1[0]);
- } else
- $$ = yasm_operand_create_reg(reg);
- yasm_intnum_destroy($3);
- }
- | '$' expr { $$ = yasm_operand_create_imm($2); }
- | '*' REG {
- $$ = yasm_operand_create_reg($2[0]);
- $$->deref = 1;
- }
- | '*' memaddr {
- $$ = yasm_operand_create_mem($2);
- $$->deref = 1;
- }
-;
-
-/* Expressions */
-expr: INTNUM { $$ = p_expr_new_ident(yasm_expr_int($1)); }
- | FLTNUM { $$ = p_expr_new_ident(yasm_expr_float($1)); }
- | explabel { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
- | expr '|' expr { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
- | expr '^' expr { $$ = p_expr_new_tree($1, YASM_EXPR_XOR, $3); }
- | expr '&' expr { $$ = p_expr_new_tree($1, YASM_EXPR_AND, $3); }
- | expr '!' expr { $$ = p_expr_new_tree($1, YASM_EXPR_NOR, $3); }
- | expr LEFT_OP expr { $$ = p_expr_new_tree($1, YASM_EXPR_SHL, $3); }
- | expr RIGHT_OP expr { $$ = p_expr_new_tree($1, YASM_EXPR_SHR, $3); }
- | expr '+' expr { $$ = p_expr_new_tree($1, YASM_EXPR_ADD, $3); }
- | expr '-' expr { $$ = p_expr_new_tree($1, YASM_EXPR_SUB, $3); }
- | expr '*' expr { $$ = p_expr_new_tree($1, YASM_EXPR_MUL, $3); }
- | expr '/' expr { $$ = p_expr_new_tree($1, YASM_EXPR_DIV, $3); }
- | expr '%' expr { $$ = p_expr_new_tree($1, YASM_EXPR_MOD, $3); }
- | '+' expr %prec UNARYOP { $$ = $2; }
- | '-' expr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NEG, $2); }
- | '~' expr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NOT, $2); }
- | '(' expr ')' { $$ = $2; }
-;
-
-explabel: expr_id {
- /* "." references the current assembly position */
- if ($1[1] == '\0' && $1[0] == '.')
- $$ = yasm_symtab_define_curpos(p_symtab, ".", parser_gas->prev_bc,
- cur_line);
- else
- $$ = yasm_symtab_use(p_symtab, $1, cur_line);
- yasm_xfree($1);
- }
- | expr_id '@' label_id {
- /* TODO: this is needed for shared objects, e.g. sym@PLT */
- $$ = yasm_symtab_use(p_symtab, $1, cur_line);
- yasm_xfree($1);
- yasm_xfree($3);
- }
-;
-
-expr_id: label_id
- | DIR_DATA { $$ = yasm__xstrdup(".data"); }
- | DIR_TEXT { $$ = yasm__xstrdup(".text"); }
- | DIR_BSS { $$ = yasm__xstrdup(".bss"); }
-;
-
-label_id: ID | DIR_ID;
-
-%%
-/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
-
-#undef parser_gas
-
-static void
-define_label(yasm_parser_gas *parser_gas, char *name, int local)
-{
- if (!local) {
- if (parser_gas->locallabel_base)
- yasm_xfree(parser_gas->locallabel_base);
- parser_gas->locallabel_base_len = strlen(name);
- parser_gas->locallabel_base =
- yasm_xmalloc(parser_gas->locallabel_base_len+1);
- strcpy(parser_gas->locallabel_base, name);
- }
-
- yasm_symtab_define_label(p_symtab, name, parser_gas->prev_bc, 1,
- cur_line);
- yasm_xfree(name);
-}
-
-static void
-define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
- yasm_expr *size, /*@null@*/ yasm_expr *align)
-{
- /* Put into .bss section. */
- /*@dependent@*/ yasm_section *bss =
- gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL, NULL, 1);
-
- if (align) {
- /* XXX: assume alignment is in bytes, not power-of-two */
- yasm_section_bcs_append(bss, gas_parser_align(parser_gas, bss, align,
- NULL, NULL, 0));
- }
-
- yasm_symtab_define_label(p_symtab, name, yasm_section_bcs_last(bss), 1,
- cur_line);
- yasm_section_bcs_append(bss, yasm_bc_create_reserve(size, 1, cur_line));
- yasm_xfree(name);
-}
-
-static yasm_section *
-gas_get_section(yasm_parser_gas *parser_gas, char *name,
- /*@null@*/ char *flags, /*@null@*/ char *type,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- int builtin)
-{
- yasm_valparamhead vps;
- yasm_valparam *vp;
- char *gasflags;
- yasm_section *new_section;
-
- yasm_vps_initialize(&vps);
- vp = yasm_vp_create(name, NULL);
- yasm_vps_append(&vps, vp);
-
- if (!builtin) {
- if (flags) {
- gasflags = yasm_xmalloc(5+strlen(flags));
- strcpy(gasflags, "gas_");
- strcat(gasflags, flags);
- } else
- gasflags = yasm__xstrdup("gas_");
- vp = yasm_vp_create(gasflags, NULL);
- yasm_vps_append(&vps, vp);
- if (type) {
- vp = yasm_vp_create(type, NULL);
- yasm_vps_append(&vps, vp);
- }
- }
-
- new_section = yasm_objfmt_section_switch(parser_gas->objfmt, &vps,
- objext_valparams, cur_line);
-
- yasm_vps_delete(&vps);
- return new_section;
-}
-
-static void
-gas_switch_section(yasm_parser_gas *parser_gas, char *name,
- /*@null@*/ char *flags, /*@null@*/ char *type,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- int builtin)
-{
- yasm_section *new_section;
-
- new_section = gas_get_section(parser_gas, yasm__xstrdup(name), flags, type,
- objext_valparams, builtin);
- if (new_section) {
- parser_gas->cur_section = new_section;
- parser_gas->prev_bc = yasm_section_bcs_last(new_section);
- } else
- yasm_error_set(YASM_ERROR_GENERAL, N_("invalid section name `%s'"),
- name);
-
- yasm_xfree(name);
-
- if (objext_valparams)
- yasm_vps_delete(objext_valparams);
-}
-
-static yasm_bytecode *
-gas_parser_align(yasm_parser_gas *parser_gas, yasm_section *sect,
- yasm_expr *boundval, /*@null@*/ yasm_expr *fillval,
- /*@null@*/ yasm_expr *maxskipval, int power2)
-{
- yasm_intnum *boundintn;
-
- /* Convert power of two to number of bytes if necessary */
- if (power2)
- boundval = yasm_expr_create(YASM_EXPR_SHL,
- yasm_expr_int(yasm_intnum_create_uint(1)),
- yasm_expr_expr(boundval), cur_line);
-
- /* Largest .align in the section specifies section alignment. */
- boundintn = yasm_expr_get_intnum(&boundval, 0);
- if (boundintn) {
- unsigned long boundint = yasm_intnum_get_uint(boundintn);
-
- /* Alignments must be a power of two. */
- if (is_exp2(boundint)) {
- if (boundint > yasm_section_get_align(sect))
- yasm_section_set_align(sect, boundint, cur_line);
- }
- }
-
- return yasm_bc_create_align(boundval, fillval, maxskipval,
- yasm_section_is_code(sect) ?
- yasm_arch_get_fill(parser_gas->arch) : NULL,
- cur_line);
-}
-
-static yasm_bytecode *
-gas_parser_dir_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams,
- int power2)
-{
- /*@dependent@*/ yasm_valparam *bound, *fill = NULL, *maxskip = NULL;
- yasm_expr *boundval, *fillval = NULL, *maxskipval = NULL;
-
- bound = yasm_vps_first(valparams);
- boundval = bound->param;
- bound->param = NULL;
- if (bound && boundval) {
- fill = yasm_vps_next(bound);
- } else {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("align directive must specify alignment"));
- return NULL;
- }
-
- if (fill) {
- fillval = fill->param;
- fill->param = NULL;
- maxskip = yasm_vps_next(fill);
- }
-
- if (maxskip) {
- maxskipval = maxskip->param;
- maxskip->param = NULL;
- }
-
- yasm_vps_delete(valparams);
-
- return gas_parser_align(parser_gas, parser_gas->cur_section, boundval,
- fillval, maxskipval, power2);
-}
-
-static yasm_bytecode *
-gas_parser_dir_fill(yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat,
- /*@only@*/ /*@null@*/ yasm_expr *size,
- /*@only@*/ /*@null@*/ yasm_expr *value)
-{
- yasm_datavalhead dvs;
- yasm_bytecode *bc;
- unsigned int ssize;
-
- if (size) {
- /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
- intn = yasm_expr_get_intnum(&size, 0);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
- N_("size must be an absolute expression"));
- yasm_expr_destroy(repeat);
- yasm_expr_destroy(size);
- if (value)
- yasm_expr_destroy(value);
- return NULL;
- }
- ssize = yasm_intnum_get_uint(intn);
- } else
- ssize = 1;
-
- if (!value)
- value = yasm_expr_create_ident(
- yasm_expr_int(yasm_intnum_create_uint(0)), cur_line);
-
- yasm_dvs_initialize(&dvs);
- yasm_dvs_append(&dvs, yasm_dv_create_expr(value));
- bc = yasm_bc_create_data(&dvs, ssize, 0, parser_gas->arch, cur_line);
-
- yasm_bc_set_multiple(bc, repeat);
-
- return bc;
-}
-
-static void
-gas_parser_directive(yasm_parser_gas *parser_gas, const char *name,
- yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams)
-{
- unsigned long line = cur_line;
-
- /* Handle (mostly) output-format independent directives here */
- if (!yasm_arch_parse_directive(parser_gas->arch, name, valparams,
- objext_valparams, parser_gas->object, line)) {
- ;
- } else if (yasm_objfmt_directive(parser_gas->objfmt, name, valparams,
- objext_valparams, line)) {
- yasm_error_set(YASM_ERROR_GENERAL, N_("unrecognized directive [%s]"),
- name);
- }
-
- yasm_vps_delete(valparams);
- if (objext_valparams)
- yasm_vps_delete(objext_valparams);
-}
+++ /dev/null
-/* $Id$
- * Variable name redefinitions for GAS-compatible parser
- *
- * Copyright (C) 2005 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of other contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#define yy_create_buffer gas_parser__create_buffer
-#define yy_delete_buffer gas_parser__delete_buffer
-#define yy_init_buffer gas_parser__init_buffer
-#define yy_load_buffer_state gas_parser__load_buffer_state
-#define yy_switch_to_buffer gas_parser__switch_to_buffer
-#define yyact gas_parser_act
-#define yyback gas_parser_back
-#define yybgin gas_parser_bgin
-#define yychar gas_parser_char
-#define yychk gas_parser_chk
-#define yycrank gas_parser_crank
-#define yydebug gas_parser_debug
-#define yydef gas_parser_def
-#define yyerrflag gas_parser_errflag
-#define yyerror gas_parser_error
-#define yyestate gas_parser_estate
-#define yyexca gas_parser_exca
-#define yyextra gas_parser_extra
-#define yyfnd gas_parser_fnd
-#define yyin gas_parser_in
-#define yyinput gas_parser_input
-#define yyleng gas_parser_leng
-#define yylex gas_parser_lex
-#define yylineno gas_parser_lineno
-#define yylook gas_parser_look
-#define yylsp gas_parser_lsp
-#define yylstate gas_parser_lstate
-#define yylval gas_parser_lval
-#define yymatch gas_parser_match
-#define yymorfg gas_parser_morfg
-#define yynerrs gas_parser_nerrs
-#define yyolsp gas_parser_olsp
-#define yyout gas_parser_out
-#define yyoutput gas_parser_output
-#define yypact gas_parser_pact
-#define yyparse gas_parser_parse
-#define yypgo gas_parser_pgo
-#define yyprevious gas_parser_previous
-#define yyps gas_parser_ps
-#define yypv gas_parser_pv
-#define yyr1 gas_parser_r1
-#define yyr2 gas_parser_r2
-#define yyreds gas_parser_reds
-#define yyrestart gas_parser_restart
-#define yys gas_parser_s
-#define yysbuf gas_parser_sbuf
-#define yysptr gas_parser_sptr
-#define yystate gas_parser_state
-#define yysvec gas_parser_svec
-#define yytchar gas_parser_tchar
-#define yytext gas_parser_text
-#define yytmp gas_parser_tmp
-#define yytoks gas_parser_toks
-#define yytop gas_parser_top
-#define yyunput gas_parser_unput
-#define yyv gas_parser_v
-#define yyval gas_parser_val
-#define yyvstop gas_parser_vstop
-/*#define yywrap gas_parser_wrap*/
--- /dev/null
+/*
+ * GAS-compatible parser
+ *
+ * Copyright (C) 2005 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of other contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <util.h>
+RCSID("$Id$");
+
+#define YASM_LIB_INTERNAL
+#define YASM_EXPR_INTERNAL
+#include <libyasm.h>
+
+#include <limits.h>
+#include <math.h>
+
+#include "modules/parsers/gas/gas-parser.h"
+
+static yasm_bytecode *parse_line(yasm_parser_gas *parser_gas);
+static yasm_bytecode *parse_instr(yasm_parser_gas *parser_gas);
+static int parse_dirvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps);
+static int parse_dirstrvals(yasm_parser_gas *parser_gas,
+ yasm_valparamhead *vps);
+static int parse_datavals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs);
+static int parse_strvals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs);
+static yasm_effaddr *parse_memaddr(yasm_parser_gas *parser_gas);
+static yasm_insn_operand *parse_operand(yasm_parser_gas *parser_gas);
+static yasm_expr *parse_expr(yasm_parser_gas *parser_gas);
+static yasm_expr *parse_expr0(yasm_parser_gas *parser_gas);
+static yasm_expr *parse_expr1(yasm_parser_gas *parser_gas);
+static yasm_expr *parse_expr2(yasm_parser_gas *parser_gas);
+
+static void define_label(yasm_parser_gas *parser_gas, char *name, int local);
+static void define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
+ yasm_expr *size, /*@null@*/ yasm_expr *align);
+static yasm_section *gas_get_section
+ (yasm_parser_gas *parser_gas, /*@only@*/ char *name, /*@null@*/ char *flags,
+ /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams,
+ int builtin);
+static void gas_switch_section
+ (yasm_parser_gas *parser_gas, /*@only@*/ char *name, /*@null@*/ char *flags,
+ /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams,
+ int builtin);
+static yasm_bytecode *gas_parser_align
+ (yasm_parser_gas *parser_gas, yasm_section *sect, yasm_expr *boundval,
+ /*@null@*/ yasm_expr *fillval, /*@null@*/ yasm_expr *maxskipval,
+ int power2);
+static yasm_bytecode *gas_parser_dir_fill
+ (yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat,
+ /*@only@*/ /*@null@*/ yasm_expr *size,
+ /*@only@*/ /*@null@*/ yasm_expr *value);
+static void gas_parser_directive
+ (yasm_parser_gas *parser_gas, const char *name,
+ yasm_valparamhead *valparams,
+ /*@null@*/ yasm_valparamhead *objext_valparams);
+
+#define is_eol_tok(tok) ((tok) == '\n' || (tok) == ';' || (tok) == 0)
+#define is_eol() is_eol_tok(curtok)
+
+#define get_next_token() (curtok = gas_parser_lex(&curval, parser_gas))
+
+static void
+get_peek_token(yasm_parser_gas *parser_gas)
+{
+ char savech = parser_gas->tokch;
+ if (parser_gas->peek_token != NONE)
+ yasm_internal_error(N_("only can have one token of lookahead"));
+ parser_gas->peek_token =
+ gas_parser_lex(&parser_gas->peek_tokval, parser_gas);
+ parser_gas->peek_tokch = parser_gas->tokch;
+ parser_gas->tokch = savech;
+}
+
+static void
+destroy_curtok_(yasm_parser_gas *parser_gas)
+{
+ if (curtok < 256)
+ ;
+ else switch ((enum tokentype)curtok) {
+ case INTNUM:
+ yasm_intnum_destroy(curval.intn);
+ break;
+ case FLTNUM:
+ yasm_floatnum_destroy(curval.flt);
+ break;
+ case ID:
+ case LABEL:
+ yasm_xfree(curval.str_val);
+ break;
+ case STRING:
+ yasm_xfree(curval.str.contents);
+ break;
+ default:
+ break;
+ }
+ curtok = NONE; /* sanity */
+}
+#define destroy_curtok() destroy_curtok_(parser_gas)
+
+/* Eat all remaining tokens to EOL, discarding all of them. If there's any
+ * intervening tokens, generates an error (junk at end of line).
+ */
+static void
+demand_eol_(yasm_parser_gas *parser_gas)
+{
+ if (is_eol())
+ return;
+
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("junk at end of line, first unrecognized character is `%c'"),
+ parser_gas->tokch);
+
+ do {
+ destroy_curtok();
+ get_next_token();
+ } while (!is_eol());
+}
+#define demand_eol() demand_eol_(parser_gas)
+
+static int
+expect_(yasm_parser_gas *parser_gas, int token)
+{
+ static char strch[] = "expected ` '";
+ const char *str;
+
+ if (curtok == token)
+ return 1;
+
+ switch (token) {
+ case INTNUM: str = "expected integer"; break;
+ case FLTNUM: str = "expected floating point value"; break;
+ case STRING: str = "expected string"; break;
+ case INSN: str = "expected instruction"; break;
+ case PREFIX: str = "expected instruction prefix"; break;
+ case REG: str = "expected register"; break;
+ case REGGROUP: str = "expected register group"; break;
+ case SEGREG: str = "expected segment register"; break;
+ case TARGETMOD: str = "expected target modifier"; break;
+ case LEFT_OP: str = "expected <<"; break;
+ case RIGHT_OP: str = "expected >>"; break;
+ case ID: str = "expected identifier"; break;
+ case LABEL: str = "expected label"; break;
+ case LINE:
+ case DIR_ALIGN:
+ case DIR_ASCII:
+ case DIR_COMM:
+ case DIR_DATA:
+ case DIR_ENDR:
+ case DIR_EXTERN:
+ case DIR_EQU:
+ case DIR_FILE:
+ case DIR_FILL:
+ case DIR_GLOBAL:
+ case DIR_IDENT:
+ case DIR_LEB128:
+ case DIR_LINE:
+ case DIR_LOC:
+ case DIR_LOCAL:
+ case DIR_LCOMM:
+ case DIR_ORG:
+ case DIR_REPT:
+ case DIR_SECTION:
+ case DIR_SECTNAME:
+ case DIR_SIZE:
+ case DIR_SKIP:
+ case DIR_TYPE:
+ case DIR_WEAK:
+ case DIR_ZERO:
+ str = "expected directive";
+ break;
+ default:
+ strch[10] = token;
+ str = strch;
+ break;
+ }
+ yasm_error_set(YASM_ERROR_PARSE, str);
+ destroy_curtok();
+ return 0;
+}
+#define expect(token) expect_(parser_gas, token)
+
+void
+gas_parser_parse(yasm_parser_gas *parser_gas)
+{
+ while (get_next_token() != 0) {
+ yasm_bytecode *bc = NULL, *temp_bc;
+
+ if (!is_eol()) {
+ bc = parse_line(parser_gas);
+ demand_eol();
+ }
+
+ yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
+
+ temp_bc = yasm_section_bcs_append(parser_gas->cur_section, bc);
+ if (temp_bc)
+ parser_gas->prev_bc = temp_bc;
+ if (curtok == ';')
+ continue; /* don't advance line number until \n */
+ if (parser_gas->save_input)
+ yasm_linemap_add_source(parser_gas->linemap,
+ temp_bc,
+ (char *)parser_gas->save_line[parser_gas->save_last ^ 1]);
+ yasm_linemap_goto_next(parser_gas->linemap);
+ parser_gas->dir_line++; /* keep track for .line followed by .file */
+ }
+}
+
+static yasm_bytecode *
+parse_line(yasm_parser_gas *parser_gas)
+{
+ yasm_bytecode *bc;
+ yasm_expr *e;
+ yasm_intnum *intn;
+ yasm_datavalhead dvs;
+ yasm_valparamhead vps;
+ yasm_valparam *vp;
+ unsigned int ival;
+ char *id;
+
+ bc = parse_instr(parser_gas);
+ if (bc)
+ return bc;
+
+ switch (curtok) {
+ case ID:
+ id = ID_val;
+ get_next_token(); /* ID */
+ if (curtok == ':') {
+ /* Label */
+ get_next_token(); /* : */
+ define_label(parser_gas, id, 0);
+ return parse_instr(parser_gas);
+ } else if (curtok == '=') {
+ /* EQU */
+ get_next_token(); /* = */
+ e = parse_expr(parser_gas);
+ if (e)
+ yasm_symtab_define_equ(p_symtab, id, e, cur_line);
+ else
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected after `%s'"), "=");
+ yasm_xfree(id);
+ return NULL;
+ }
+ /* must be an error at this point */
+ if (id[0] == '.')
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("directive `%s' not recognized"), id);
+ else
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("instruction not recognized: `%s'"), id);
+ yasm_xfree(id);
+ return NULL;
+ case LABEL:
+ define_label(parser_gas, LABEL_val, 0);
+ get_next_token(); /* LABEL */
+ return parse_instr(parser_gas);
+
+ /* Line directive */
+ case DIR_LINE:
+ get_next_token(); /* DIR_LINE */
+
+ if (!expect(INTNUM)) return NULL;
+ if (yasm_intnum_sign(INTNUM_val) < 0) {
+ get_next_token(); /* INTNUM */
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("line number is negative"));
+ return NULL;
+ }
+
+ parser_gas->dir_line = yasm_intnum_get_uint(INTNUM_val);
+ yasm_intnum_destroy(INTNUM_val);
+ get_next_token(); /* INTNUM */
+
+ if (parser_gas->dir_fileline == 3) {
+ /* Have both file and line */
+ yasm_linemap_set(parser_gas->linemap, NULL,
+ parser_gas->dir_line, 1);
+ } else if (parser_gas->dir_fileline == 1) {
+ /* Had previous file directive only */
+ parser_gas->dir_fileline = 3;
+ yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file,
+ parser_gas->dir_line, 1);
+ } else {
+ /* Didn't see file yet */
+ parser_gas->dir_fileline = 2;
+ }
+ return NULL;
+
+ /* Macro directives */
+ case DIR_REPT:
+ get_next_token(); /* DIR_REPT */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected after `%s'"),
+ ".rept");
+ return NULL;
+ }
+ intn = yasm_expr_get_intnum(&e, 0);
+
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("rept expression not absolute"));
+ } else if (yasm_intnum_sign(intn) < 0) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_("rept expression is negative"));
+ } else {
+ gas_rept *rept = yasm_xmalloc(sizeof(gas_rept));
+ STAILQ_INIT(&rept->lines);
+ rept->startline = cur_line;
+ rept->numrept = yasm_intnum_get_uint(intn);
+ rept->numdone = 0;
+ rept->line = NULL;
+ rept->linepos = 0;
+ rept->ended = 0;
+ rept->oldbuf = NULL;
+ rept->oldbuflen = 0;
+ rept->oldbufpos = 0;
+ parser_gas->rept = rept;
+ }
+ return NULL;
+ case DIR_ENDR:
+ get_next_token(); /* DIR_ENDR */
+ /* Shouldn't ever get here unless we didn't get a DIR_REPT first */
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("endr without matching rept"));
+ return NULL;
+
+ /* Alignment directives */
+ case DIR_ALIGN:
+ {
+ yasm_expr *bound, *fill=NULL, *maxskip=NULL;
+
+ ival = DIR_ALIGN_val;
+ get_next_token(); /* DIR_ALIGN */
+
+ bound = parse_expr(parser_gas);
+ if (!bound) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_(".align directive must specify alignment"));
+ return NULL;
+ }
+
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ fill = parse_expr(parser_gas);
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ maxskip = parse_expr(parser_gas);
+ }
+ }
+
+ return gas_parser_align(parser_gas, parser_gas->cur_section, bound,
+ fill, maxskip, (int)ival);
+ }
+ case DIR_ORG:
+ get_next_token(); /* DIR_ORG */
+ if (!expect(INTNUM)) return NULL;
+ /* TODO: support expr instead of intnum */
+ bc = yasm_bc_create_org(yasm_intnum_get_uint(INTNUM_val), cur_line);
+ yasm_intnum_destroy(INTNUM_val);
+ get_next_token(); /* INTNUM */
+ return bc;
+
+ /* Data visibility directives */
+ case DIR_LOCAL:
+ get_next_token(); /* DIR_LOCAL */
+ if (!expect(ID)) return NULL;
+ yasm_symtab_declare(parser_gas->symtab, ID_val, YASM_SYM_DLOCAL,
+ cur_line);
+ yasm_xfree(ID_val);
+ get_next_token(); /* ID */
+ return NULL;
+ case DIR_GLOBAL:
+ get_next_token(); /* DIR_GLOBAL */
+ if (!expect(ID)) return NULL;
+ yasm_objfmt_global_declare(parser_gas->objfmt, ID_val, NULL,
+ cur_line);
+ yasm_xfree(ID_val);
+ get_next_token(); /* ID */
+ return NULL;
+ case DIR_COMM:
+ case DIR_LCOMM:
+ {
+ yasm_expr *align = NULL;
+ /*@null@*/ /*@dependent@*/ yasm_symrec *sym;
+ int is_lcomm = curtok == DIR_LCOMM;
+
+ get_next_token(); /* DIR_LOCAL */
+
+ if (!expect(ID)) return NULL;
+ id = ID_val;
+ get_next_token(); /* ID */
+ if (!expect(',')) {
+ yasm_xfree(id);
+ return NULL;
+ }
+ get_next_token(); /* , */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("size expected for `%s'"),
+ ".COMM");
+ return NULL;
+ }
+ if (curtok == ',') {
+ /* Optional alignment expression */
+ get_next_token(); /* ',' */
+ align = parse_expr(parser_gas);
+ }
+ /* If already explicitly declared local, treat like LCOMM */
+ if (is_lcomm
+ || ((sym = yasm_symtab_get(parser_gas->symtab, id))
+ && yasm_symrec_get_visibility(sym) == YASM_SYM_DLOCAL)) {
+ define_lcomm(parser_gas, id, e, align);
+ } else if (align) {
+ /* Give third parameter as objext valparam */
+ yasm_vps_initialize(&vps);
+ vp = yasm_vp_create(NULL, align);
+ yasm_vps_append(&vps, vp);
+
+ yasm_objfmt_common_declare(parser_gas->objfmt, id, e, &vps,
+ cur_line);
+
+ yasm_vps_delete(&vps);
+ yasm_xfree(id);
+ } else {
+ yasm_objfmt_common_declare(parser_gas->objfmt, id, e, NULL,
+ cur_line);
+ yasm_xfree(id);
+ }
+ return NULL;
+ }
+ case DIR_EXTERN:
+ get_next_token(); /* DIR_EXTERN */
+ if (!expect(ID)) return NULL;
+ /* Go ahead and do it, even though all undef become extern */
+ yasm_objfmt_extern_declare(parser_gas->objfmt, ID_val, NULL,
+ cur_line);
+ yasm_xfree(ID_val);
+ get_next_token(); /* ID */
+ return NULL;
+ case DIR_WEAK:
+ get_next_token(); /* DIR_EXTERN */
+ if (!expect(ID)) return NULL;
+
+ yasm_vps_initialize(&vps);
+ vp = yasm_vp_create(ID_val, NULL);
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* ID */
+
+ yasm_objfmt_directive(parser_gas->objfmt, "weak", &vps, NULL,
+ cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+
+ /* Integer data definition directives */
+ case DIR_ASCII:
+ ival = DIR_ASCII_val;
+ get_next_token(); /* DIR_ASCII */
+ if (!parse_strvals(parser_gas, &dvs))
+ return NULL;
+ return yasm_bc_create_data(&dvs, 1, (int)ival, parser_gas->arch,
+ cur_line);
+ case DIR_DATA:
+ ival = DIR_DATA_val;
+ get_next_token(); /* DIR_DATA */
+ if (!parse_datavals(parser_gas, &dvs))
+ return NULL;
+ return yasm_bc_create_data(&dvs, ival, 0, parser_gas->arch,
+ cur_line);
+ case DIR_LEB128:
+ ival = DIR_LEB128_val;
+ get_next_token(); /* DIR_LEB128 */
+ if (!parse_datavals(parser_gas, &dvs))
+ return NULL;
+ return yasm_bc_create_leb128(&dvs, (int)ival, cur_line);
+
+ /* Empty space / fill data definition directives */
+ case DIR_ZERO:
+ get_next_token(); /* DIR_ZERO */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected after `%s'"), ".ZERO");
+ return NULL;
+ }
+
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(
+ p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
+ bc = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
+ yasm_bc_set_multiple(bc, e);
+ return bc;
+ case DIR_SKIP:
+ {
+ yasm_expr *e_val;
+
+ get_next_token(); /* DIR_SKIP */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected after `%s'"), ".SKIP");
+ return NULL;
+ }
+ if (curtok != ',')
+ return yasm_bc_create_reserve(e, 1, cur_line);
+ get_next_token(); /* ',' */
+ e_val = parse_expr(parser_gas);
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(e_val));
+ bc = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
+
+ yasm_bc_set_multiple(bc, e);
+ return bc;
+ }
+
+ /* fill data definition directive */
+ case DIR_FILL:
+ {
+ yasm_expr *sz=NULL, *val=NULL;
+ get_next_token(); /* DIR_FILL */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected after `%s'"), ".FILL");
+ return NULL;
+ }
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ sz = parse_expr(parser_gas);
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ val = parse_expr(parser_gas);
+ }
+ }
+ return gas_parser_dir_fill(parser_gas, e, sz, val);
+ }
+
+ /* Section directives */
+ case DIR_SECTNAME:
+ gas_switch_section(parser_gas, DIR_SECTNAME_val, NULL, NULL, NULL,
+ 1);
+ get_next_token(); /* DIR_SECTNAME */
+ return NULL;
+ case DIR_SECTION:
+ {
+ /* DIR_SECTION ID ',' STRING ',' '@' ID ',' dirvals */
+ char *sectname, *flags = NULL, *type = NULL;
+ yasm_valparamhead objext_vps;
+ int have_vps = 0;
+
+ get_next_token(); /* DIR_SECTION */
+
+ if (!expect(ID)) return NULL;
+ sectname = ID_val;
+ get_next_token(); /* ID */
+
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ if (!expect(STRING)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("flag string expected"));
+ yasm_xfree(sectname);
+ return NULL;
+ }
+ flags = STRING_val.contents;
+ get_next_token(); /* STRING */
+ }
+
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ if (!expect('@')) {
+ yasm_xfree(sectname);
+ yasm_xfree(flags);
+ return NULL;
+ }
+ get_next_token(); /* '@' */
+ if (!expect(ID)) {
+ yasm_xfree(sectname);
+ yasm_xfree(flags);
+ return NULL;
+ }
+ type = ID_val;
+ get_next_token(); /* ID */
+ }
+
+ if (curtok == ',') {
+ get_next_token(); /* ',' */
+ if (parse_dirvals(parser_gas, &vps))
+ have_vps = 1;
+ }
+
+ gas_switch_section(parser_gas, sectname, flags, type,
+ have_vps ? &vps : NULL, 0);
+ yasm_xfree(flags);
+ return NULL;
+ }
+
+ /* Other directives */
+ case DIR_IDENT:
+ get_next_token(); /* DIR_IDENT */
+ if (!parse_dirstrvals(parser_gas, &vps))
+ return NULL;
+ yasm_objfmt_directive(parser_gas->objfmt, "ident", &vps, NULL,
+ cur_line);
+ yasm_vps_delete(&vps);
+ return NULL;
+ case DIR_FILE:
+ get_next_token(); /* DIR_FILE */
+ if (curtok == STRING) {
+ /* No file number; this form also sets the assembler's
+ * internal line number.
+ */
+ char *filename = STRING_val.contents;
+ get_next_token(); /* STRING */
+ if (parser_gas->dir_fileline == 3) {
+ /* Have both file and line */
+ const char *old_fn;
+ unsigned long old_line;
+
+ yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn,
+ &old_line);
+ yasm_linemap_set(parser_gas->linemap, filename, old_line,
+ 1);
+ } else if (parser_gas->dir_fileline == 2) {
+ /* Had previous line directive only */
+ parser_gas->dir_fileline = 3;
+ yasm_linemap_set(parser_gas->linemap, filename,
+ parser_gas->dir_line, 1);
+ } else {
+ /* Didn't see line yet, save file */
+ parser_gas->dir_fileline = 1;
+ if (parser_gas->dir_file)
+ yasm_xfree(parser_gas->dir_file);
+ parser_gas->dir_file = yasm__xstrdup(filename);
+ }
+
+ /* Pass change along to debug format */
+ yasm_vps_initialize(&vps);
+ vp = yasm_vp_create(filename, NULL);
+ yasm_vps_append(&vps, vp);
+
+ yasm_dbgfmt_directive(parser_gas->dbgfmt, "file",
+ parser_gas->cur_section, &vps, cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+
+ /* fileno filename form */
+ yasm_vps_initialize(&vps);
+
+ if (!expect(INTNUM)) return NULL;
+ vp = yasm_vp_create(NULL,
+ p_expr_new_ident(yasm_expr_int(INTNUM_val)));
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* INTNUM */
+
+ if (!expect(STRING)) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ vp = yasm_vp_create(STRING_val.contents, NULL);
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* STRING */
+
+ yasm_dbgfmt_directive(parser_gas->dbgfmt, "file",
+ parser_gas->cur_section, &vps, cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+ case DIR_LOC:
+ /* INTNUM INTNUM INTNUM */
+ get_next_token(); /* DIR_LOC */
+ yasm_vps_initialize(&vps);
+
+ if (!expect(INTNUM)) return NULL;
+ vp = yasm_vp_create(NULL,
+ p_expr_new_ident(yasm_expr_int(INTNUM_val)));
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* INTNUM */
+
+ if (!expect(INTNUM)) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ vp = yasm_vp_create(NULL,
+ p_expr_new_ident(yasm_expr_int(INTNUM_val)));
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* INTNUM */
+
+ if (!expect(INTNUM)) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ vp = yasm_vp_create(NULL,
+ p_expr_new_ident(yasm_expr_int(INTNUM_val)));
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* INTNUM */
+
+ yasm_dbgfmt_directive(parser_gas->dbgfmt, "loc",
+ parser_gas->cur_section, &vps, cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+ case DIR_TYPE:
+ /* ID ',' '@' ID */
+ get_next_token(); /* DIR_TYPE */
+ yasm_vps_initialize(&vps);
+
+ if (!expect(ID)) return NULL;
+ vp = yasm_vp_create(ID_val, NULL);
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* ID */
+
+ if (!expect(',')) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ get_next_token(); /* ',' */
+
+ if (!expect('@')) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ get_next_token(); /* '@' */
+
+ if (!expect(ID)) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ vp = yasm_vp_create(ID_val, NULL);
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* ID */
+
+ yasm_objfmt_directive(parser_gas->objfmt, "type", &vps, NULL,
+ cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+ case DIR_SIZE:
+ /* ID ',' expr */
+ get_next_token(); /* DIR_SIZE */
+ yasm_vps_initialize(&vps);
+
+ if (!expect(ID)) return NULL;
+ vp = yasm_vp_create(ID_val, NULL);
+ yasm_vps_append(&vps, vp);
+ get_next_token(); /* ID */
+
+ if (!expect(',')) {
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ get_next_token(); /* ',' */
+
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression expected for `.size'"));
+ yasm_vps_delete(&vps);
+ return NULL;
+ }
+ vp = yasm_vp_create(NULL, e);
+ yasm_vps_append(&vps, vp);
+
+ yasm_objfmt_directive(parser_gas->objfmt, "size", &vps, NULL,
+ cur_line);
+
+ yasm_vps_delete(&vps);
+ return NULL;
+ default:
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("label or instruction expected at start of line"));
+ return NULL;
+ }
+}
+
+static yasm_bytecode *
+parse_instr(yasm_parser_gas *parser_gas)
+{
+ yasm_bytecode *bc;
+
+ switch (curtok) {
+ case INSN:
+ {
+ yystype insn = curval; /* structure copy */
+ yasm_insn_operands operands;
+ int num_operands = 0;
+
+ get_next_token();
+ if (is_eol()) {
+ /* no operands */
+ return yasm_bc_create_insn(parser_gas->arch, insn.arch_data,
+ 0, NULL, cur_line);
+ }
+
+ /* parse operands */
+ yasm_ops_initialize(&operands);
+ for (;;) {
+ yasm_insn_operand *op = parse_operand(parser_gas);
+ if (!op) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression syntax error"));
+ yasm_ops_delete(&operands, 1);
+ return NULL;
+ }
+ yasm_ops_append(&operands, op);
+ num_operands++;
+
+ if (is_eol())
+ break;
+ if (!expect(',')) {
+ yasm_ops_delete(&operands, 1);
+ return NULL;
+ }
+ get_next_token();
+ }
+ return yasm_bc_create_insn(parser_gas->arch, insn.arch_data,
+ num_operands, &operands, cur_line);
+ }
+ case PREFIX:
+ {
+ yystype prefix = curval; /* structure copy */
+ get_next_token(); /* PREFIX */
+ bc = parse_instr(parser_gas);
+ if (!bc)
+ bc = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
+ yasm_bc_insn_add_prefix(bc, prefix.arch_data);
+ return bc;
+ }
+ case SEGREG:
+ {
+ unsigned long segreg = SEGREG_val[0];
+ get_next_token(); /* SEGREG */
+ bc = parse_instr(parser_gas);
+ if (!bc)
+ bc = yasm_bc_create_empty_insn(parser_gas->arch, cur_line);
+ yasm_bc_insn_add_seg_prefix(bc, segreg);
+ }
+ default:
+ return NULL;
+ }
+}
+
+static int
+parse_dirvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps)
+{
+ yasm_expr *e;
+ yasm_valparam *vp;
+ int num = 0;
+
+ yasm_vps_initialize(vps);
+
+ for (;;) {
+ e = parse_expr(parser_gas);
+ vp = yasm_vp_create(NULL, e);
+ yasm_vps_append(vps, vp);
+ num++;
+ if (curtok != ',')
+ break;
+ get_next_token(); /* ',' */
+ }
+ return num;
+}
+
+static int
+parse_dirstrvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps)
+{
+ char *s;
+ yasm_valparam *vp;
+ int num = 0;
+
+ yasm_vps_initialize(vps);
+
+ for (;;) {
+ if (!expect(STRING)) {
+ yasm_vps_delete(vps);
+ yasm_vps_initialize(vps);
+ return 0;
+ }
+ vp = yasm_vp_create(STRING_val.contents, NULL);
+ yasm_vps_append(vps, vp);
+ get_next_token(); /* STRING */
+ num++;
+ if (curtok != ',')
+ break;
+ get_next_token(); /* ',' */
+ }
+ return num;
+}
+
+static int
+parse_datavals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs)
+{
+ yasm_expr *e;
+ yasm_dataval *dv;
+ int num = 0;
+
+ yasm_dvs_initialize(dvs);
+
+ for (;;) {
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_dvs_delete(dvs);
+ yasm_dvs_initialize(dvs);
+ return 0;
+ }
+ dv = yasm_dv_create_expr(e);
+ yasm_dvs_append(dvs, dv);
+ num++;
+ if (curtok != ',')
+ break;
+ get_next_token(); /* ',' */
+ }
+ return num;
+}
+
+static int
+parse_strvals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs)
+{
+ char *s;
+ yasm_dataval *dv;
+ int num = 0;
+
+ yasm_dvs_initialize(dvs);
+
+ for (;;) {
+ if (!expect(STRING)) {
+ yasm_dvs_delete(dvs);
+ yasm_dvs_initialize(dvs);
+ return 0;
+ }
+ dv = yasm_dv_create_string(STRING_val.contents, STRING_val.len);
+ yasm_dvs_append(dvs, dv);
+ get_next_token(); /* STRING */
+ num++;
+ if (curtok != ',')
+ break;
+ get_next_token(); /* ',' */
+ }
+ return num;
+}
+
+/* instruction operands */
+/* memory addresses */
+static yasm_effaddr *
+parse_memaddr(yasm_parser_gas *parser_gas)
+{
+ yasm_effaddr *ea = NULL;
+ yasm_expr *e1, *e2;
+ int strong = 0;
+
+ if (curtok == SEGREG) {
+ unsigned long segreg = SEGREG_val[0];
+ get_next_token(); /* SEGREG */
+ if (!expect(':')) return NULL;
+ get_next_token(); /* ':' */
+ ea = parse_memaddr(parser_gas);
+ if (!ea)
+ return NULL;
+ yasm_ea_set_segreg(ea, segreg);
+ return ea;
+ }
+
+ /* We want to parse a leading expression, except when it's actually
+ * just a memory address (with no preceding expression) such as
+ * (REG...) or (,...).
+ */
+ get_peek_token(parser_gas);
+ if (curtok != '(' || (parser_gas->peek_token != REG
+ && parser_gas->peek_token != ','))
+ e1 = parse_expr(parser_gas);
+ else
+ e1 = NULL;
+
+ if (curtok == '(') {
+ unsigned long reg = ULONG_MAX;
+ yasm_intnum *scale = NULL;
+
+ get_next_token(); /* '(' */
+
+ /* base register */
+ if (curtok == REG) {
+ e2 = p_expr_new_ident(yasm_expr_reg(REG_val[0]));
+ get_next_token(); /* REG */
+ } else
+ e2 = p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)));
+
+ if (curtok == ')')
+ goto done;
+
+ if (!expect(',')) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid memory expression"));
+ if (e1) yasm_expr_destroy(e1);
+ yasm_expr_destroy(e2);
+ return NULL;
+ }
+ get_next_token(); /* ',' */
+
+ if (curtok == ')')
+ goto done;
+
+ /* index register */
+ if (curtok == REG) {
+ reg = REG_val[0];
+ get_next_token(); /* REG */
+ if (curtok != ',') {
+ scale = yasm_intnum_create_uint(1);
+ goto done;
+ }
+ get_next_token(); /* ',' */
+ }
+
+ /* scale */
+ if (!expect(INTNUM)) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("non-integer scale"));
+ if (e1) yasm_expr_destroy(e1);
+ yasm_expr_destroy(e2);
+ return NULL;
+ }
+ scale = INTNUM_val;
+ get_next_token(); /* INTNUM */
+
+done:
+ if (!expect(')')) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid memory expression"));
+ if (scale) yasm_intnum_destroy(scale);
+ if (e1) yasm_expr_destroy(e1);
+ yasm_expr_destroy(e2);
+ return NULL;
+ }
+ get_next_token(); /* ')' */
+
+ if (scale) {
+ if (reg == ULONG_MAX) {
+ if (yasm_intnum_get_uint(scale) != 1)
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("scale factor of %u without an index register"),
+ yasm_intnum_get_uint(scale));
+ yasm_intnum_destroy(scale);
+ } else
+ e2 = p_expr_new(yasm_expr_expr(e2), YASM_EXPR_ADD,
+ yasm_expr_expr(p_expr_new(yasm_expr_reg(reg), YASM_EXPR_MUL,
+ yasm_expr_int(scale))));
+ }
+
+ if (e1) {
+ /* Ordering is critical here to correctly detecting presence of
+ * RIP in RIP-relative expressions.
+ */
+ e1 = p_expr_new_tree(e2, YASM_EXPR_ADD, e1);
+ } else
+ e1 = e2;
+ strong = 1;
+ }
+
+ if (!e1)
+ return NULL;
+ ea = yasm_arch_ea_create(parser_gas->arch, e1);
+ if (strong)
+ yasm_ea_set_strong(ea, 1);
+ return ea;
+}
+
+static yasm_insn_operand *
+parse_operand(yasm_parser_gas *parser_gas)
+{
+ yasm_effaddr *ea;
+ yasm_insn_operand *op;
+ unsigned long reg;
+
+ switch (curtok) {
+ case REG:
+ reg = REG_val[0];
+ get_next_token(); /* REG */
+ return yasm_operand_create_reg(reg);
+ case SEGREG:
+ /* need to see if it's really a memory address */
+ get_peek_token(parser_gas);
+ if (parser_gas->peek_token == ':') {
+ ea = parse_memaddr(parser_gas);
+ if (!ea)
+ return NULL;
+ return yasm_operand_create_mem(ea);
+ }
+ reg = SEGREG_val[0];
+ get_next_token(); /* SEGREG */
+ return yasm_operand_create_segreg(reg);
+ case REGGROUP:
+ {
+ unsigned long regindex;
+ reg = REGGROUP_val[0];
+ get_next_token(); /* REGGROUP */
+ if (curtok != '(')
+ return yasm_operand_create_reg(reg);
+ get_next_token(); /* '(' */
+ if (!expect(INTNUM)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("integer register index expected"));
+ return NULL;
+ }
+ regindex = yasm_intnum_get_uint(INTNUM_val);
+ get_next_token(); /* INTNUM */
+ if (!expect(')')) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("missing closing parenthesis for register index"));
+ return NULL;
+ }
+ get_next_token(); /* ')' */
+ reg = yasm_arch_reggroup_get_reg(parser_gas->arch, reg, regindex);
+ if (reg == 0) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"),
+ regindex);
+ return NULL;
+ }
+ return yasm_operand_create_reg(reg);
+ }
+ case '$':
+ {
+ yasm_expr *e;
+ get_next_token(); /* '$' */
+ e = parse_expr(parser_gas);
+ if (!e) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression missing after `%s'"), "$");
+ return NULL;
+ }
+ return yasm_operand_create_imm(e);
+ }
+ case '*':
+ get_next_token(); /* '*' */
+ if (curtok == REG) {
+ op = yasm_operand_create_reg(REG_val[0]);
+ get_next_token(); /* REG */
+ } else {
+ ea = parse_memaddr(parser_gas);
+ if (!ea) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expression missing after `%s'"), "*");
+ return NULL;
+ }
+ op = yasm_operand_create_mem(ea);
+ }
+ op->deref = 1;
+ return op;
+ default:
+ ea = parse_memaddr(parser_gas);
+ if (!ea)
+ return NULL;
+ return yasm_operand_create_mem(ea);
+ }
+}
+
+/* Expression grammar parsed is:
+ *
+ * expr : expr0 [ {+,-} expr0...]
+ * expr0 : expr1 [ {|,^,&,!} expr1...]
+ * expr1 : expr2 [ {*,/,%,<<,>>} expr2...]
+ * expr2 : { ~,+,- } expr2
+ * | (expr)
+ * | symbol
+ * | number
+ */
+
+static yasm_expr *
+parse_expr(yasm_parser_gas *parser_gas)
+{
+ yasm_expr *e, *f;
+ e = parse_expr0(parser_gas);
+ if (!e)
+ return NULL;
+
+ while (curtok == '+' || curtok == '-') {
+ int op = curtok;
+ get_next_token();
+ f = parse_expr0(parser_gas);
+ if (!f) {
+ yasm_expr_destroy(e);
+ return NULL;
+ }
+
+ switch (op) {
+ case '+': e = p_expr_new_tree(e, YASM_EXPR_ADD, f); break;
+ case '-': e = p_expr_new_tree(e, YASM_EXPR_SUB, f); break;
+ }
+ }
+ return e;
+}
+
+static yasm_expr *
+parse_expr0(yasm_parser_gas *parser_gas)
+{
+ yasm_expr *e, *f;
+ e = parse_expr1(parser_gas);
+ if (!e)
+ return NULL;
+
+ while (curtok == '|' || curtok == '^' || curtok == '&' || curtok == '!') {
+ int op = curtok;
+ get_next_token();
+ f = parse_expr1(parser_gas);
+ if (!f) {
+ yasm_expr_destroy(e);
+ return NULL;
+ }
+
+ switch (op) {
+ case '|': e = p_expr_new_tree(e, YASM_EXPR_OR, f); break;
+ case '^': e = p_expr_new_tree(e, YASM_EXPR_XOR, f); break;
+ case '&': e = p_expr_new_tree(e, YASM_EXPR_AND, f); break;
+ case '!': e = p_expr_new_tree(e, YASM_EXPR_NOR, f); break;
+ }
+ }
+ return e;
+}
+
+static yasm_expr *
+parse_expr1(yasm_parser_gas *parser_gas)
+{
+ yasm_expr *e, *f;
+ e = parse_expr2(parser_gas);
+ if (!e)
+ return NULL;
+
+ while (curtok == '*' || curtok == '/' || curtok == '%' || curtok == LEFT_OP
+ || curtok == RIGHT_OP) {
+ int op = curtok;
+ get_next_token();
+ f = parse_expr2(parser_gas);
+ if (!f) {
+ yasm_expr_destroy(e);
+ return NULL;
+ }
+
+ switch (op) {
+ case '*': e = p_expr_new_tree(e, YASM_EXPR_MUL, f); break;
+ case '/': e = p_expr_new_tree(e, YASM_EXPR_DIV, f); break;
+ case '%': e = p_expr_new_tree(e, YASM_EXPR_MOD, f); break;
+ case LEFT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHL, f); break;
+ case RIGHT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHR, f); break;
+ }
+ }
+ return e;
+}
+
+static yasm_expr *
+parse_expr2(yasm_parser_gas *parser_gas)
+{
+ yasm_expr *e;
+ yasm_symrec *sym;
+
+ switch (curtok) {
+ case '+':
+ get_next_token();
+ return parse_expr2(parser_gas);
+ case '-':
+ get_next_token();
+ e = parse_expr2(parser_gas);
+ if (!e)
+ return NULL;
+ return p_expr_new_branch(YASM_EXPR_NEG, e);
+ case '~':
+ get_next_token();
+ e = parse_expr2(parser_gas);
+ if (!e)
+ return NULL;
+ return p_expr_new_branch(YASM_EXPR_NOT, e);
+ case '(':
+ get_next_token();
+ e = parse_expr(parser_gas);
+ if (!e)
+ return NULL;
+ if (!expect(')')) {
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("missing parenthesis"));
+ return NULL;
+ }
+ get_next_token();
+ return e;
+ case INTNUM:
+ e = p_expr_new_ident(yasm_expr_int(INTNUM_val));
+ get_next_token();
+ return e;
+ case FLTNUM:
+ e = p_expr_new_ident(yasm_expr_float(FLTNUM_val));
+ get_next_token();
+ return e;
+ case ID:
+ case DIR_SECTNAME:
+ {
+ char *name = ID_val;
+ get_next_token(); /* ID */
+ if (curtok == '@') {
+ /* TODO: this is needed for shared objects, e.g. sym@PLT */
+ get_next_token(); /* '@' */
+ if (!expect(ID)) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("expected identifier after `@'"));
+ yasm_xfree(name);
+ return NULL;
+ }
+ yasm_xfree(ID_val);
+ get_next_token(); /* ID */
+ sym = yasm_symtab_use(p_symtab, name, cur_line);
+ yasm_xfree(name);
+ return p_expr_new_ident(yasm_expr_sym(sym));
+ }
+
+ /* "." references the current assembly position */
+ if (name[1] == '\0' && name[0] == '.')
+ sym = yasm_symtab_define_curpos(p_symtab, ".",
+ parser_gas->prev_bc, cur_line);
+ else
+ sym = yasm_symtab_use(p_symtab, name, cur_line);
+ yasm_xfree(name);
+ return p_expr_new_ident(yasm_expr_sym(sym));
+ }
+ default:
+ return NULL;
+ }
+}
+
+static void
+define_label(yasm_parser_gas *parser_gas, char *name, int local)
+{
+ if (!local) {
+ if (parser_gas->locallabel_base)
+ yasm_xfree(parser_gas->locallabel_base);
+ parser_gas->locallabel_base_len = strlen(name);
+ parser_gas->locallabel_base =
+ yasm_xmalloc(parser_gas->locallabel_base_len+1);
+ strcpy(parser_gas->locallabel_base, name);
+ }
+
+ yasm_symtab_define_label(p_symtab, name, parser_gas->prev_bc, 1,
+ cur_line);
+ yasm_xfree(name);
+}
+
+static void
+define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
+ yasm_expr *size, /*@null@*/ yasm_expr *align)
+{
+ /* Put into .bss section. */
+ /*@dependent@*/ yasm_section *bss =
+ gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL, NULL, 1);
+
+ if (align) {
+ /* XXX: assume alignment is in bytes, not power-of-two */
+ yasm_section_bcs_append(bss, gas_parser_align(parser_gas, bss, align,
+ NULL, NULL, 0));
+ }
+
+ yasm_symtab_define_label(p_symtab, name, yasm_section_bcs_last(bss), 1,
+ cur_line);
+ yasm_section_bcs_append(bss, yasm_bc_create_reserve(size, 1, cur_line));
+ yasm_xfree(name);
+}
+
+static yasm_section *
+gas_get_section(yasm_parser_gas *parser_gas, char *name,
+ /*@null@*/ char *flags, /*@null@*/ char *type,
+ /*@null@*/ yasm_valparamhead *objext_valparams,
+ int builtin)
+{
+ yasm_valparamhead vps;
+ yasm_valparam *vp;
+ char *gasflags;
+ yasm_section *new_section;
+
+ yasm_vps_initialize(&vps);
+ vp = yasm_vp_create(name, NULL);
+ yasm_vps_append(&vps, vp);
+
+ if (!builtin) {
+ if (flags) {
+ gasflags = yasm_xmalloc(5+strlen(flags));
+ strcpy(gasflags, "gas_");
+ strcat(gasflags, flags);
+ } else
+ gasflags = yasm__xstrdup("gas_");
+ vp = yasm_vp_create(gasflags, NULL);
+ yasm_vps_append(&vps, vp);
+ if (type) {
+ vp = yasm_vp_create(type, NULL);
+ yasm_vps_append(&vps, vp);
+ }
+ }
+
+ new_section = yasm_objfmt_section_switch(parser_gas->objfmt, &vps,
+ objext_valparams, cur_line);
+
+ yasm_vps_delete(&vps);
+ return new_section;
+}
+
+static void
+gas_switch_section(yasm_parser_gas *parser_gas, char *name,
+ /*@null@*/ char *flags, /*@null@*/ char *type,
+ /*@null@*/ yasm_valparamhead *objext_valparams,
+ int builtin)
+{
+ yasm_section *new_section;
+
+ new_section = gas_get_section(parser_gas, yasm__xstrdup(name), flags, type,
+ objext_valparams, builtin);
+ if (new_section) {
+ parser_gas->cur_section = new_section;
+ parser_gas->prev_bc = yasm_section_bcs_last(new_section);
+ } else
+ yasm_error_set(YASM_ERROR_GENERAL, N_("invalid section name `%s'"),
+ name);
+
+ yasm_xfree(name);
+
+ if (objext_valparams)
+ yasm_vps_delete(objext_valparams);
+}
+
+static yasm_bytecode *
+gas_parser_align(yasm_parser_gas *parser_gas, yasm_section *sect,
+ yasm_expr *boundval, /*@null@*/ yasm_expr *fillval,
+ /*@null@*/ yasm_expr *maxskipval, int power2)
+{
+ yasm_intnum *boundintn;
+
+ /* Convert power of two to number of bytes if necessary */
+ if (power2)
+ boundval = yasm_expr_create(YASM_EXPR_SHL,
+ yasm_expr_int(yasm_intnum_create_uint(1)),
+ yasm_expr_expr(boundval), cur_line);
+
+ /* Largest .align in the section specifies section alignment. */
+ boundintn = yasm_expr_get_intnum(&boundval, 0);
+ if (boundintn) {
+ unsigned long boundint = yasm_intnum_get_uint(boundintn);
+
+ /* Alignments must be a power of two. */
+ if (is_exp2(boundint)) {
+ if (boundint > yasm_section_get_align(sect))
+ yasm_section_set_align(sect, boundint, cur_line);
+ }
+ }
+
+ return yasm_bc_create_align(boundval, fillval, maxskipval,
+ yasm_section_is_code(sect) ?
+ yasm_arch_get_fill(parser_gas->arch) : NULL,
+ cur_line);
+}
+
+static yasm_bytecode *
+gas_parser_dir_fill(yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat,
+ /*@only@*/ /*@null@*/ yasm_expr *size,
+ /*@only@*/ /*@null@*/ yasm_expr *value)
+{
+ yasm_datavalhead dvs;
+ yasm_bytecode *bc;
+ unsigned int ssize;
+
+ if (size) {
+ /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+ intn = yasm_expr_get_intnum(&size, 0);
+ if (!intn) {
+ yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
+ N_("size must be an absolute expression"));
+ yasm_expr_destroy(repeat);
+ yasm_expr_destroy(size);
+ if (value)
+ yasm_expr_destroy(value);
+ return NULL;
+ }
+ ssize = yasm_intnum_get_uint(intn);
+ } else
+ ssize = 1;
+
+ if (!value)
+ value = yasm_expr_create_ident(
+ yasm_expr_int(yasm_intnum_create_uint(0)), cur_line);
+
+ yasm_dvs_initialize(&dvs);
+ yasm_dvs_append(&dvs, yasm_dv_create_expr(value));
+ bc = yasm_bc_create_data(&dvs, ssize, 0, parser_gas->arch, cur_line);
+
+ yasm_bc_set_multiple(bc, repeat);
+
+ return bc;
+}
+
+static void
+gas_parser_directive(yasm_parser_gas *parser_gas, const char *name,
+ yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams)
+{
+ unsigned long line = cur_line;
+
+ /* Handle (mostly) output-format independent directives here */
+ if (!yasm_arch_parse_directive(parser_gas->arch, name, valparams,
+ objext_valparams, parser_gas->object, line)) {
+ ;
+ } else if (yasm_objfmt_directive(parser_gas->objfmt, name, valparams,
+ objext_valparams, line)) {
+ yasm_error_set(YASM_ERROR_GENERAL, N_("unrecognized directive [%s]"),
+ name);
+ }
+
+ yasm_vps_delete(valparams);
+ if (objext_valparams)
+ yasm_vps_delete(objext_valparams);
+}
parser_gas.save_input = save_input;
parser_gas.save_last = 0;
+ parser_gas.peek_token = NONE;
+
/* initialize scanner structure */
yasm_scanner_initialize(&parser_gas.s);
#ifndef YASM_GAS_PARSER_H
#define YASM_GAS_PARSER_H
-#include "gas-bison.h"
-
#define YYCTYPE unsigned char
#define MAX_SAVED_LINE_LEN 80
+enum tokentype {
+ INTNUM = 258,
+ FLTNUM,
+ STRING,
+ INSN,
+ PREFIX,
+ REG,
+ REGGROUP,
+ SEGREG,
+ TARGETMOD,
+ LEFT_OP,
+ RIGHT_OP,
+ ID,
+ LABEL,
+ LINE,
+ DIR_ALIGN,
+ DIR_ASCII,
+ DIR_COMM,
+ DIR_DATA,
+ DIR_ENDR,
+ DIR_EXTERN,
+ DIR_EQU,
+ DIR_FILE,
+ DIR_FILL,
+ DIR_GLOBAL,
+ DIR_IDENT,
+ DIR_LEB128,
+ DIR_LINE,
+ DIR_LOC,
+ DIR_LOCAL,
+ DIR_LCOMM,
+ DIR_ORG,
+ DIR_REPT,
+ DIR_SECTION,
+ DIR_SECTNAME,
+ DIR_SIZE,
+ DIR_SKIP,
+ DIR_TYPE,
+ DIR_WEAK,
+ DIR_ZERO,
+ NONE
+};
+
+typedef union {
+ unsigned int int_info;
+ char *str_val;
+ yasm_intnum *intn;
+ yasm_floatnum *flt;
+ unsigned long arch_data[4];
+ struct {
+ char *contents;
+ size_t len;
+ } str;
+} yystype;
+#define YYSTYPE yystype
+
typedef struct gas_rept_line {
STAILQ_ENTRY(gas_rept_line) link;
YYCTYPE *data; /* line characters */
INSTDIR
} state;
+ int token; /* enum tokentype or any character */
+ yystype tokval;
+ char tokch; /* first character of token */
+
+ /* one token of lookahead; used sparingly */
+ int peek_token; /* NONE if none */
+ yystype peek_tokval;
+ char peek_tokch;
+
/*@null@*/ gas_rept *rept;
} yasm_parser_gas;
/* shorter access names to commonly used parser_gas fields */
#define p_symtab (parser_gas->symtab)
+#define curtok (parser_gas->token)
+#define curval (parser_gas->tokval)
+
+#define INTNUM_val (curval.intn)
+#define FLTNUM_val (curval.flt)
+#define STRING_val (curval.str)
+#define INSN_val (curval.arch_data)
+#define PREFIX_val (curval.arch_data)
+#define REG_val (curval.arch_data)
+#define REGGROUP_val (curval.arch_data)
+#define SEGREG_val (curval.arch_data)
+#define TARGETMOD_val (curval.arch_data)
+#define ID_val (curval.str_val)
+#define LABEL_val (curval.str_val)
+#define DIR_ALIGN_val (curval.int_info)
+#define DIR_ASCII_val (curval.int_info)
+#define DIR_DATA_val (curval.int_info)
+#define DIR_LEB128_val (curval.int_info)
+#define DIR_SECTNAME_val (curval.str_val)
#define cur_line (yasm_linemap_get_current(parser_gas->linemap))
#define p_expr_new_branch(o,r) yasm_expr_create_branch(o,r,cur_line)
#define p_expr_new_ident(r) yasm_expr_create_ident(r,cur_line)
-int gas_parser_parse(void *parser_gas_arg);
+void gas_parser_parse(yasm_parser_gas *parser_gas);
void gas_parser_cleanup(yasm_parser_gas *parser_gas);
int gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas);
#include <libyasm.h>
#include "modules/parsers/gas/gas-parser.h"
-#include "modules/parsers/gas/gas-defs.h"
#define BSIZE 8192
#define YYMARKER (s->ptr)
#define YYFILL(n) {cursor = fill(parser_gas, cursor);}
-#define RETURN(i) {s->cur = cursor; return i;}
+#define RETURN(i) {s->cur = cursor; parser_gas->tokch = s->tok[0]; \
+ return i;}
#define SCANINIT() {s->tok = cursor;}
int linestart;
gas_rept_line *new_line;
+ /* Handle one token of lookahead */
+ if (parser_gas->peek_token != NONE) {
+ int tok = parser_gas->peek_token;
+ *lvalp = parser_gas->peek_tokval; /* structure copy */
+ parser_gas->tokch = parser_gas->peek_tokch;
+ parser_gas->peek_token = NONE;
+ return tok;
+ }
+
/* Catch EOF */
if (s->eof && cursor == s->eof)
return 0;
}
/* arch-independent directives */
- '.2byte' { parser_gas->state = INSTDIR; RETURN(DIR_2BYTE); }
- '.4byte' { parser_gas->state = INSTDIR; RETURN(DIR_4BYTE); }
- '.8byte' { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); }
- '.align' { parser_gas->state = INSTDIR; RETURN(DIR_ALIGN); }
- '.ascii' { parser_gas->state = INSTDIR; RETURN(DIR_ASCII); }
- '.asciz' { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); }
- '.balign' { parser_gas->state = INSTDIR; RETURN(DIR_BALIGN); }
- '.bss' { parser_gas->state = INSTDIR; RETURN(DIR_BSS); }
- '.byte' { parser_gas->state = INSTDIR; RETURN(DIR_BYTE); }
- '.comm' { parser_gas->state = INSTDIR; RETURN(DIR_COMM); }
- '.data' { parser_gas->state = INSTDIR; RETURN(DIR_DATA); }
- '.double' { parser_gas->state = INSTDIR; RETURN(DIR_DOUBLE); }
- '.endr' { parser_gas->state = INSTDIR; RETURN(DIR_ENDR); }
- '.equ' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
- '.extern' { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); }
- '.file' { parser_gas->state = INSTDIR; RETURN(DIR_FILE); }
- '.fill' { parser_gas->state = INSTDIR; RETURN(DIR_FILL); }
- '.float' { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); }
+ /* alignment directives */
+ '.align' {
+ /* FIXME: Whether this is power-of-two or not depends on arch and
+ * objfmt.
+ */
+ lvalp->int_info = 0;
+ parser_gas->state = INSTDIR; RETURN(DIR_ALIGN);
+ }
+ '.p2align' {
+ lvalp->int_info = 1;
+ parser_gas->state = INSTDIR; RETURN(DIR_ALIGN);
+ }
+ '.balign' {
+ lvalp->int_info = 0;
+ parser_gas->state = INSTDIR; RETURN(DIR_ALIGN);
+ }
+ '.org' { parser_gas->state = INSTDIR; RETURN(DIR_ORG); }
+ /* data visibility directives */
+ '.local' { parser_gas->state = INSTDIR; RETURN(DIR_LOCAL); }
'.global' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
'.globl' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
- '.hword' { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); }
- '.ident' { parser_gas->state = INSTDIR; RETURN(DIR_IDENT); }
- '.int' { parser_gas->state = INSTDIR; RETURN(DIR_INT); }
+ '.comm' { parser_gas->state = INSTDIR; RETURN(DIR_COMM); }
'.lcomm' { parser_gas->state = INSTDIR; RETURN(DIR_LCOMM); }
- '.line' { parser_gas->state = INSTDIR; RETURN(DIR_LINE); }
- '.loc' { parser_gas->state = INSTDIR; RETURN(DIR_LOC); }
- '.local' { parser_gas->state = INSTDIR; RETURN(DIR_LOCAL); }
- '.long' { parser_gas->state = INSTDIR; RETURN(DIR_INT); }
- '.octa' { parser_gas->state = INSTDIR; RETURN(DIR_OCTA); }
- '.org' { parser_gas->state = INSTDIR; RETURN(DIR_ORG); }
- '.p2align' { parser_gas->state = INSTDIR; RETURN(DIR_P2ALIGN); }
- '.rept' { parser_gas->state = INSTDIR; RETURN(DIR_REPT); }
+ '.extern' { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); }
+ '.weak' { parser_gas->state = INSTDIR; RETURN(DIR_WEAK); }
+ /* integer data declaration directives */
+ '.byte' {
+ lvalp->int_info = 1;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.2byte' {
+ lvalp->int_info = 2;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.4byte' {
+ lvalp->int_info = 4;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.8byte' {
+ lvalp->int_info = 8;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.16byte' {
+ lvalp->int_info = 16;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.short' {
+ lvalp->int_info = 2; /* TODO: This should depend on arch */
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.int' {
+ lvalp->int_info = 4; /* TODO: This should depend on arch */
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.long' {
+ lvalp->int_info = 4; /* TODO: This should depend on arch */
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.hword' {
+ lvalp->int_info = 2; /* TODO: This should depend on arch */
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.word' {
+ lvalp->int_info = yasm_arch_wordsize(parser_gas->arch)/8;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.quad' {
+ lvalp->int_info = 8;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.octa' {
+ lvalp->int_info = 16;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.value' {
+ lvalp->int_info = 2; /* XXX: At least on x86, this is 2 bytes */
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ /* ASCII data declaration directives */
+ '.ascii' {
+ lvalp->int_info = 0; /* do not add terminating zero */
+ parser_gas->state = INSTDIR; RETURN(DIR_ASCII);
+ }
+ '.asciz' {
+ lvalp->int_info = 1; /* add terminating zero */
+ parser_gas->state = INSTDIR; RETURN(DIR_ASCII);
+ }
+ '.string' {
+ lvalp->int_info = 1; /* add terminating zero */
+ parser_gas->state = INSTDIR; RETURN(DIR_ASCII);
+ }
+ /* LEB128 integer data declaration directives */
+ '.sleb128' {
+ lvalp->int_info = 1; /* signed */
+ parser_gas->state = INSTDIR; RETURN(DIR_LEB128);
+ }
+ '.uleb128' {
+ lvalp->int_info = 0; /* unsigned */
+ parser_gas->state = INSTDIR; RETURN(DIR_LEB128);
+ }
+ /* floating point data declaration directives */
+ '.float' {
+ lvalp->int_info = 4;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.single' {
+ lvalp->int_info = 4;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.double' {
+ lvalp->int_info = 8;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ '.tfloat' {
+ lvalp->int_info = 10;
+ parser_gas->state = INSTDIR; RETURN(DIR_DATA);
+ }
+ /* section directives */
+ '.bss' {
+ lvalp->str_val = yasm__xstrdup(".bss");
+ RETURN(DIR_SECTNAME);
+ }
+ '.data' {
+ lvalp->str_val = yasm__xstrdup(".data");
+ RETURN(DIR_SECTNAME);
+ }
+ '.text' {
+ lvalp->str_val = yasm__xstrdup(".text");
+ RETURN(DIR_SECTNAME);
+ }
'.section' {
parser_gas->state = SECTION_DIRECTIVE;
RETURN(DIR_SECTION);
}
- '.set' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
- '.short' { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); }
- '.single' { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); }
- '.size' { parser_gas->state = INSTDIR; RETURN(DIR_SIZE); }
+ /* macro directives */
+ '.rept' { parser_gas->state = INSTDIR; RETURN(DIR_REPT); }
+ '.endr' { parser_gas->state = INSTDIR; RETURN(DIR_ENDR); }
+ /* empty space/fill directives */
'.skip' { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); }
- '.sleb128' { parser_gas->state = INSTDIR; RETURN(DIR_SLEB128); }
'.space' { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); }
- '.string' { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); }
- '.text' { parser_gas->state = INSTDIR; RETURN(DIR_TEXT); }
- '.tfloat' { parser_gas->state = INSTDIR; RETURN(DIR_TFLOAT); }
- '.type' { parser_gas->state = INSTDIR; RETURN(DIR_TYPE); }
- '.quad' { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); }
- '.uleb128' { parser_gas->state = INSTDIR; RETURN(DIR_ULEB128); }
- '.value' { parser_gas->state = INSTDIR; RETURN(DIR_VALUE); }
- '.weak' { parser_gas->state = INSTDIR; RETURN(DIR_WEAK); }
- '.word' { parser_gas->state = INSTDIR; RETURN(DIR_WORD); }
+ '.fill' { parser_gas->state = INSTDIR; RETURN(DIR_FILL); }
'.zero' { parser_gas->state = INSTDIR; RETURN(DIR_ZERO); }
-
- /* label or maybe directive */
- [.][a-zA-Z0-9_$.]* {
- lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
- RETURN(DIR_ID);
+ /* other directives */
+ '.code16' {
+ yasm_arch_set_var(parser_gas->arch, "mode_bits", 16);
+ goto scan;
+ }
+ '.code32' {
+ yasm_arch_set_var(parser_gas->arch, "mode_bits", 32);
+ goto scan;
}
+ '.code64' {
+ yasm_arch_set_var(parser_gas->arch, "mode_bits", 64);
+ goto scan;
+ }
+ '.equ' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
+ '.file' { parser_gas->state = INSTDIR; RETURN(DIR_FILE); }
+ '.ident' { parser_gas->state = INSTDIR; RETURN(DIR_IDENT); }
+ '.line' { parser_gas->state = INSTDIR; RETURN(DIR_LINE); }
+ '.loc' { parser_gas->state = INSTDIR; RETURN(DIR_LOC); }
+ '.set' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
+ '.size' { parser_gas->state = INSTDIR; RETURN(DIR_SIZE); }
+ '.type' { parser_gas->state = INSTDIR; RETURN(DIR_TYPE); }
- /* label */
- [_][a-zA-Z0-9_$.]* {
+ /* label or maybe directive */
+ [_.][a-zA-Z0-9_$.]* {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
RETURN(ID);
}
frontends/yasm/yasm-options.c
frontends/yasm/yasm.c
-gas-bison.c
gas-token.c
#lc3bid.c
libyasm/bc-align.c
modules/objfmts/elf/elf.c
modules/objfmts/rdf/rdf-objfmt.c
modules/objfmts/xdf/xdf-objfmt.c
+modules/parsers/gas/gas-parse.c
modules/parsers/gas/gas-parser.c
modules/parsers/nasm/nasm-parse.c
modules/preprocs/nasm/nasm-pp.c