AM_YFLAGS = -d
AM_CFLAGS = @MORE_CFLAGS@
AM_CPPFLAGS = \
- -I$(top_srcdir)/src \
+ -I$(top_srcdir)/libyasm \
-I$(top_srcdir)/check \
@INCLTDL@
EXTRA_DIST = config/config.rpath \
check/Makefile.inc \
tools/Makefile.inc \
- src/Makefile.inc
+ libyasm/Makefile.inc \
+ modules/Makefile.inc \
+ frontends/Makefile.inc
include check/Makefile.inc
include tools/Makefile.inc
-include src/Makefile.inc
+include libyasm/Makefile.inc
+include modules/Makefile.inc
+include frontends/Makefile.inc
EXTRA_DIST += \
out_test.sh \
#
AC_PREREQ(2.50)
AC_INIT([yasm], `date "+%Y%m%d"`, [bug-yasm@tortall.net])
-AC_CONFIG_SRCDIR([src/main.c])
+#AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_AUX_DIR(config)
AM_CONFIG_HEADER([config.h])
--- /dev/null
+# $IdPath$
+
+EXTRA_DIST += \
+ frontends/yasm/Makefile.inc
+
+include frontends/yasm/Makefile.inc
# $IdPath$
-libyasm_la_SOURCES = \
- src/bytecode.c \
- src/bytecode.h \
- src/bc-int.h \
- src/errwarn.h \
- src/expr.c \
- src/expr.h \
- src/expr-int.h \
- src/symrec.c \
- src/symrec.h \
- src/linemgr.h \
- src/util.h \
- src/coretype.h \
- src/file.c \
- src/file.h \
- src/section.c \
- src/section.h \
- src/arch.c \
- src/arch.h \
- src/dbgfmt.h \
- src/objfmt.h \
- src/optimizer.h \
- src/parser.h \
- src/preproc.h \
- src/intnum.c \
- src/intnum.h \
- src/floatnum.c \
- src/floatnum.h \
- src/hamt.c \
- src/hamt.h \
- src/bitvect.c \
- src/bitvect.h \
- src/valparam.c \
- src/valparam.h \
- src/errwarn.c \
- src/linemgr.c \
- src/xmalloc.c \
- src/xstrdup.c \
- src/strcasecmp.c
-libyasm_la_LDFLAGS = -no-undefined
-
yasm_SOURCES += \
- src/main.c \
- src/options.c \
- src/options.h \
- src/module.h \
- src/module.c
-
-
-EXTRA_DIST += \
- src/arch/Makefile.inc \
- src/parsers/Makefile.inc \
- src/preprocs/Makefile.inc \
- src/optimizers/Makefile.inc \
- src/objfmts/Makefile.inc \
- src/tests/Makefile.inc
-
-# Modules with more than one type of interface
-
-lib_LTLIBRARIES += yasm-nasm.la
-yasm_nasm_la_SOURCES =
-yasm_nasm_la_LDFLAGS = -module -avoid-version
-yasm_nasm_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-nasm.la
-
-include src/arch/Makefile.inc
-include src/parsers/Makefile.inc
-include src/preprocs/Makefile.inc
-include src/optimizers/Makefile.inc
-include src/dbgfmts/Makefile.inc
-include src/objfmts/Makefile.inc
-include src/tests/Makefile.inc
-
-EXTRA_yasm_SOURCES += \
- src/compat-queue.h
+ frontends/yasm/yasm.c \
+ frontends/yasm/yasm-options.c \
+ frontends/yasm/yasm-options.h \
+ frontends/yasm/yasm-module.h \
+ frontends/yasm/yasm-module.c
#include "ltdl.h"
-#include "module.h"
+#include "yasm-module.h"
#include "objfmt.h"
#include "parser.h"
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
-#include "options.h"
+#include "yasm-options.h"
#include "errwarn.h"
/*@unused@*/ RCSID("$IdPath$");
#include "ltdl.h"
-#include "module.h"
+#include "yasm-module.h"
#include "bitvect.h"
#include "file.h"
-#include "options.h"
+#include "yasm-options.h"
#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
# $IdPath$
libyasm_la_SOURCES = \
- src/bytecode.c \
- src/bytecode.h \
- src/bc-int.h \
- src/errwarn.h \
- src/expr.c \
- src/expr.h \
- src/expr-int.h \
- src/symrec.c \
- src/symrec.h \
- src/linemgr.h \
- src/util.h \
- src/coretype.h \
- src/file.c \
- src/file.h \
- src/section.c \
- src/section.h \
- src/arch.c \
- src/arch.h \
- src/dbgfmt.h \
- src/objfmt.h \
- src/optimizer.h \
- src/parser.h \
- src/preproc.h \
- src/intnum.c \
- src/intnum.h \
- src/floatnum.c \
- src/floatnum.h \
- src/hamt.c \
- src/hamt.h \
- src/bitvect.c \
- src/bitvect.h \
- src/valparam.c \
- src/valparam.h \
- src/errwarn.c \
- src/linemgr.c \
- src/xmalloc.c \
- src/xstrdup.c \
- src/strcasecmp.c
+ libyasm/bytecode.c \
+ libyasm/bytecode.h \
+ libyasm/bc-int.h \
+ libyasm/errwarn.h \
+ libyasm/expr.c \
+ libyasm/expr.h \
+ libyasm/expr-int.h \
+ libyasm/symrec.c \
+ libyasm/symrec.h \
+ libyasm/linemgr.h \
+ libyasm/util.h \
+ libyasm/coretype.h \
+ libyasm/file.c \
+ libyasm/file.h \
+ libyasm/section.c \
+ libyasm/section.h \
+ libyasm/arch.c \
+ libyasm/arch.h \
+ libyasm/dbgfmt.h \
+ libyasm/objfmt.h \
+ libyasm/optimizer.h \
+ libyasm/parser.h \
+ libyasm/preproc.h \
+ libyasm/intnum.c \
+ libyasm/intnum.h \
+ libyasm/floatnum.c \
+ libyasm/floatnum.h \
+ libyasm/hamt.c \
+ libyasm/hamt.h \
+ libyasm/bitvect.c \
+ libyasm/bitvect.h \
+ libyasm/valparam.c \
+ libyasm/valparam.h \
+ libyasm/errwarn.c \
+ libyasm/linemgr.c \
+ libyasm/xmalloc.c \
+ libyasm/xstrdup.c \
+ libyasm/strcasecmp.c
libyasm_la_LDFLAGS = -no-undefined
-yasm_SOURCES += \
- src/main.c \
- src/options.c \
- src/options.h \
- src/module.h \
- src/module.c
-
-
EXTRA_DIST += \
- src/arch/Makefile.inc \
- src/parsers/Makefile.inc \
- src/preprocs/Makefile.inc \
- src/optimizers/Makefile.inc \
- src/objfmts/Makefile.inc \
- src/tests/Makefile.inc
-
-# Modules with more than one type of interface
-
-lib_LTLIBRARIES += yasm-nasm.la
-yasm_nasm_la_SOURCES =
-yasm_nasm_la_LDFLAGS = -module -avoid-version
-yasm_nasm_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-nasm.la
+ libyasm/tests/Makefile.inc
-include src/arch/Makefile.inc
-include src/parsers/Makefile.inc
-include src/preprocs/Makefile.inc
-include src/optimizers/Makefile.inc
-include src/dbgfmts/Makefile.inc
-include src/objfmts/Makefile.inc
-include src/tests/Makefile.inc
+include libyasm/tests/Makefile.inc
-EXTRA_yasm_SOURCES += \
- src/compat-queue.h
+EXTRA_libyasm_la_SOURCES = \
+ libyasm/compat-queue.h
bitvect_test_CFLAGS =
bitvect_test_SOURCES = \
- src/tests/bitvect_test.c \
+ libyasm/tests/bitvect_test.c \
$(CHECKFILES)
bitvect_test_LDFLAGS =
bitvect_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
floatnum_test_CFLAGS =
floatnum_test_SOURCES = \
- src/tests/floatnum_test.c \
+ libyasm/tests/floatnum_test.c \
$(CHECKFILES)
floatnum_test_LDFLAGS =
floatnum_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
# $IdPath$
-libyasm_la_SOURCES = \
- src/bytecode.c \
- src/bytecode.h \
- src/bc-int.h \
- src/errwarn.h \
- src/expr.c \
- src/expr.h \
- src/expr-int.h \
- src/symrec.c \
- src/symrec.h \
- src/linemgr.h \
- src/util.h \
- src/coretype.h \
- src/file.c \
- src/file.h \
- src/section.c \
- src/section.h \
- src/arch.c \
- src/arch.h \
- src/dbgfmt.h \
- src/objfmt.h \
- src/optimizer.h \
- src/parser.h \
- src/preproc.h \
- src/intnum.c \
- src/intnum.h \
- src/floatnum.c \
- src/floatnum.h \
- src/hamt.c \
- src/hamt.h \
- src/bitvect.c \
- src/bitvect.h \
- src/valparam.c \
- src/valparam.h \
- src/errwarn.c \
- src/linemgr.c \
- src/xmalloc.c \
- src/xstrdup.c \
- src/strcasecmp.c
-libyasm_la_LDFLAGS = -no-undefined
-
-yasm_SOURCES += \
- src/main.c \
- src/options.c \
- src/options.h \
- src/module.h \
- src/module.c
-
-
EXTRA_DIST += \
- src/arch/Makefile.inc \
- src/parsers/Makefile.inc \
- src/preprocs/Makefile.inc \
- src/optimizers/Makefile.inc \
- src/objfmts/Makefile.inc \
- src/tests/Makefile.inc
+ modules/arch/Makefile.inc \
+ modules/parsers/Makefile.inc \
+ modules/preprocs/Makefile.inc \
+ modules/optimizers/Makefile.inc \
+ modules/objfmts/Makefile.inc
# Modules with more than one type of interface
yasm_nasm_la_LIBADD = libyasm.la
yasm_LDADD += -dlopen yasm-nasm.la
-include src/arch/Makefile.inc
-include src/parsers/Makefile.inc
-include src/preprocs/Makefile.inc
-include src/optimizers/Makefile.inc
-include src/dbgfmts/Makefile.inc
-include src/objfmts/Makefile.inc
-include src/tests/Makefile.inc
-
-EXTRA_yasm_SOURCES += \
- src/compat-queue.h
+include modules/arch/Makefile.inc
+include modules/parsers/Makefile.inc
+include modules/preprocs/Makefile.inc
+include modules/optimizers/Makefile.inc
+include modules/dbgfmts/Makefile.inc
+include modules/objfmts/Makefile.inc
# $IdPath$
EXTRA_DIST += \
- src/arch/x86/Makefile.inc
+ modules/arch/x86/Makefile.inc
-include src/arch/x86/Makefile.inc
+include modules/arch/x86/Makefile.inc
lib_LTLIBRARIES += yasm-x86.la
yasm_x86_la_SOURCES = \
- src/arch/x86/x86arch.c \
- src/arch/x86/x86arch.h \
- src/arch/x86/x86bc.c \
- src/arch/x86/x86expr.c \
+ modules/arch/x86/x86arch.c \
+ modules/arch/x86/x86arch.h \
+ modules/arch/x86/x86bc.c \
+ modules/arch/x86/x86expr.c \
x86id.c
yasm_x86_la_LDFLAGS = -module -avoid-version
yasm_x86_la_LIBADD = libyasm.la
yasm_LDADD += -dlpreopen yasm-x86.la
-x86id.c: $(srcdir)/src/arch/x86/x86id.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
- $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/src/arch/x86/x86id.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
+x86id.c: $(srcdir)/modules/arch/x86/x86id.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
+ $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/modules/arch/x86/x86id.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
BUILT_SOURCES += \
x86id.c
x86id.c
EXTRA_DIST += \
- src/arch/x86/tests/Makefile.inc \
- src/arch/x86/README \
- src/arch/x86/x86id.re
+ modules/arch/x86/tests/Makefile.inc \
+ modules/arch/x86/README \
+ modules/arch/x86/x86id.re
-include src/arch/x86/tests/Makefile.inc
+include modules/arch/x86/tests/Makefile.inc
# $IdPath$
TESTS += \
- src/arch/x86/tests/x86_test.sh
+ modules/arch/x86/tests/x86_test.sh
EXTRA_DIST += \
- src/arch/x86/tests/x86_test.sh \
- src/arch/x86/tests/addbyte.asm \
- src/arch/x86/tests/addbyte.errwarn \
- src/arch/x86/tests/addbyte.hex \
- src/arch/x86/tests/addrop.asm \
- src/arch/x86/tests/addrop.errwarn \
- src/arch/x86/tests/addrop.hex \
- src/arch/x86/tests/addrop-err.asm \
- src/arch/x86/tests/addrop-err.errwarn \
- src/arch/x86/tests/cpubasic-err.asm \
- src/arch/x86/tests/cpubasic-err.errwarn \
- src/arch/x86/tests/div-err.asm \
- src/arch/x86/tests/div-err.errwarn \
- src/arch/x86/tests/effaddr.asm \
- src/arch/x86/tests/effaddr.errwarn \
- src/arch/x86/tests/effaddr.hex \
- src/arch/x86/tests/genopcode.asm \
- src/arch/x86/tests/genopcode.errwarn \
- src/arch/x86/tests/genopcode.hex \
- src/arch/x86/tests/lds-err.asm \
- src/arch/x86/tests/lds-err.errwarn \
- src/arch/x86/tests/loopadsz.asm \
- src/arch/x86/tests/loopadsz.errwarn \
- src/arch/x86/tests/loopadsz.hex \
- src/arch/x86/tests/mem64-err.asm \
- src/arch/x86/tests/mem64-err.errwarn \
- src/arch/x86/tests/mem64.asm \
- src/arch/x86/tests/mem64.errwarn \
- src/arch/x86/tests/mem64.hex \
- src/arch/x86/tests/negequ.asm \
- src/arch/x86/tests/negequ.errwarn \
- src/arch/x86/tests/negequ.hex \
- src/arch/x86/tests/nomem64-err.asm \
- src/arch/x86/tests/nomem64-err.errwarn \
- src/arch/x86/tests/nomem64.asm \
- src/arch/x86/tests/nomem64.errwarn \
- src/arch/x86/tests/nomem64.hex \
- src/arch/x86/tests/opersize.asm \
- src/arch/x86/tests/opersize.errwarn \
- src/arch/x86/tests/opersize.hex \
- src/arch/x86/tests/opsize-err.asm \
- src/arch/x86/tests/opsize-err.errwarn \
- src/arch/x86/tests/ret.asm \
- src/arch/x86/tests/ret.errwarn \
- src/arch/x86/tests/ret.hex \
- src/arch/x86/tests/segmov.asm \
- src/arch/x86/tests/segmov.errwarn \
- src/arch/x86/tests/segmov.hex \
- src/arch/x86/tests/shift.asm \
- src/arch/x86/tests/shift.errwarn \
- src/arch/x86/tests/shift.hex \
- src/arch/x86/tests/x86label.asm \
- src/arch/x86/tests/x86label.errwarn \
- src/arch/x86/tests/x86label.hex
+ modules/arch/x86/tests/x86_test.sh \
+ modules/arch/x86/tests/addbyte.asm \
+ modules/arch/x86/tests/addbyte.errwarn \
+ modules/arch/x86/tests/addbyte.hex \
+ modules/arch/x86/tests/addrop.asm \
+ modules/arch/x86/tests/addrop.errwarn \
+ modules/arch/x86/tests/addrop.hex \
+ modules/arch/x86/tests/addrop-err.asm \
+ modules/arch/x86/tests/addrop-err.errwarn \
+ modules/arch/x86/tests/cpubasic-err.asm \
+ modules/arch/x86/tests/cpubasic-err.errwarn \
+ modules/arch/x86/tests/div-err.asm \
+ modules/arch/x86/tests/div-err.errwarn \
+ modules/arch/x86/tests/effaddr.asm \
+ modules/arch/x86/tests/effaddr.errwarn \
+ modules/arch/x86/tests/effaddr.hex \
+ modules/arch/x86/tests/genopcode.asm \
+ modules/arch/x86/tests/genopcode.errwarn \
+ modules/arch/x86/tests/genopcode.hex \
+ modules/arch/x86/tests/lds-err.asm \
+ modules/arch/x86/tests/lds-err.errwarn \
+ modules/arch/x86/tests/loopadsz.asm \
+ modules/arch/x86/tests/loopadsz.errwarn \
+ modules/arch/x86/tests/loopadsz.hex \
+ modules/arch/x86/tests/mem64-err.asm \
+ modules/arch/x86/tests/mem64-err.errwarn \
+ modules/arch/x86/tests/mem64.asm \
+ modules/arch/x86/tests/mem64.errwarn \
+ modules/arch/x86/tests/mem64.hex \
+ modules/arch/x86/tests/negequ.asm \
+ modules/arch/x86/tests/negequ.errwarn \
+ modules/arch/x86/tests/negequ.hex \
+ modules/arch/x86/tests/nomem64-err.asm \
+ modules/arch/x86/tests/nomem64-err.errwarn \
+ modules/arch/x86/tests/nomem64.asm \
+ modules/arch/x86/tests/nomem64.errwarn \
+ modules/arch/x86/tests/nomem64.hex \
+ modules/arch/x86/tests/opersize.asm \
+ modules/arch/x86/tests/opersize.errwarn \
+ modules/arch/x86/tests/opersize.hex \
+ modules/arch/x86/tests/opsize-err.asm \
+ modules/arch/x86/tests/opsize-err.errwarn \
+ modules/arch/x86/tests/ret.asm \
+ modules/arch/x86/tests/ret.errwarn \
+ modules/arch/x86/tests/ret.hex \
+ modules/arch/x86/tests/segmov.asm \
+ modules/arch/x86/tests/segmov.errwarn \
+ modules/arch/x86/tests/segmov.hex \
+ modules/arch/x86/tests/shift.asm \
+ modules/arch/x86/tests/shift.errwarn \
+ modules/arch/x86/tests/shift.hex \
+ modules/arch/x86/tests/x86label.asm \
+ modules/arch/x86/tests/x86label.errwarn \
+ modules/arch/x86/tests/x86label.hex
#! /bin/sh
# $IdPath$
-${srcdir}/out_test.sh x86_test src/arch/x86/tests "x86 arch" "-f bin" ""
+${srcdir}/out_test.sh x86_test modules/arch/x86/tests "x86 arch" "-f bin" ""
exit $?
#include "bytecode.h"
#include "arch.h"
-#include "src/arch/x86/x86arch.h"
+#include "modules/arch/x86/x86arch.h"
#include "expr-int.h"
#include "bc-int.h"
# $IdPath$
EXTRA_DIST += \
- src/dbgfmts/null/Makefile.inc
+ modules/dbgfmts/null/Makefile.inc
-include src/dbgfmts/null/Makefile.inc
+include modules/dbgfmts/null/Makefile.inc
lib_LTLIBRARIES += yasm-null.la
yasm_null_la_SOURCES = \
- src/dbgfmts/null/null-dbgfmt.c
+ modules/dbgfmts/null/null-dbgfmt.c
yasm_null_la_LDFLAGS = -module -avoid-version
yasm_null_la_LIBADD = libyasm.la
yasm_LDADD += -dlpreopen yasm-null.la
# $IdPath$
EXTRA_DIST += \
- src/objfmts/dbg/Makefile.inc \
- src/objfmts/bin/Makefile.inc \
- src/objfmts/coff/Makefile.inc
+ modules/objfmts/dbg/Makefile.inc \
+ modules/objfmts/bin/Makefile.inc \
+ modules/objfmts/coff/Makefile.inc
-include src/objfmts/dbg/Makefile.inc
-include src/objfmts/bin/Makefile.inc
-include src/objfmts/coff/Makefile.inc
+include modules/objfmts/dbg/Makefile.inc
+include modules/objfmts/bin/Makefile.inc
+include modules/objfmts/coff/Makefile.inc
lib_LTLIBRARIES += yasm-bin.la
yasm_bin_la_SOURCES = \
- src/objfmts/bin/bin-objfmt.c
+ modules/objfmts/bin/bin-objfmt.c
yasm_bin_la_LDFLAGS = -module -avoid-version
yasm_bin_la_LIBADD = libyasm.la
yasm_LDADD += -dlopen yasm-bin.la
EXTRA_DIST += \
- src/objfmts/bin/tests/Makefile.inc
+ modules/objfmts/bin/tests/Makefile.inc
-include src/objfmts/bin/tests/Makefile.inc
+include modules/objfmts/bin/tests/Makefile.inc
# $IdPath$
TESTS += \
- src/objfmts/bin/tests/bin_test.sh
+ modules/objfmts/bin/tests/bin_test.sh
EXTRA_DIST += \
- src/objfmts/bin/tests/bin_test.sh \
- src/objfmts/bin/tests/abs.asm \
- src/objfmts/bin/tests/abs.hex \
- src/objfmts/bin/tests/abs.errwarn \
- src/objfmts/bin/tests/bintest.asm \
- src/objfmts/bin/tests/bintest.hex \
- src/objfmts/bin/tests/bintest.errwarn \
- src/objfmts/bin/tests/float-err.asm \
- src/objfmts/bin/tests/float-err.errwarn \
- src/objfmts/bin/tests/float.asm \
- src/objfmts/bin/tests/float.hex \
- src/objfmts/bin/tests/float.errwarn \
- src/objfmts/bin/tests/integer-warn.asm \
- src/objfmts/bin/tests/integer-warn.hex \
- src/objfmts/bin/tests/integer-warn.errwarn \
- src/objfmts/bin/tests/integer.asm \
- src/objfmts/bin/tests/integer.hex \
- src/objfmts/bin/tests/integer.errwarn \
- src/objfmts/bin/tests/reserve.asm \
- src/objfmts/bin/tests/reserve.hex \
- src/objfmts/bin/tests/reserve.errwarn \
- src/objfmts/bin/tests/reserve-err.asm \
- src/objfmts/bin/tests/reserve-err.errwarn
+ modules/objfmts/bin/tests/bin_test.sh \
+ modules/objfmts/bin/tests/abs.asm \
+ modules/objfmts/bin/tests/abs.hex \
+ modules/objfmts/bin/tests/abs.errwarn \
+ modules/objfmts/bin/tests/bintest.asm \
+ modules/objfmts/bin/tests/bintest.hex \
+ modules/objfmts/bin/tests/bintest.errwarn \
+ modules/objfmts/bin/tests/float-err.asm \
+ modules/objfmts/bin/tests/float-err.errwarn \
+ modules/objfmts/bin/tests/float.asm \
+ modules/objfmts/bin/tests/float.hex \
+ modules/objfmts/bin/tests/float.errwarn \
+ modules/objfmts/bin/tests/integer-warn.asm \
+ modules/objfmts/bin/tests/integer-warn.hex \
+ modules/objfmts/bin/tests/integer-warn.errwarn \
+ modules/objfmts/bin/tests/integer.asm \
+ modules/objfmts/bin/tests/integer.hex \
+ modules/objfmts/bin/tests/integer.errwarn \
+ modules/objfmts/bin/tests/reserve.asm \
+ modules/objfmts/bin/tests/reserve.hex \
+ modules/objfmts/bin/tests/reserve.errwarn \
+ modules/objfmts/bin/tests/reserve-err.asm \
+ modules/objfmts/bin/tests/reserve-err.errwarn
#! /bin/sh
# $IdPath$
-${srcdir}/out_test.sh bin_test src/objfmts/bin/tests "bin objfmt" "-f bin" ""
+${srcdir}/out_test.sh bin_test modules/objfmts/bin/tests "bin objfmt" "-f bin" ""
exit $?
lib_LTLIBRARIES += yasm-coff.la
yasm_coff_la_SOURCES = \
- src/objfmts/coff/coff-objfmt.c
+ modules/objfmts/coff/coff-objfmt.c
yasm_coff_la_LDFLAGS = -module -avoid-version
yasm_coff_la_LIBADD = libyasm.la
yasm_LDADD += -dlopen yasm-coff.la
EXTRA_DIST += \
- src/objfmts/coff/tests/Makefile.inc
+ modules/objfmts/coff/tests/Makefile.inc
-include src/objfmts/coff/tests/Makefile.inc
+include modules/objfmts/coff/tests/Makefile.inc
# $IdPath$
TESTS += \
- src/objfmts/coff/tests/coff_test.sh
+ modules/objfmts/coff/tests/coff_test.sh
EXTRA_DIST += \
- src/objfmts/coff/tests/coff_test.sh \
- src/objfmts/coff/tests/cofftest.c \
- src/objfmts/coff/tests/cofftest.asm \
- src/objfmts/coff/tests/cofftest.hex \
- src/objfmts/coff/tests/cofftest.errwarn
+ modules/objfmts/coff/tests/coff_test.sh \
+ modules/objfmts/coff/tests/cofftest.c \
+ modules/objfmts/coff/tests/cofftest.asm \
+ modules/objfmts/coff/tests/cofftest.hex \
+ modules/objfmts/coff/tests/cofftest.errwarn
#! /bin/sh
# $IdPath$
-${srcdir}/out_test.sh coff_test src/objfmts/coff/tests "coff objfmt" "-f coff" ".o"
+${srcdir}/out_test.sh coff_test modules/objfmts/coff/tests "coff objfmt" "-f coff" ".o"
exit $?
lib_LTLIBRARIES += yasm-dbg.la
yasm_dbg_la_SOURCES = \
- src/objfmts/dbg/dbg-objfmt.c
+ modules/objfmts/dbg/dbg-objfmt.c
yasm_dbg_la_LDFLAGS = -module -avoid-version
yasm_dbg_la_LIBADD = libyasm.la
yasm_LDADD += -dlopen yasm-dbg.la
# $IdPath$
EXTRA_DIST += \
- src/optimizers/basic/Makefile.inc
+ modules/optimizers/basic/Makefile.inc
-include src/optimizers/basic/Makefile.inc
+include modules/optimizers/basic/Makefile.inc
lib_LTLIBRARIES += yasm-basic.la
yasm_basic_la_SOURCES = \
- src/optimizers/basic/basic-optimizer.c
+ modules/optimizers/basic/basic-optimizer.c
yasm_basic_la_LDFLAGS = -module -avoid-version
yasm_basic_la_LIBADD = libyasm.la
yasm_LDADD += -dlpreopen yasm-basic.la
# $IdPath$
EXTRA_DIST += \
- src/parsers/nasm/Makefile.inc
+ modules/parsers/nasm/Makefile.inc
-include src/parsers/nasm/Makefile.inc
+include modules/parsers/nasm/Makefile.inc
#lib_LTLIBRARIES += yasm-nasm.la
yasm_nasm_la_SOURCES += \
- src/parsers/nasm/nasm-parser.h \
- src/parsers/nasm/nasm-parser.c \
- src/parsers/nasm/nasm-defs.h \
- src/parsers/nasm/nasm-bison.y \
+ modules/parsers/nasm/nasm-parser.h \
+ modules/parsers/nasm/nasm-parser.c \
+ modules/parsers/nasm/nasm-defs.h \
+ modules/parsers/nasm/nasm-bison.y \
nasm-bison.h \
nasm-token.c
#yasm_nasm_la_LDFLAGS = -module -avoid-version
#yasm_nasm_la_LIBADD = libyasm.la
#yasm_LDADD += -dlpreopen yasm-nasm.la
-nasm-token.c: $(srcdir)/src/parsers/nasm/nasm-token.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
- $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/src/parsers/nasm/nasm-token.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
+nasm-token.c: $(srcdir)/modules/parsers/nasm/nasm-token.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
+ $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/modules/parsers/nasm/nasm-token.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
BUILT_SOURCES += \
nasm-bison.c \
nasm-token.c
EXTRA_DIST += \
- src/parsers/nasm/tests/Makefile.inc \
- src/parsers/nasm/nasm-token.re
+ modules/parsers/nasm/tests/Makefile.inc \
+ modules/parsers/nasm/nasm-token.re
-include src/parsers/nasm/tests/Makefile.inc
+include modules/parsers/nasm/tests/Makefile.inc
#include "arch.h"
-#include "src/parsers/nasm/nasm-parser.h"
-#include "src/parsers/nasm/nasm-defs.h"
+#include "modules/parsers/nasm/nasm-parser.h"
+#include "modules/parsers/nasm/nasm-defs.h"
static void nasm_parser_error(const char *);
#include "arch.h"
-#include "src/parsers/nasm/nasm-parser.h"
-#include "src/parsers/nasm/nasm-defs.h"
+#include "modules/parsers/nasm/nasm-parser.h"
+#include "modules/parsers/nasm/nasm-defs.h"
#include "nasm-bison.h"
# $IdPath$
TESTS += \
- src/parsers/nasm/tests/nasm_test.sh
+ modules/parsers/nasm/tests/nasm_test.sh
EXTRA_DIST += \
- src/parsers/nasm/tests/nasm_test.sh \
- src/parsers/nasm/tests/equlocal.asm \
- src/parsers/nasm/tests/equlocal.errwarn \
- src/parsers/nasm/tests/equlocal.hex \
- src/parsers/nasm/tests/newsect.asm \
- src/parsers/nasm/tests/newsect.errwarn \
- src/parsers/nasm/tests/newsect.hex
+ modules/parsers/nasm/tests/nasm_test.sh \
+ modules/parsers/nasm/tests/equlocal.asm \
+ modules/parsers/nasm/tests/equlocal.errwarn \
+ modules/parsers/nasm/tests/equlocal.hex \
+ modules/parsers/nasm/tests/newsect.asm \
+ modules/parsers/nasm/tests/newsect.errwarn \
+ modules/parsers/nasm/tests/newsect.hex
#! /bin/sh
# $IdPath$
-${srcdir}/out_test.sh nasm_test src/parsers/nasm/tests "nasm-compat parser" "-f bin" ""
+${srcdir}/out_test.sh nasm_test modules/parsers/nasm/tests "nasm-compat parser" "-f bin" ""
exit $?
# $IdPath$
EXTRA_DIST += \
- src/preprocs/nasm/Makefile.inc \
- src/preprocs/raw/Makefile.inc \
- src/preprocs/yapp/Makefile.inc
+ modules/preprocs/nasm/Makefile.inc \
+ modules/preprocs/raw/Makefile.inc \
+ modules/preprocs/yapp/Makefile.inc
-include src/preprocs/nasm/Makefile.inc
-include src/preprocs/raw/Makefile.inc
-include src/preprocs/yapp/Makefile.inc
+include modules/preprocs/nasm/Makefile.inc
+include modules/preprocs/raw/Makefile.inc
+include modules/preprocs/yapp/Makefile.inc
#lib_LTLIBRARIES += yasm-nasm.la
yasm_nasm_la_SOURCES += \
- src/preprocs/nasm/nasm-preproc.c \
- src/preprocs/nasm/nasm-pp.h \
- src/preprocs/nasm/nasm-pp.c \
- src/preprocs/nasm/nasm.h \
- src/preprocs/nasm/nasmlib.h \
- src/preprocs/nasm/nasmlib.c \
- src/preprocs/nasm/nasm-eval.h \
- src/preprocs/nasm/nasm-eval.c
+ modules/preprocs/nasm/nasm-preproc.c \
+ modules/preprocs/nasm/nasm-pp.h \
+ modules/preprocs/nasm/nasm-pp.c \
+ modules/preprocs/nasm/nasm.h \
+ modules/preprocs/nasm/nasmlib.h \
+ modules/preprocs/nasm/nasmlib.c \
+ modules/preprocs/nasm/nasm-eval.h \
+ modules/preprocs/nasm/nasm-eval.c
-$(top_srcdir)/src/preprocs/nasm/nasm-pp.c: nasm-macros.c
+$(top_modulesdir)/src/preprocs/nasm/nasm-pp.c: nasm-macros.c
-nasm-macros.c: $(top_srcdir)/src/preprocs/nasm/macros.pl $(top_srcdir)/src/preprocs/nasm/standard.mac
- $(PERL) $(top_srcdir)/src/preprocs/nasm/macros.pl $(top_srcdir)/src/preprocs/nasm/standard.mac
+nasm-macros.c: $(top_srcdir)/modules/preprocs/nasm/macros.pl $(top_srcdir)/modules/preprocs/nasm/standard.mac
+ $(PERL) $(top_srcdir)/modules/preprocs/nasm/macros.pl $(top_srcdir)/modules/preprocs/nasm/standard.mac
BUILT_SOURCES += nasm-macros.c
CLEANFILES += nasm-macros.c
-EXTRA_DIST += src/preprocs/nasm/macros.pl \
- src/preprocs/nasm/standard.mac
+EXTRA_DIST += modules/preprocs/nasm/macros.pl \
+ modules/preprocs/nasm/standard.mac
#yasm_nasm_la_LDFLAGS = -module -avoid-version
#yasm_nasm_la_LIBADD = libyasm.la
lib_LTLIBRARIES += yasm-raw.la
yasm_raw_la_SOURCES = \
- src/preprocs/raw/raw-preproc.c
+ modules/preprocs/raw/raw-preproc.c
yasm_raw_la_LDFLAGS = -module -avoid-version
yasm_raw_la_LIBADD = libyasm.la
yasm_LDADD += -dlpreopen yasm-raw.la
lib_LTLIBRARIES += yasm-yapp.la
yasm_yapp_la_SOURCES = \
- src/preprocs/yapp/yapp-preproc.h \
- src/preprocs/yapp/yapp-preproc.c \
- src/preprocs/yapp/yapp-token.h \
- src/preprocs/yapp/yapp-token.l
+ modules/preprocs/yapp/yapp-preproc.h \
+ modules/preprocs/yapp/yapp-preproc.c \
+ modules/preprocs/yapp/yapp-token.h \
+ modules/preprocs/yapp/yapp-token.l
yasm_yapp_la_LDFLAGS = -module -avoid-version
yasm_yapp_la_LIBADD = libyasm.la
yasm_LDADD += -dlopen yasm-yapp.la
CLEANFILES += \
yapp-token.c
-include src/preprocs/yapp/tests/Makefile.inc
+include modules/preprocs/yapp/tests/Makefile.inc
# $IdPath$
TESTS += \
- src/preprocs/yapp/tests/yapp_test.sh
+ modules/preprocs/yapp/tests/yapp_test.sh
EXTRA_DIST += \
- src/preprocs/yapp/tests/Makefile.inc \
- src/preprocs/yapp/tests/yapp_test.sh \
- src/preprocs/yapp/tests/raw.asm \
- src/preprocs/yapp/tests/raw.pre \
- src/preprocs/yapp/tests/comment.asm \
- src/preprocs/yapp/tests/comment.pre \
- src/preprocs/yapp/tests/define.asm \
- src/preprocs/yapp/tests/define.pre \
- src/preprocs/yapp/tests/ddefine.asm \
- src/preprocs/yapp/tests/ddefine.pre \
- src/preprocs/yapp/tests/rdefine.asm \
- src/preprocs/yapp/tests/rdefine.pre \
- src/preprocs/yapp/tests/pdefine.asm \
- src/preprocs/yapp/tests/pdefine.pre \
- src/preprocs/yapp/tests/ifdef.asm \
- src/preprocs/yapp/tests/ifdef.pre \
- src/preprocs/yapp/tests/include.asm \
- src/preprocs/yapp/tests/include.pre \
- src/preprocs/yapp/tests/rinclude.asm \
- src/preprocs/yapp/tests/rinclude.pre \
- src/preprocs/yapp/tests/params.asm \
- src/preprocs/yapp/tests/params.pre
+ modules/preprocs/yapp/tests/Makefile.inc \
+ modules/preprocs/yapp/tests/yapp_test.sh \
+ modules/preprocs/yapp/tests/raw.asm \
+ modules/preprocs/yapp/tests/raw.pre \
+ modules/preprocs/yapp/tests/comment.asm \
+ modules/preprocs/yapp/tests/comment.pre \
+ modules/preprocs/yapp/tests/define.asm \
+ modules/preprocs/yapp/tests/define.pre \
+ modules/preprocs/yapp/tests/ddefine.asm \
+ modules/preprocs/yapp/tests/ddefine.pre \
+ modules/preprocs/yapp/tests/rdefine.asm \
+ modules/preprocs/yapp/tests/rdefine.pre \
+ modules/preprocs/yapp/tests/pdefine.asm \
+ modules/preprocs/yapp/tests/pdefine.pre \
+ modules/preprocs/yapp/tests/ifdef.asm \
+ modules/preprocs/yapp/tests/ifdef.pre \
+ modules/preprocs/yapp/tests/include.asm \
+ modules/preprocs/yapp/tests/include.pre \
+ modules/preprocs/yapp/tests/rinclude.asm \
+ modules/preprocs/yapp/tests/rinclude.pre \
+ modules/preprocs/yapp/tests/params.asm \
+ modules/preprocs/yapp/tests/params.pre
mov ax, 5
-%include "./src/preprocs/yapp/tests/raw.asm"
+%include "./modules/preprocs/yapp/tests/raw.asm"
mov ax, 6
-%include "./src/preprocs/yapp/tests/raw.asm"
+%include "./modules/preprocs/yapp/tests/raw.asm"
mov ax, 7
%line 1+1 -
mov ax, 5
-%line 1+1 ./src/preprocs/yapp/tests/raw.asm
+%line 1+1 ./modules/preprocs/yapp/tests/raw.asm
mov ax, raw
%line 3+1 -
mov ax, 6
-%line 1+1 ./src/preprocs/yapp/tests/raw.asm
+%line 1+1 ./modules/preprocs/yapp/tests/raw.asm
mov ax, raw
%line 5+1 -
mov ax, 7
%ifndef recurse
%define recurse
-%include "./src/preprocs/yapp/tests/rinclude.asm"
+%include "./modules/preprocs/yapp/tests/rinclude.asm"
mov ax, 5
%endif
YT="yapp_test"
-for asm in ${srcdir}/src/preprocs/yapp/tests/*.asm
+for asm in ${srcdir}/modules/preprocs/yapp/tests/*.asm
do
a=`echo ${asm} | sed 's,^.*/,,;s,.asm$,,'`
y=${a}.yp
#include "preproc.h"
#include "hamt.h"
-#include "src/preprocs/yapp/yapp-preproc.h"
-#include "src/preprocs/yapp/yapp-token.h"
+#include "yapp-preproc.h"
+#include "yapp-token.h"
#define ydebug(x) /* printf x */
#include "linemgr.h"
#include "errwarn.h"
-#include "src/preprocs/yapp/yapp-preproc.h"
-#include "src/preprocs/yapp/yapp-token.h"
+#include "modules/preprocs/yapp/yapp-preproc.h"
+#include "modules/preprocs/yapp/yapp-token.h"
#define yylval yapp_preproc_lval
#
# $IdPath$
+frontends/yasm/yasm-options.c
+frontends/yasm/yasm.c
+libyasm/bitvect.c
+libyasm/bytecode.c
+libyasm/errwarn.c
+libyasm/expr.c
+libyasm/floatnum.c
+libyasm/hamt.c
+libyasm/intnum.c
+libyasm/linemgr.c
+libyasm/section.c
+libyasm/symrec.c
+libyasm/xmalloc.c
+modules/arch/x86/x86arch.c
+modules/arch/x86/x86bc.c
+modules/arch/x86/x86expr.c
+modules/objfmts/bin/bin-objfmt.c
+modules/objfmts/coff/coff-objfmt.c
+modules/objfmts/dbg/dbg-objfmt.c
+modules/optimizers/basic/basic-optimizer.c
+modules/preprocs/nasm/nasm-pp.c
+modules/preprocs/nasm/nasm-preproc.c
+modules/preprocs/raw/raw-preproc.c
+modules/preprocs/yapp/yapp-preproc.c
nasm-bison.c
nasm-token.c
x86id.c
yapp-token.c
-src/bitvect.c
-src/bytecode.c
-src/errwarn.c
-src/expr.c
-src/file.c
-src/floatnum.c
-src/hamt.c
-src/intnum.c
-src/main.c
-src/options.c
-src/section.c
-src/symrec.c
-src/arch/x86/x86arch.c
-src/arch/x86/x86bc.c
-src/arch/x86/x86expr.c
-src/objfmts/dbg/dbg-objfmt.c
-src/objfmts/bin/bin-objfmt.c
-src/objfmts/coff/coff-objfmt.c
-src/optimizers/basic/basic-optimizer.c
-src/preprocs/raw/raw-preproc.c
-src/preprocs/yapp/yapp-preproc.c
+++ /dev/null
-/* blank lines */
---blank-lines-after-declarations
---blank-lines-after-procedures
---no-blank-lines-before-block-comments
---leave-optional-blank-lines
-/* comments */
---no-comment-delimiters-on-blank-lines
---start-left-side-of-comments
-/* statements */
---braces-on-if-line
---cuddle-else
---cuddle-do-while
---case-indentation 4
---case-brace-indentation 4
---space-special-semicolon
---no-space-after-function-call-names
---no-space-after-casts
---space-after-for
---space-after-if
---space-after-while
---no-space-after-parentheses
-/* declarations */
---no-blank-lines-after-commas
---dont-break-function-decl-args
---procnames-start-lines
---braces-on-struct-decl-line
-/* indentation */
---continuation-indentation 4
---indent-level 4
---continue-at-parentheses
---parameter-indentation 4
---leave-preprocessor-space
-/* breaking long lines */
---line-length 78
---break-after-boolean-operator
---honour-newlines
-/* typedefs */
--Teffaddr
--Timmval
--Tjmprel_opcode_sel
--Ttargetval
--Tbytecode
--Tfatal_num
--Terr_num
--Twarn_num
--TExprOp
--TExprType
--TExprItem
--Texpr
--Tsection
--Tpreproc
--Tparser
--Tobjfmt
--Tdataval
--TSymStatus
--TSymType
--Tsymrec
--Tsymtab
--TFILE
+++ /dev/null
-# $IdPath$
-
-libyasm_la_SOURCES = \
- src/bytecode.c \
- src/bytecode.h \
- src/bc-int.h \
- src/errwarn.h \
- src/expr.c \
- src/expr.h \
- src/expr-int.h \
- src/symrec.c \
- src/symrec.h \
- src/linemgr.h \
- src/util.h \
- src/coretype.h \
- src/file.c \
- src/file.h \
- src/section.c \
- src/section.h \
- src/arch.c \
- src/arch.h \
- src/dbgfmt.h \
- src/objfmt.h \
- src/optimizer.h \
- src/parser.h \
- src/preproc.h \
- src/intnum.c \
- src/intnum.h \
- src/floatnum.c \
- src/floatnum.h \
- src/hamt.c \
- src/hamt.h \
- src/bitvect.c \
- src/bitvect.h \
- src/valparam.c \
- src/valparam.h \
- src/errwarn.c \
- src/linemgr.c \
- src/xmalloc.c \
- src/xstrdup.c \
- src/strcasecmp.c
-libyasm_la_LDFLAGS = -no-undefined
-
-yasm_SOURCES += \
- src/main.c \
- src/options.c \
- src/options.h \
- src/module.h \
- src/module.c
-
-
-EXTRA_DIST += \
- src/arch/Makefile.inc \
- src/parsers/Makefile.inc \
- src/preprocs/Makefile.inc \
- src/optimizers/Makefile.inc \
- src/objfmts/Makefile.inc \
- src/tests/Makefile.inc
-
-# Modules with more than one type of interface
-
-lib_LTLIBRARIES += yasm-nasm.la
-yasm_nasm_la_SOURCES =
-yasm_nasm_la_LDFLAGS = -module -avoid-version
-yasm_nasm_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-nasm.la
-
-include src/arch/Makefile.inc
-include src/parsers/Makefile.inc
-include src/preprocs/Makefile.inc
-include src/optimizers/Makefile.inc
-include src/dbgfmts/Makefile.inc
-include src/objfmts/Makefile.inc
-include src/tests/Makefile.inc
-
-EXTRA_yasm_SOURCES += \
- src/compat-queue.h
+++ /dev/null
-/*
- * Architecture interface
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "expr.h"
-
-#include "bytecode.h"
-
-#include "arch.h"
-
-
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-void
-yasm_arch_common_initialize(yasm_arch *a)
-{
- cur_arch = a;
-}
-
-yasm_insn_operand *
-yasm_operand_new_reg(unsigned long reg)
-{
- yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
-
- retval->type = YASM_INSN__OPERAND_REG;
- retval->data.reg = reg;
- retval->targetmod = 0;
- retval->size = 0;
-
- return retval;
-}
-
-yasm_insn_operand *
-yasm_operand_new_segreg(unsigned long segreg)
-{
- yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
-
- retval->type = YASM_INSN__OPERAND_SEGREG;
- retval->data.reg = segreg;
- retval->targetmod = 0;
- retval->size = 0;
-
- return retval;
-}
-
-yasm_insn_operand *
-yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea)
-{
- yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
-
- retval->type = YASM_INSN__OPERAND_MEMORY;
- retval->data.ea = ea;
- retval->targetmod = 0;
- retval->size = 0;
-
- return retval;
-}
-
-yasm_insn_operand *
-yasm_operand_new_imm(/*@only@*/ yasm_expr *val)
-{
- yasm_insn_operand *retval;
- const unsigned long *reg;
-
- reg = yasm_expr_get_reg(&val, 0);
- if (reg) {
- retval = yasm_operand_new_reg(*reg);
- yasm_expr_delete(val);
- } else {
- retval = yasm_xmalloc(sizeof(yasm_insn_operand));
- retval->type = YASM_INSN__OPERAND_IMM;
- retval->data.val = val;
- retval->targetmod = 0;
- retval->size = 0;
- }
-
- return retval;
-}
-
-void
-yasm_operand_print(FILE *f, int indent_level, const yasm_insn_operand *op)
-{
- switch (op->type) {
- case YASM_INSN__OPERAND_REG:
- fprintf(f, "%*sReg=", indent_level, "");
- cur_arch->reg_print(f, op->data.reg);
- fprintf(f, "\n");
- break;
- case YASM_INSN__OPERAND_SEGREG:
- fprintf(f, "%*sSegReg=", indent_level, "");
- cur_arch->segreg_print(f, op->data.reg);
- fprintf(f, "\n");
- break;
- case YASM_INSN__OPERAND_MEMORY:
- fprintf(f, "%*sMemory=\n", indent_level, "");
- yasm_ea_print(f, indent_level, op->data.ea);
- break;
- case YASM_INSN__OPERAND_IMM:
- fprintf(f, "%*sImm=", indent_level, "");
- yasm_expr_print(f, op->data.val);
- fprintf(f, "\n");
- break;
- }
- fprintf(f, "%*sTargetMod=%lx\n", indent_level+1, "", op->targetmod);
- fprintf(f, "%*sSize=%u\n", indent_level+1, "", op->size);
-}
-
-void
-yasm_ops_delete(yasm_insn_operandhead *headp, int content)
-{
- yasm_insn_operand *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- if (content)
- switch (cur->type) {
- case YASM_INSN__OPERAND_MEMORY:
- yasm_ea_delete(cur->data.ea);
- break;
- case YASM_INSN__OPERAND_IMM:
- yasm_expr_delete(cur->data.val);
- break;
- default:
- break;
- }
- yasm_xfree(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
-}
-
-/*@null@*/ yasm_insn_operand *
-yasm_ops_append(yasm_insn_operandhead *headp,
- /*@returned@*/ /*@null@*/ yasm_insn_operand *op)
-{
- if (op) {
- STAILQ_INSERT_TAIL(headp, op, link);
- return op;
- }
- return (yasm_insn_operand *)NULL;
-}
-
-void
-yasm_ops_print(FILE *f, int indent_level, const yasm_insn_operandhead *headp)
-{
- yasm_insn_operand *cur;
-
- STAILQ_FOREACH (cur, headp, link)
- yasm_operand_print(f, indent_level, cur);
-}
+++ /dev/null
-/* $IdPath$
- * YASM architecture interface header file
- *
- * Copyright (C) 2002 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.
- *
- * 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.
- */
-#ifndef YASM_ARCH_H
-#define YASM_ARCH_H
-
-typedef enum yasm_arch_check_id_retval {
- YASM_ARCH_CHECK_ID_NONE = 0, /* just a normal identifier */
- YASM_ARCH_CHECK_ID_INSN, /* an instruction */
- YASM_ARCH_CHECK_ID_PREFIX, /* an instruction prefix */
- YASM_ARCH_CHECK_ID_REG, /* a register */
- YASM_ARCH_CHECK_ID_SEGREG, /* a segment register (for memory overrides) */
- YASM_ARCH_CHECK_ID_TARGETMOD /* an target modifier (for jumps) */
-} yasm_arch_check_id_retval;
-
-typedef /*@reldef@*/ STAILQ_HEAD(yasm_insn_operandhead, yasm_insn_operand)
- yasm_insn_operandhead;
-
-typedef struct yasm_insn_operand yasm_insn_operand;
-
-/* Different assemblers order instruction operands differently. Also, some
- * differ on how exactly various registers are specified. There's no great
- * solution to this, as the parsers aren't supposed to have knowledge of the
- * architectural internals, and the architecture is supposed to be parser-
- * independent. To make things work, as a rather hackish solution, we give the
- * architecture a little knowledge about the general "flavor" of the parser,
- * and let the architecture decide what to do with it. Most architectures will
- * probably not even use this, but it's required for some (x86 in particular)
- * for correct behavior on all parsers.
- */
-typedef enum yasm_arch_syntax_flavor {
- YASM_ARCH_SYNTAX_FLAVOR_NASM = 1, /* like NASM */
- YASM_ARCH_SYNTAX_FLAVOR_GAS /* like GAS */
-} yasm_arch_syntax_flavor;
-
-struct yasm_arch {
- /* one-line description of the architecture */
- const char *name;
-
- /* keyword used to select architecture */
- const char *keyword;
-
- void (*initialize) (void);
- void (*cleanup) (void);
-
- struct {
- /* All "data" below starts the parse initialized to 0. Thus, it is
- * okay for a funtion to use/check previously stored data to see if
- * it's been called before on the same piece of data.
- */
-
- /* Switches available instructions/registers/etc. based on a
- * user-specified CPU identifier. Should modify behavior ONLY of
- * parse functions! The bytecode and output functions should be able
- * to handle any CPU.
- */
- void (*switch_cpu) (const char *cpuid, unsigned long lindex);
-
- /* Checks an generic identifier to see if it matches architecture
- * specific names for instructions, registers, etc (see the
- * arch_check_id_retval enum above for the various types this function
- * can detect & return. Unrecognized identifiers should be returned
- * as NONE so they can be treated as normal symbols. Any additional
- * data beyond just the type (almost always necessary) should be
- * returned into the space provided by the data parameter.
- * Note: even though this is passed a data[4], only data[0] should be
- * used for TARGETMOD, REG, and SEGREG return values.
- */
- yasm_arch_check_id_retval (*check_identifier)
- (unsigned long data[4], const char *id, unsigned long lindex);
-
- /* Architecture-specific directive support. Returns 1 if directive was
- * not recognized. Returns 0 if directive was recognized, even if it
- * wasn't valid. Should modify behavior ONLY of parse functions, much
- * like switch_cpu() above.
- */
- int (*directive) (const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
-
- /* Creates an instruction. Creates a bytecode by matching the
- * instruction data and the parameters given with a valid instruction.
- * If no match is found (the instruction is invalid), returns NULL.
- * All zero data indicates an empty instruction should be created.
- */
- /*@null@*/ yasm_bytecode * (*new_insn)
- (const unsigned long data[4], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands,
- yasm_section *cur_section, /*@null@*/ yasm_bytecode *prev_bc,
- unsigned long lindex);
-
- /* Handle an instruction prefix by modifying bc as necessary. */
- void (*handle_prefix) (yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex);
-
- /* Handle an segment register instruction prefix by modifying bc as
- * necessary.
- */
- void (*handle_seg_prefix) (yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex);
-
- /* Handle memory expression segment overrides by modifying ea as
- * necessary.
- */
- void (*handle_seg_override) (yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex);
-
- /* Convert an expression into an effective address. */
- yasm_effaddr * (*ea_new_expr) (/*@keep@*/ yasm_expr *e);
- } parse;
-
- struct {
- /* Maximum used bytecode type value+1. Should be set to
- * BYTECODE_TYPE_BASE if no additional bytecode types are defined by
- * the architecture.
- */
- const int type_max;
-
- void (*bc_delete) (yasm_bytecode *bc);
- void (*bc_print) (FILE *f, int indent_level, const yasm_bytecode *bc);
-
- /* See bytecode.h comments on bc_resolve() */
- yasm_bc_resolve_flags (*bc_resolve)
- (yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
- /* See bytecode.h comments on bc_tobytes() */
- int (*bc_tobytes) (yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr);
- } bc;
-
- /* Functions to output floats and integers, architecture-specific because
- * of endianness. Returns nonzero on error, otherwise updates bufp by
- * valsize (bytes saved to bufp). For intnums, rel indicates a relative
- * displacement, and bc is the containing bytecode to compute it from.
- */
- int (*floatnum_tobytes) (const yasm_floatnum *flt, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e);
- int (*intnum_tobytes) (const yasm_intnum *intn, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e,
- const yasm_bytecode *bc, int rel);
-
- /* Gets the equivalent register size in bytes. Returns 0 if there is no
- * suitable equivalent size.
- */
- unsigned int (*get_reg_size) (unsigned long reg);
-
- void (*reg_print) (FILE *f, unsigned long reg);
- void (*segreg_print) (FILE *f, unsigned long segreg);
-
- /* Deletes the arch-specific data in ea. May be NULL if no special
- * deletion is required (e.g. there's no dynamically allocated pointers
- * in the ea data).
- */
- void (*ea_data_delete) (yasm_effaddr *ea);
-
- void (*ea_data_print) (FILE *f, int indent_level, const yasm_effaddr *ea);
-};
-
-struct yasm_insn_operand {
- /*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link;
-
- enum {
- YASM_INSN__OPERAND_REG = 1, /* a register */
- YASM_INSN__OPERAND_SEGREG, /* a segment register */
- YASM_INSN__OPERAND_MEMORY,/* an effective address (memory reference) */
- YASM_INSN__OPERAND_IMM /* an immediate or jump target */
- } type;
-
- union {
- unsigned long reg; /* arch data for reg/segreg */
- yasm_effaddr *ea; /* effective address for memory references */
- yasm_expr *val; /* value of immediate or jump target */
- } data;
-
- unsigned long targetmod; /* arch target modifier, 0 if none */
-
- /* Specified size of the operand, in bytes. 0 if not user-specified. */
- unsigned int size;
-};
-
-void yasm_arch_common_initialize(yasm_arch *a);
-
-/* insn_operand constructors. operand_new_imm() will look for cases of a
- * single register and create an INSN_OPERAND_REG variant of insn_operand.
- */
-yasm_insn_operand *yasm_operand_new_reg(unsigned long reg);
-yasm_insn_operand *yasm_operand_new_segreg(unsigned long segreg);
-yasm_insn_operand *yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea);
-yasm_insn_operand *yasm_operand_new_imm(/*@only@*/ yasm_expr *val);
-
-void yasm_operand_print(FILE *f, int indent_level,
- const yasm_insn_operand *op);
-
-#define yasm_ops_initialize(headp) STAILQ_INIT(headp)
-#define yasm_ops_first(headp) STAILQ_FIRST(headp)
-#define yasm_ops_next(cur) STAILQ_NEXT(cur, link)
-
-/* Deletes operands linked list. Deletes content of each operand if content i
- * nonzero.
- */
-void yasm_ops_delete(yasm_insn_operandhead *headp, int content);
-
-/* Adds op to the list of operands headp.
- * NOTE: Does not make a copy of op; so don't pass this function
- * static or local variables, and discard the op pointer after calling
- * this function. If op was actually appended (it wasn't NULL), then
- * returns op, otherwise returns NULL.
- */
-/*@null@*/ yasm_insn_operand *yasm_ops_append
- (yasm_insn_operandhead *headp,
- /*@returned@*/ /*@null@*/ yasm_insn_operand *op);
-
-void yasm_ops_print(FILE *f, int indent_level,
- const yasm_insn_operandhead *headp);
-
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/arch/x86/Makefile.inc
-
-include src/arch/x86/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-x86.la
-
-yasm_x86_la_SOURCES = \
- src/arch/x86/x86arch.c \
- src/arch/x86/x86arch.h \
- src/arch/x86/x86bc.c \
- src/arch/x86/x86expr.c \
- x86id.c
-yasm_x86_la_LDFLAGS = -module -avoid-version
-yasm_x86_la_LIBADD = libyasm.la
-yasm_LDADD += -dlpreopen yasm-x86.la
-
-x86id.c: $(srcdir)/src/arch/x86/x86id.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
- $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/src/arch/x86/x86id.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
-
-BUILT_SOURCES += \
- x86id.c
-
-CLEANFILES += \
- x86id.c
-
-EXTRA_DIST += \
- src/arch/x86/tests/Makefile.inc \
- src/arch/x86/README \
- src/arch/x86/x86id.re
-
-include src/arch/x86/tests/Makefile.inc
+++ /dev/null
-Architecture to support Intel IA-32, AMD x86-64, and other extensions and
-derivatives of the x86 instruction set.
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- src/arch/x86/tests/x86_test.sh
-
-EXTRA_DIST += \
- src/arch/x86/tests/x86_test.sh \
- src/arch/x86/tests/addbyte.asm \
- src/arch/x86/tests/addbyte.errwarn \
- src/arch/x86/tests/addbyte.hex \
- src/arch/x86/tests/addrop.asm \
- src/arch/x86/tests/addrop.errwarn \
- src/arch/x86/tests/addrop.hex \
- src/arch/x86/tests/addrop-err.asm \
- src/arch/x86/tests/addrop-err.errwarn \
- src/arch/x86/tests/cpubasic-err.asm \
- src/arch/x86/tests/cpubasic-err.errwarn \
- src/arch/x86/tests/div-err.asm \
- src/arch/x86/tests/div-err.errwarn \
- src/arch/x86/tests/effaddr.asm \
- src/arch/x86/tests/effaddr.errwarn \
- src/arch/x86/tests/effaddr.hex \
- src/arch/x86/tests/genopcode.asm \
- src/arch/x86/tests/genopcode.errwarn \
- src/arch/x86/tests/genopcode.hex \
- src/arch/x86/tests/lds-err.asm \
- src/arch/x86/tests/lds-err.errwarn \
- src/arch/x86/tests/loopadsz.asm \
- src/arch/x86/tests/loopadsz.errwarn \
- src/arch/x86/tests/loopadsz.hex \
- src/arch/x86/tests/mem64-err.asm \
- src/arch/x86/tests/mem64-err.errwarn \
- src/arch/x86/tests/mem64.asm \
- src/arch/x86/tests/mem64.errwarn \
- src/arch/x86/tests/mem64.hex \
- src/arch/x86/tests/negequ.asm \
- src/arch/x86/tests/negequ.errwarn \
- src/arch/x86/tests/negequ.hex \
- src/arch/x86/tests/nomem64-err.asm \
- src/arch/x86/tests/nomem64-err.errwarn \
- src/arch/x86/tests/nomem64.asm \
- src/arch/x86/tests/nomem64.errwarn \
- src/arch/x86/tests/nomem64.hex \
- src/arch/x86/tests/opersize.asm \
- src/arch/x86/tests/opersize.errwarn \
- src/arch/x86/tests/opersize.hex \
- src/arch/x86/tests/opsize-err.asm \
- src/arch/x86/tests/opsize-err.errwarn \
- src/arch/x86/tests/ret.asm \
- src/arch/x86/tests/ret.errwarn \
- src/arch/x86/tests/ret.hex \
- src/arch/x86/tests/segmov.asm \
- src/arch/x86/tests/segmov.errwarn \
- src/arch/x86/tests/segmov.hex \
- src/arch/x86/tests/shift.asm \
- src/arch/x86/tests/shift.errwarn \
- src/arch/x86/tests/shift.hex \
- src/arch/x86/tests/x86label.asm \
- src/arch/x86/tests/x86label.errwarn \
- src/arch/x86/tests/x86label.hex
+++ /dev/null
-add ax,5
-add ax,byte 5
-add bx,5
-add bx,byte 5
+++ /dev/null
-05
-05
-00
-83
-c0
-05
-81
-c3
-05
-00
-83
-c3
-05
+++ /dev/null
-[BITS 32]
-a16 idiv byte [dword 0] ; 67 F6 3D 00 00 00 00
+++ /dev/null
--:2: invalid effective address (displacement size)
+++ /dev/null
-[BITS 32]
-idiv al ; F6 F8
-idiv ax ; 66 F7 F8
-idiv eax ; F7 F8
-idiv byte [word 0] ; 67 F6 3E 00 00
-idiv byte [dword 0xFFFFFFFF] ; F6 3D FF FF FF FF
-idiv byte [0] ; F6 3D 00 00 00 00
-a16 idiv byte [word 0] ; 67 67 F6 3E 00 00
-;a16 idiv byte [dword 0] ; 67 F6 3D 00 00 00 00
-a16 idiv byte [0] ; 67 F6 3D 00 00
-a32 idiv byte [0] ; F6 3D 00 00 00 00
-[BITS 16]
-nop
-idiv al
-idiv ax
-idiv eax
-nop
-idiv byte [word 0]
-idiv byte [dword 0xFFFFFFFF]
-idiv byte [0]
-idiv dword [es:dword 5]
-idiv dword [byte es:5]
-idiv word [es:dword edi+5]
-;idiv word [es:edi+dword 5]
-nop
+++ /dev/null
-f6
-f8
-66
-f7
-f8
-f7
-f8
-67
-f6
-3e
-00
-00
-f6
-3d
-ff
-ff
-ff
-ff
-f6
-3d
-00
-00
-00
-00
-67
-f6
-3e
-00
-00
-67
-f6
-3e
-00
-00
-f6
-3d
-00
-00
-00
-00
-90
-f6
-f8
-f7
-f8
-66
-f7
-f8
-90
-f6
-3e
-00
-00
-67
-f6
-3d
-ff
-ff
-ff
-ff
-f6
-3e
-00
-00
-26
-66
-67
-f7
-3d
-05
-00
-00
-00
-26
-66
-f7
-3e
-05
-26
-67
-f7
-bf
-05
-00
-00
-00
-90
+++ /dev/null
-[cpu 8086]
-pause
+++ /dev/null
--:2: invalid combination of opcode and operands
+++ /dev/null
-div byte si
-div word si
-div dword si
-div byte esi
-div word esi
-div dword esi
-
+++ /dev/null
--:1: cannot override register size
--:3: cannot override register size
--:4: cannot override register size
--:5: cannot override register size
+++ /dev/null
-[bits 32]
-mov ax,[eax+ebx+ecx-eax]
-mov ax,[eax+ecx+ebx-eax]
-label
-dd 5
-label2
-mov ax,[eax+ebx*(label2-label)]
+++ /dev/null
-66
-8b
-04
-0b
-66
-8b
-04
-19
-05
-00
-00
-00
-66
-8b
-04
-98
+++ /dev/null
-[bits 16]
-mov al, 0
-mov byte al, 0
-mov al, byte 0
-mov byte al, byte 0
-;mov al, word 0
-mov byte [0], 0
-mov [0], word 0
-mov dword [0], dword 0
-;mov [0], 0
-mov eax, 0
-mov dword eax, 0
-mov eax, dword 0
-;mov eax, word 0
-mov dword eax, dword 0
-mov bx, 1h
-mov cr0, eax
-mov cr2, ebx
-mov cr4, edx
-mov ecx, cr4
-mov dr3, edx
-mov eax, dr7
-
-mov [0], al
-mov [0], bl
-mov [1], al
-mov [1], bl
-mov ecx, edx
-movsx ax, [ecx]
-;movzx eax, [edx]
-movzx ebx, word [eax]
-movzx ecx, byte [ebx]
-fnstenv [es:ecx+5]
-nop
-
-push cs
-push word cs
-push dword cs ; NASM unsupported
-push ds
-push es
-push fs
-push gs
-pop ds
-pop es
-pop fs
-pop gs
-xchg al, bl
-xchg al, [0]
-xchg [0], al
-xchg ax, bx
-xchg cx, ax
-xchg [0], ax
-xchg [0], cx
-xchg cx, [0]
-xchg eax, edx
-xchg ebx, eax
-xchg ecx, ebx
-xchg [0], ecx
-xchg eax, [0]
-in al, 55
-in ax, 99
-in eax, 100
-in al, dx
-in ax, dx
-in eax, dx
-out 55, al
-out 66, ax
-out 77, eax
-out dx, al
-out dx, ax
-out dx, eax
-lea bx, [5]
-lea ebx, [32]
-lds si, [0]
-lds ax, [1]
-;lds ax, dword [1]
-les di, [5]
-lds eax, [7]
-les ebx, [9]
-lss esp, [11]
-lfs ecx, [13]
-lgs edx, [15]
-;; TODO: add arith stuff
-imul eax, 4
-aad
-aam
-aad 5
-aam 10
-shl al, 5
-shl bl, 1
-shl cl, cl
-shr ax, 5
-shr bx, 1
-shr cx, cl
-shld ax, bx, 5
-shrd cx, dx, cl
-shld ecx, edx, 10
-shld eax, ebx, cl
-retn
-retf
-retn 8
-retf 16
-enter 10, 12
-setc al
-setc [0]
-;; TODO: add bit manip
-int 10
-;; TODO: add bound
-;; TODO: add protection control
-fld dword [0]
-fld qword [4]
-fld tword [16]
-fld st2
-fstp dword [0]
-fstp st4
-fild word [0]
-fild dword [4]
-fild qword [8]
-fbld [100]
-fbld tword [10]
-fst dword [1]
-fst qword [8]
-fst st1
-fxch
-fxch st1
-fxch st0, st2
-fxch st2, st0
-fcom dword [0]
-fcom qword [8]
-fcom st1
-fcom st0, st0
-fucom st7
-fucomp st0, st5
-fadd dword [10]
-fadd qword [5]
-fadd st0
-fadd st0, st5
-fadd to st7
-fadd st6, st0
-faddp ;NASM unsupported
-faddp st2
-faddp st5, st0
-fiadd word [10]
-fisub dword [4]
-fldcw [0]
-fnstcw [4]
-fstcw word [4]
-fnstsw [8]
-fnstsw ax
-fstsw word [0]
-fstsw ax
-ffree st1
-ffreep st0 ;NASM unsupported
-jc short label
-jc label
-label:
-jz label
-jz near label
-loop label
-jcxz label
-jecxz label
-call label
-call [label]
-call dword [label]
-;jmp label
-jmp short label
-jmp near label
-jmp far [label]
-jmp far dword [label]
-call far word [label]
-[bits 16]
-push si
-push esi
-[bits 32]
-push esi
+++ /dev/null
-b0
-00
-b0
-00
-b0
-00
-b0
-00
-c6
-06
-00
-00
-00
-c7
-06
-00
-00
-00
-00
-66
-c7
-06
-00
-00
-00
-00
-00
-00
-66
-b8
-00
-00
-00
-00
-66
-b8
-00
-00
-00
-00
-66
-b8
-00
-00
-00
-00
-66
-b8
-00
-00
-00
-00
-bb
-01
-00
-0f
-22
-c0
-0f
-22
-d3
-0f
-22
-e2
-0f
-20
-e1
-0f
-23
-da
-0f
-21
-f8
-a2
-00
-00
-88
-1e
-00
-00
-a2
-01
-00
-88
-1e
-01
-00
-66
-89
-d1
-67
-0f
-be
-01
-66
-67
-0f
-b7
-18
-66
-67
-0f
-b6
-0b
-26
-67
-d9
-71
-05
-90
-0e
-0e
-66
-0e
-1e
-06
-0f
-a0
-0f
-a8
-1f
-07
-0f
-a1
-0f
-a9
-86
-d8
-86
-06
-00
-00
-86
-06
-00
-00
-93
-91
-87
-06
-00
-00
-87
-0e
-00
-00
-87
-0e
-00
-00
-66
-92
-66
-93
-66
-87
-d9
-66
-87
-0e
-00
-00
-66
-87
-06
-00
-00
-e4
-37
-e5
-63
-66
-e5
-64
-ec
-ed
-66
-ed
-e6
-37
-e7
-42
-66
-e7
-4d
-ee
-ef
-66
-ef
-8d
-1e
-05
-00
-66
-8d
-1e
-20
-00
-c5
-36
-00
-00
-c5
-06
-01
-00
-c4
-3e
-05
-00
-66
-c5
-06
-07
-00
-66
-c4
-1e
-09
-00
-66
-0f
-b6
-26
-0b
-00
-66
-0f
-b4
-0e
-0d
-00
-66
-0f
-b5
-16
-0f
-00
-66
-69
-c0
-04
-00
-00
-00
-d5
-0a
-d4
-0a
-d5
-05
-d4
-0a
-c0
-e0
-05
-d0
-e3
-d2
-e1
-c1
-e8
-05
-d1
-eb
-d3
-e9
-0f
-a4
-d8
-05
-0f
-ad
-d1
-66
-0f
-a4
-d1
-0a
-66
-0f
-a5
-d8
-c3
-cb
-c2
-08
-00
-ca
-10
-00
-c8
-0a
-00
-0c
-0f
-92
-d0
-0f
-92
-16
-00
-00
-cd
-0a
-d9
-06
-00
-00
-dd
-06
-04
-00
-db
-2e
-10
-00
-d9
-c2
-d9
-1e
-00
-00
-d9
-dc
-df
-06
-00
-00
-db
-06
-04
-00
-df
-2e
-08
-00
-df
-26
-64
-00
-df
-26
-0a
-00
-d9
-16
-01
-00
-dd
-16
-08
-00
-dd
-d1
-d9
-c9
-d9
-c9
-d9
-ca
-d9
-ca
-d8
-16
-00
-00
-dc
-16
-08
-00
-d8
-d1
-d8
-d0
-dd
-e7
-dd
-ed
-d8
-06
-0a
-00
-dc
-06
-05
-00
-d8
-c0
-d8
-c5
-dc
-c7
-dc
-c6
-de
-c1
-de
-c2
-de
-c5
-de
-06
-0a
-00
-da
-26
-04
-00
-d9
-2e
-00
-00
-d9
-3e
-04
-00
-9b
-d9
-3e
-04
-00
-dd
-3e
-08
-00
-df
-e0
-9b
-dd
-3e
-00
-00
-9b
-df
-e0
-dd
-c1
-df
-c0
-72
-02
-72
-00
-74
-fe
-0f
-84
-fa
-ff
-e2
-f8
-e3
-f6
-67
-e3
-f3
-e8
-f0
-ff
-ff
-16
-bc
-01
-66
-ff
-16
-bc
-01
-eb
-e5
-e9
-e2
-ff
-ff
-2e
-bc
-01
-66
-ff
-2e
-bc
-01
-ff
-1e
-bc
-01
-56
-66
-56
-56
+++ /dev/null
-lds ax,[1]
-lds ax,word [1]
-lds ax,dword [1]
-lds eax,[1]
-lds eax,word [1]
-lds eax,dword [1]
+++ /dev/null
--:2: invalid combination of opcode and operands
--:3: invalid combination of opcode and operands
--:5: invalid combination of opcode and operands
--:6: invalid combination of opcode and operands
+++ /dev/null
-[bits 16]
-foo: a32 loop foo ; 67 E2 FD
-bar: loop bar, ecx ; 67 E2 FD
-
-[bits 32]
-baz: a16 loop baz ; 67 E2 FD
-qux: loop qux, cx ; 67 E2 FD
+++ /dev/null
-67
-e2
-fd
-67
-e2
-fd
-67
-e2
-fd
-67
-e2
-fd
+++ /dev/null
-[bits 64]
-mov ax, [word 0]
-;a16 mov ax, [0]
-mov ax, [ax]
-mov eax, [rip+rcx]
-mov rbx, [rcx+ebx]
-mov ah, [r8]
+++ /dev/null
--:2: 16-bit addresses not supported in 64-bit mode
--:4: 16-bit addresses not supported in 64-bit mode
--:5: invalid effective address
--:6: invalid effective address
--:7: invalid combination of operands and effective address
+++ /dev/null
-[bits 64]
-mov ax, [0] ; 66 A1 00 00 00 00 00 00 00 00
-mov rax, [qword 0] ; 48 A1 00 00 00 00 00 00 00 00
-mov rax, [dword 0] ; 67 48 A1 00 00 00 00
-mov al, [0xfedcba9876543210] ; 48 A0 10 32 54 76 98 BA DC FE
-a32 mov rax, [0] ; 67 48 A1 00 00 00 00
-a32 mov eax, [0] ; 67 A1 00 00 00 00
-mov ecx, [0] ; 8B 0C 25 00 00 00 00
-mov edx, [dword 0] ; 8B 14 25 00 00 00 00
-a32 mov rbx, [0] ; 67 48 8B 1C 25 00 00 00 00
-mov ebx, [rcx] ; 8B 19
-mov r8, [r9] ; 4D 8B 01
-mov ecx, [ebx] ; 67 8B 0B
-mov edx, [rip] ; 8B 15
-a32 mov rcx, [rip+5] ; 67 48 8B 4D 05
-mov rbx, [rax+rbx*4] ; 48 8B 1C 98
-mov rdx, [rsp] ; 48 8B 14 24
-mov rax, [r12] ; 49 8B 04 24
-mov rcx, [rbp] ; 48 8B 4D 00
-mov rbx, [r13] ; 49 8B 5D 00
-mov ah, [rip] ; 8A 25
-mov bh, [rcx] ; 8A 39
+++ /dev/null
-66
-a1
-00
-00
-00
-00
-00
-00
-00
-00
-48
-a1
-00
-00
-00
-00
-00
-00
-00
-00
-67
-48
-a1
-00
-00
-00
-00
-a0
-10
-32
-54
-76
-98
-ba
-dc
-fe
-67
-48
-a1
-00
-00
-00
-00
-67
-a1
-00
-00
-00
-00
-8b
-0c
-25
-00
-00
-00
-00
-8b
-14
-25
-00
-00
-00
-00
-67
-48
-8b
-1c
-25
-00
-00
-00
-00
-8b
-19
-4d
-8b
-01
-67
-8b
-0b
-8b
-15
-67
-48
-8b
-4d
-05
-48
-8b
-1c
-98
-48
-8b
-14
-24
-49
-8b
-04
-24
-48
-8b
-4d
-00
-49
-8b
-5d
-00
-8a
-25
-8a
-39
+++ /dev/null
-[bits 32]
-off equ -4
-pos equ 4
-
-mov [ebp+off], eax
-mov [ebp+pos], eax
-mov [ebp-off], eax
-mov [ebp-pos], eax
+++ /dev/null
-89
-45
-fc
-89
-45
-04
-89
-45
-04
-89
-45
-fc
+++ /dev/null
-[bits 64]
-mov bh, r8b
-mov r8b, ch
-push es
-pop fs
-pushaw
-popa
-lds eax, [5]
-aas
-das
-aad
-into
-salc
-[bits 32]
-xmm9:
-rax:
-rdx:
-cdqe
-swapgs
+++ /dev/null
--:2: invalid combination of opcode and operands
--:3: invalid combination of opcode and operands
--:4: warning: `es' segment register ignored in 64-bit mode
--:4: invalid combination of opcode and operands
--:6: `pushaw' invalid in 64-bit mode
--:6: invalid combination of opcode and operands
--:7: `popa' invalid in 64-bit mode
--:7: invalid combination of opcode and operands
--:8: `lds' invalid in 64-bit mode
--:8: invalid combination of opcode and operands
--:9: `aas' invalid in 64-bit mode
--:9: invalid combination of opcode and operands
--:10: `das' invalid in 64-bit mode
--:10: invalid combination of opcode and operands
--:11: `aad' invalid in 64-bit mode
--:11: invalid combination of opcode and operands
--:12: `into' invalid in 64-bit mode
--:12: invalid combination of opcode and operands
--:13: `salc' invalid in 64-bit mode
--:13: invalid combination of opcode and operands
--:15: warning: `xmm9' is a register in 64-bit mode
--:16: warning: `rax' is a register in 64-bit mode
--:17: warning: `rdx' is a register in 64-bit mode
--:18: warning: `cdqe' is an instruction in 64-bit mode
--:19: warning: `swapgs' is an instruction in 64-bit mode
+++ /dev/null
-[bits 64]
-mov ah, 5
-mov ax, 5
-mov eax, 5
-mov rax, 5
-mov ah, bl
-mov bl, r8b
-mov sil, r9b
-mov r10w, r11w
-mov r15d, r12d
-mov r13, r14
-inc ebx
-dec ecx
+++ /dev/null
-b4
-05
-66
-b8
-05
-00
-b8
-05
-00
-00
-00
-48
-b8
-05
-00
-00
-00
-00
-00
-00
-00
-88
-dc
-44
-88
-c3
-44
-88
-ce
-66
-45
-89
-da
-45
-89
-e7
-4d
-89
-f5
-ff
-c3
-ff
-c9
+++ /dev/null
-[bits 32]
-o32 mov ax, bx
-o16 mov ax, bx
-mov ax, bx
-
-o32 mov eax, ebx
-o16 mov eax, ebx
-mov eax, ebx
-
-[bits 16]
-o32 mov ax, bx
-o16 mov ax, bx
-mov ax, bx
-
-o32 mov eax, ebx
-o16 mov eax, ebx
-mov eax, ebx
+++ /dev/null
-89
-d8
-66
-89
-d8
-66
-89
-d8
-89
-d8
-66
-89
-d8
-89
-d8
-66
-89
-d8
-89
-d8
-89
-d8
-66
-89
-d8
-89
-d8
-66
-89
-d8
+++ /dev/null
-mov ax,1
-mov ax,word 1
-mov ax,byte 1
+++ /dev/null
--:3: invalid combination of opcode and operands
+++ /dev/null
-ret
-ret 4
-ret word 2
-retn 6
-retn word 2
-retf 8
-retf word 2
+++ /dev/null
-c3
-c2
-04
-00
-c2
-02
-00
-c2
-06
-00
-c2
-02
-00
-ca
-08
-00
-ca
-02
-00
+++ /dev/null
-mov [0], ds
-mov word [0], ds
-mov ax, ds
-mov eax, ds
-mov ds, ax
-mov ds, eax
-mov ds, [0]
-mov ds, word [0]
-mov word ds, [0]
+++ /dev/null
-8c
-1e
-00
-00
-8c
-1e
-00
-00
-8c
-d8
-66
-8c
-d8
-8e
-d8
-8e
-d8
-8e
-1e
-00
-00
-8e
-1e
-00
-00
-8e
-1e
-00
-00
+++ /dev/null
-blah equ 1
-
-shl al, 1
-shl al, 2-1
-shl al, blah
-shl al, 2-blah
+++ /dev/null
-d0
-e0
-d0
-e0
-d0
-e0
-d0
-e0
+++ /dev/null
-#! /bin/sh
-# $IdPath$
-${srcdir}/out_test.sh x86_test src/arch/x86/tests "x86 arch" "-f bin" ""
-exit $?
+++ /dev/null
-and_label:
-jmp and_label
+++ /dev/null
-/*
- * x86 architecture description
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-
-#include "arch.h"
-
-#include "x86arch.h"
-
-
-unsigned char yasm_x86_LTX_mode_bits = 0;
-
-
-static void
-x86_initialize(void)
-{
-}
-
-static void
-x86_cleanup(void)
-{
-}
-
-int
-yasm_x86__directive(const char *name, yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp, unsigned long lindex)
-{
- yasm_valparam *vp;
- const yasm_intnum *intn;
- long lval;
-
- if (yasm__strcasecmp(name, "bits") == 0) {
- if ((vp = yasm_vps_first(valparams)) && !vp->val &&
- vp->param != NULL &&
- (intn = yasm_expr_get_intnum(&vp->param, NULL)) != NULL &&
- (lval = yasm_intnum_get_int(intn)) &&
- (lval == 16 || lval == 32 || lval == 64))
- yasm_x86_LTX_mode_bits = (unsigned char)lval;
- else
- yasm__error(lindex, N_("invalid argument to [%s]"), "BITS");
- return 0;
- } else
- return 1;
-}
-
-unsigned int
-yasm_x86__get_reg_size(unsigned long reg)
-{
- switch ((x86_expritem_reg_size)(reg & ~0xF)) {
- case X86_REG8:
- case X86_REG8X:
- return 1;
- case X86_REG16:
- return 2;
- case X86_REG32:
- case X86_CRREG:
- case X86_DRREG:
- case X86_TRREG:
- return 4;
- case X86_REG64:
- case X86_MMXREG:
- return 8;
- case X86_XMMREG:
- return 16;
- case X86_FPUREG:
- return 10;
- default:
- yasm_internal_error(N_("unknown register size"));
- }
- return 0;
-}
-
-void
-yasm_x86__reg_print(FILE *f, unsigned long reg)
-{
- static const char *name8[] = {"al","cl","dl","bl","ah","ch","dh","bh"};
- static const char *name8x[] = {
- "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
- "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
- };
- static const char *name16[] = {
- "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
- "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
- };
- static const char *name32[] = {
- "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
- "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
- };
- static const char *name64[] = {
- "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
- };
-
- switch ((x86_expritem_reg_size)(reg&~0xF)) {
- case X86_REG8:
- fprintf(f, "%s", name8[reg&0xF]);
- break;
- case X86_REG8X:
- fprintf(f, "%s", name8x[reg&0xF]);
- break;
- case X86_REG16:
- fprintf(f, "%s", name16[reg&0xF]);
- break;
- case X86_REG32:
- fprintf(f, "%s", name32[reg&0xF]);
- break;
- case X86_REG64:
- fprintf(f, "%s", name64[reg&0xF]);
- break;
- case X86_MMXREG:
- fprintf(f, "mm%d", (int)(reg&0xF));
- break;
- case X86_XMMREG:
- fprintf(f, "xmm%d", (int)(reg&0xF));
- break;
- case X86_CRREG:
- fprintf(f, "cr%d", (int)(reg&0xF));
- break;
- case X86_DRREG:
- fprintf(f, "dr%d", (int)(reg&0xF));
- break;
- case X86_TRREG:
- fprintf(f, "tr%d", (int)(reg&0xF));
- break;
- case X86_FPUREG:
- fprintf(f, "st%d", (int)(reg&0xF));
- break;
- default:
- yasm_internal_error(N_("unknown register size"));
- }
-}
-
-void
-yasm_x86__segreg_print(FILE *f, unsigned long segreg)
-{
- static const char *name[] = {"es","cs","ss","ds","fs","gs"};
- fprintf(f, "%s", name[segreg&7]);
-}
-
-void
-yasm_x86__handle_prefix(yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex)
-{
- switch((x86_parse_insn_prefix)data[0]) {
- case X86_LOCKREP:
- yasm_x86__bc_insn_set_lockrep_prefix(bc, (unsigned char)data[1],
- lindex);
- break;
- case X86_ADDRSIZE:
- yasm_x86__bc_insn_addrsize_override(bc, (unsigned char)data[1]);
- break;
- case X86_OPERSIZE:
- yasm_x86__bc_insn_opersize_override(bc, (unsigned char)data[1]);
- break;
- }
-}
-
-void
-yasm_x86__handle_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex)
-{
- yasm_x86__ea_set_segment(yasm_x86__bc_insn_get_ea(bc),
- (unsigned char)(segreg>>8), lindex);
-}
-
-void
-yasm_x86__handle_seg_override(yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex)
-{
- yasm_x86__ea_set_segment(ea, (unsigned char)(segreg>>8), lindex);
-}
-
-/* Define arch structure -- see arch.h for details */
-yasm_arch yasm_x86_LTX_arch = {
- "x86 (IA-32, x86-64)",
- "x86",
- x86_initialize,
- x86_cleanup,
- {
- yasm_x86__switch_cpu,
- yasm_x86__check_identifier,
- yasm_x86__directive,
- yasm_x86__new_insn,
- yasm_x86__handle_prefix,
- yasm_x86__handle_seg_prefix,
- yasm_x86__handle_seg_override,
- yasm_x86__ea_new_expr
- },
- {
- X86_BYTECODE_TYPE_MAX,
- yasm_x86__bc_delete,
- yasm_x86__bc_print,
- yasm_x86__bc_resolve,
- yasm_x86__bc_tobytes
- },
- yasm_x86__floatnum_tobytes,
- yasm_x86__intnum_tobytes,
- yasm_x86__get_reg_size,
- yasm_x86__reg_print,
- yasm_x86__segreg_print,
- NULL, /* x86_ea_data_delete */
- yasm_x86__ea_data_print
-};
+++ /dev/null
-/* $IdPath$
- * x86 Architecture header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_X86ARCH_H
-#define YASM_X86ARCH_H
-
-typedef enum {
- X86_BC_INSN = YASM_BYTECODE_TYPE_BASE,
- X86_BC_JMPREL
-} x86_bytecode_type;
-#define X86_BYTECODE_TYPE_MAX X86_BC_JMPREL+1
-
-/* 0-15 (low 4 bits) used for register number, stored in same data area.
- * Note 8-15 are only valid for some registers, and only in 64-bit mode.
- */
-typedef enum {
- X86_REG8 = 0x1<<4,
- X86_REG8X = 0x2<<4, /* 64-bit mode only, REX prefix version of REG8 */
- X86_REG16 = 0x3<<4,
- X86_REG32 = 0x4<<4,
- X86_REG64 = 0x5<<4, /* 64-bit mode only */
- X86_FPUREG = 0x6<<4,
- X86_MMXREG = 0x7<<4,
- X86_XMMREG = 0x8<<4,
- X86_CRREG = 0x9<<4,
- X86_DRREG = 0xA<<4,
- X86_TRREG = 0xB<<4,
- X86_RIP = 0xC<<4 /* 64-bit mode only, always RIP (regnum ignored) */
-} x86_expritem_reg_size;
-
-typedef enum {
- X86_LOCKREP = 1,
- X86_ADDRSIZE,
- X86_OPERSIZE
-} x86_parse_insn_prefix;
-
-typedef enum {
- X86_NEAR = 1,
- X86_SHORT,
- X86_FAR,
- X86_TO
-} x86_parse_targetmod;
-
-typedef enum {
- JR_NONE,
- JR_SHORT,
- JR_NEAR,
- JR_SHORT_FORCED,
- JR_NEAR_FORCED
-} x86_jmprel_opcode_sel;
-
-typedef enum {
- X86_REX_W = 3,
- X86_REX_R = 2,
- X86_REX_X = 1,
- X86_REX_B = 0
-} x86_rex_bit_pos;
-
-/* Sets REX (4th bit) and 3 LS bits from register size/number. Returns 1 if
- * impossible to fit reg into REX, otherwise returns 0. Input parameter rexbit
- * indicates bit of REX to use if REX is needed. Will not modify REX if not
- * in 64-bit mode or if it wasn't needed to express reg.
- */
-int yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
- unsigned long reg, unsigned char bits,
- x86_rex_bit_pos rexbit);
-
-void yasm_x86__ea_set_segment(/*@null@*/ yasm_effaddr *ea,
- unsigned char segment, unsigned long lindex);
-void yasm_x86__ea_set_disponly(yasm_effaddr *ea);
-yasm_effaddr *yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex,
- unsigned char bits);
-yasm_effaddr *yasm_x86__ea_new_imm(/*@keep@*/ yasm_expr *imm,
- unsigned char im_len);
-yasm_effaddr *yasm_x86__ea_new_expr(/*@keep@*/ yasm_expr *e);
-
-/*@observer@*/ /*@null@*/ yasm_effaddr *yasm_x86__bc_insn_get_ea
- (/*@null@*/ yasm_bytecode *bc);
-
-void yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc,
- unsigned char opersize);
-void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc,
- unsigned char addrsize);
-void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc,
- unsigned char prefix,
- unsigned long lindex);
-
-/* Structure with *all* inputs passed to x86_bytecode_new_insn().
- * IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the
- * function (it doesn't make a copy).
- */
-typedef struct x86_new_insn_data {
- unsigned long lindex;
- /*@keep@*/ /*@null@*/ yasm_effaddr *ea;
- /*@keep@*/ /*@null@*/ yasm_expr *imm;
- unsigned char opersize;
- unsigned char op_len;
- unsigned char op[3];
- unsigned char spare; /* bits to go in 'spare' field of ModRM */
- unsigned char rex;
- unsigned char im_len;
- unsigned char im_sign;
- unsigned char shift_op;
- unsigned char signext_imm8_op;
-} x86_new_insn_data;
-
-yasm_bytecode *yasm_x86__bc_new_insn(x86_new_insn_data *d);
-
-/* Structure with *all* inputs passed to x86_bytecode_new_jmprel().
- * Pass 0 for the opcode_len if that version of the opcode doesn't exist.
- */
-typedef struct x86_new_jmprel_data {
- unsigned long lindex;
- /*@keep@*/ yasm_expr *target;
- x86_jmprel_opcode_sel op_sel;
- unsigned char short_op_len;
- unsigned char short_op[3];
- unsigned char near_op_len;
- unsigned char near_op[3];
- unsigned char addrsize;
- unsigned char opersize;
-} x86_new_jmprel_data;
-
-yasm_bytecode *yasm_x86__bc_new_jmprel(x86_new_jmprel_data *d);
-
-extern unsigned char yasm_x86_LTX_mode_bits;
-
-void yasm_x86__bc_delete(yasm_bytecode *bc);
-void yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-yasm_bc_resolve_flags yasm_x86__bc_resolve
- (yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
-int yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr);
-
-int yasm_x86__expr_checkea
- (yasm_expr **ep, unsigned char *addrsize, unsigned char bits,
- unsigned char nosplit, unsigned char *displen, unsigned char *modrm,
- unsigned char *v_modrm, unsigned char *n_modrm, unsigned char *sib,
- unsigned char *v_sib, unsigned char *n_sib, unsigned char *rex,
- yasm_calc_bc_dist_func calc_bc_dist);
-
-void yasm_x86__switch_cpu(const char *cpuid, unsigned long lindex);
-
-yasm_arch_check_id_retval yasm_x86__check_identifier
- (unsigned long data[2], const char *id, unsigned long lindex);
-
-int yasm_x86__directive(const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
-
-/*@null@*/ yasm_bytecode *yasm_x86__new_insn
- (const unsigned long data[2], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
-
-void yasm_x86__handle_prefix(yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex);
-
-void yasm_x86__handle_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex);
-
-void yasm_x86__handle_seg_override(yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex);
-
-int yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e);
-int yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e,
- const yasm_bytecode *bc, int rel);
-
-unsigned int yasm_x86__get_reg_size(unsigned long reg);
-
-void yasm_x86__reg_print(FILE *f, unsigned long reg);
-
-void yasm_x86__segreg_print(FILE *f, unsigned long segreg);
-
-void yasm_x86__ea_data_print(FILE *f, int indent_level,
- const yasm_effaddr *ea);
-
-#endif
+++ /dev/null
-/*
- * x86 bytecode utility functions
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-#include "arch.h"
-
-#include "x86arch.h"
-
-#include "bc-int.h"
-
-
-typedef struct x86_effaddr {
- yasm_effaddr ea; /* base structure */
-
- unsigned char segment; /* segment override, 0 if none */
-
- /* How the spare (register) bits in Mod/RM are handled:
- * Even if valid_modrm=0, the spare bits are still valid (don't overwrite!)
- * They're set in bytecode_new_insn().
- */
- unsigned char modrm;
- unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
- unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
-
- unsigned char sib;
- unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
- unsigned char need_sib; /* 1 if SIB byte needed, 0 if not,
- 0xff if unknown */
-} x86_effaddr;
-
-typedef struct x86_insn {
- yasm_bytecode bc; /* base structure */
-
- /*@null@*/ x86_effaddr *ea; /* effective address */
-
- /*@null@*/ yasm_immval *imm;/* immediate or relative value */
-
- unsigned char opcode[3]; /* opcode */
- unsigned char opcode_len;
-
- unsigned char addrsize; /* 0 or =mode_bits => no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
-
- unsigned char rex; /* REX x86-64 extension, 0 if none,
- 0xff if not allowed (high 8 bit reg used) */
-
- /* HACK, but a space-saving one: shift opcodes have an immediate
- * form and a ,1 form (with no immediate). In the parser, we
- * set this and opcode_len=1, but store the ,1 version in the
- * second byte of the opcode array. We then choose between the
- * two versions once we know the actual value of imm (because we
- * don't know it in the parser module).
- *
- * A override to force the imm version should just leave this at
- * 0. Then later code won't know the ,1 version even exists.
- * TODO: Figure out how this affects CPU flags processing.
- *
- * Call x86_SetInsnShiftFlag() to set this flag to 1.
- */
- unsigned char shift_op;
-
- /* HACK, similar to that for shift_op above, for optimizing instructions
- * that take a sign-extended imm8 as well as imm values (eg, the arith
- * instructions and a subset of the imul instructions).
- */
- unsigned char signext_imm8_op;
-
- unsigned char mode_bits;
-} x86_insn;
-
-typedef struct x86_jmprel {
- yasm_bytecode bc; /* base structure */
-
- yasm_expr *target; /* target location */
-
- struct {
- unsigned char opcode[3];
- unsigned char opcode_len; /* 0 = no opc for this version */
- } shortop, nearop;
-
- /* which opcode are we using? */
- /* The *FORCED forms are specified in the source as such */
- x86_jmprel_opcode_sel op_sel;
-
- unsigned char addrsize; /* 0 or =mode_bits => no override */
- unsigned char opersize; /* 0 indicates no override */
- unsigned char lockrep_pre; /* 0 indicates no prefix */
-
- unsigned char mode_bits;
-} x86_jmprel;
-
-
-int
-yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
- unsigned long reg, unsigned char bits,
- x86_rex_bit_pos rexbit)
-{
- *low3 = (unsigned char)(reg&7);
-
- if (bits == 64) {
- x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xF);
-
- if (size == X86_REG8X || (reg & 0xF) >= 8) {
- if (*rex == 0xff)
- return 1;
- *rex |= 0x40 | (((reg & 8) >> 3) << rexbit);
- } else if (size == X86_REG8 && (reg & 7) >= 4) {
- /* AH/BH/CH/DH, so no REX allowed */
- if (*rex != 0 && *rex != 0xff)
- return 1;
- *rex = 0xff;
- }
- }
-
- return 0;
-}
-
-/*@-compmempass -mustfree@*/
-yasm_bytecode *
-yasm_x86__bc_new_insn(x86_new_insn_data *d)
-{
- x86_insn *insn;
-
- insn = (x86_insn *)yasm_bc_new_common((yasm_bytecode_type)X86_BC_INSN,
- sizeof(x86_insn), d->lindex);
-
- insn->ea = (x86_effaddr *)d->ea;
- if (d->ea) {
- insn->ea->modrm &= 0xC7; /* zero spare/reg bits */
- insn->ea->modrm |= (d->spare << 3) & 0x38; /* plug in provided bits */
- }
-
- if (d->imm) {
- insn->imm = yasm_imm_new_expr(d->imm);
- insn->imm->len = d->im_len;
- insn->imm->sign = d->im_sign;
- } else
- insn->imm = NULL;
-
- insn->opcode[0] = d->op[0];
- insn->opcode[1] = d->op[1];
- insn->opcode[2] = d->op[2];
- insn->opcode_len = d->op_len;
-
- insn->addrsize = 0;
- insn->opersize = d->opersize;
- insn->lockrep_pre = 0;
- insn->rex = d->rex;
- insn->shift_op = d->shift_op;
- insn->signext_imm8_op = d->signext_imm8_op;
-
- insn->mode_bits = yasm_x86_LTX_mode_bits;
-
- return (yasm_bytecode *)insn;
-}
-/*@=compmempass =mustfree@*/
-
-/*@-compmempass -mustfree@*/
-yasm_bytecode *
-yasm_x86__bc_new_jmprel(x86_new_jmprel_data *d)
-{
- x86_jmprel *jmprel;
-
- jmprel = (x86_jmprel *)
- yasm_bc_new_common((yasm_bytecode_type)X86_BC_JMPREL,
- sizeof(x86_jmprel), d->lindex);
-
- jmprel->target = d->target;
- jmprel->op_sel = d->op_sel;
-
- if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0))
- yasm__error(d->lindex,
- N_("no SHORT form of that jump instruction exists"));
- if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0))
- yasm__error(d->lindex,
- N_("no NEAR form of that jump instruction exists"));
-
- jmprel->shortop.opcode[0] = d->short_op[0];
- jmprel->shortop.opcode[1] = d->short_op[1];
- jmprel->shortop.opcode[2] = d->short_op[2];
- jmprel->shortop.opcode_len = d->short_op_len;
-
- jmprel->nearop.opcode[0] = d->near_op[0];
- jmprel->nearop.opcode[1] = d->near_op[1];
- jmprel->nearop.opcode[2] = d->near_op[2];
- jmprel->nearop.opcode_len = d->near_op_len;
-
- jmprel->addrsize = d->addrsize;
- jmprel->opersize = d->opersize;
- jmprel->lockrep_pre = 0;
-
- jmprel->mode_bits = yasm_x86_LTX_mode_bits;
-
- return (yasm_bytecode *)jmprel;
-}
-/*@=compmempass =mustfree@*/
-
-void
-yasm_x86__ea_set_segment(yasm_effaddr *ea, unsigned char segment,
- unsigned long lindex)
-{
- x86_effaddr *x86_ea = (x86_effaddr *)ea;
-
- if (!ea)
- return;
-
- if (segment != 0 && x86_ea->segment != 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("multiple segment overrides, using leftmost"));
-
- x86_ea->segment = segment;
-}
-
-void
-yasm_x86__ea_set_disponly(yasm_effaddr *ea)
-{
- x86_effaddr *x86_ea = (x86_effaddr *)ea;
-
- x86_ea->valid_modrm = 0;
- x86_ea->need_modrm = 0;
- x86_ea->valid_sib = 0;
- x86_ea->need_sib = 0;
-}
-
-yasm_effaddr *
-yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, unsigned char bits)
-{
- x86_effaddr *x86_ea;
- unsigned char rm;
-
- if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
- return NULL;
-
- x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
-
- x86_ea->ea.disp = (yasm_expr *)NULL;
- x86_ea->ea.len = 0;
- x86_ea->ea.nosplit = 0;
- x86_ea->segment = 0;
- x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */
- x86_ea->valid_modrm = 1;
- x86_ea->need_modrm = 1;
- x86_ea->sib = 0;
- x86_ea->valid_sib = 0;
- x86_ea->need_sib = 0;
-
- return (yasm_effaddr *)x86_ea;
-}
-
-yasm_effaddr *
-yasm_x86__ea_new_expr(yasm_expr *e)
-{
- x86_effaddr *x86_ea;
-
- x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
-
- x86_ea->ea.disp = e;
- x86_ea->ea.len = 0;
- x86_ea->ea.nosplit = 0;
- x86_ea->segment = 0;
- x86_ea->modrm = 0;
- x86_ea->valid_modrm = 0;
- x86_ea->need_modrm = 1;
- x86_ea->sib = 0;
- x86_ea->valid_sib = 0;
- /* We won't know whether we need an SIB until we know more about expr and
- * the BITS/address override setting.
- */
- x86_ea->need_sib = 0xff;
-
- return (yasm_effaddr *)x86_ea;
-}
-
-/*@-compmempass@*/
-yasm_effaddr *
-yasm_x86__ea_new_imm(yasm_expr *imm, unsigned char im_len)
-{
- x86_effaddr *x86_ea;
-
- x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
-
- x86_ea->ea.disp = imm;
- x86_ea->ea.len = im_len;
- x86_ea->ea.nosplit = 0;
- x86_ea->segment = 0;
- x86_ea->modrm = 0;
- x86_ea->valid_modrm = 0;
- x86_ea->need_modrm = 0;
- x86_ea->sib = 0;
- x86_ea->valid_sib = 0;
- x86_ea->need_sib = 0;
-
- return (yasm_effaddr *)x86_ea;
-}
-/*@=compmempass@*/
-
-yasm_effaddr *
-yasm_x86__bc_insn_get_ea(yasm_bytecode *bc)
-{
- if (!bc)
- return NULL;
-
- if ((x86_bytecode_type)bc->type != X86_BC_INSN)
- yasm_internal_error(N_("Trying to get EA of non-instruction"));
-
- return (yasm_effaddr *)(((x86_insn *)bc)->ea);
-}
-
-void
-yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, unsigned char opersize)
-{
- x86_insn *insn;
- x86_jmprel *jmprel;
-
- if (!bc)
- return;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- insn->opersize = opersize;
- break;
- case X86_BC_JMPREL:
- jmprel = (x86_jmprel *)bc;
- jmprel->opersize = opersize;
- break;
- default:
- yasm_internal_error(
- N_("OperSize override applied to non-instruction"));
- }
-}
-
-void
-yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, unsigned char addrsize)
-{
- x86_insn *insn;
- x86_jmprel *jmprel;
-
- if (!bc)
- return;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- insn->addrsize = addrsize;
- break;
- case X86_BC_JMPREL:
- jmprel = (x86_jmprel *)bc;
- jmprel->addrsize = addrsize;
- break;
- default:
- yasm_internal_error(
- N_("AddrSize override applied to non-instruction"));
- }
-}
-
-void
-yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, unsigned char prefix,
- unsigned long lindex)
-{
- x86_insn *insn;
- x86_jmprel *jmprel;
- unsigned char *lockrep_pre = (unsigned char *)NULL;
-
- if (!bc)
- return;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- lockrep_pre = &insn->lockrep_pre;
- break;
- case X86_BC_JMPREL:
- jmprel = (x86_jmprel *)bc;
- lockrep_pre = &jmprel->lockrep_pre;
- break;
- default:
- yasm_internal_error(
- N_("LockRep prefix applied to non-instruction"));
- }
-
- if (*lockrep_pre != 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("multiple LOCK or REP prefixes, using leftmost"));
-
- *lockrep_pre = prefix;
-}
-
-void
-yasm_x86__bc_delete(yasm_bytecode *bc)
-{
- x86_insn *insn;
- x86_jmprel *jmprel;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- if (insn->ea)
- yasm_ea_delete((yasm_effaddr *)insn->ea);
- if (insn->imm) {
- yasm_expr_delete(insn->imm->val);
- yasm_xfree(insn->imm);
- }
- break;
- case X86_BC_JMPREL:
- jmprel = (x86_jmprel *)bc;
- yasm_expr_delete(jmprel->target);
- break;
- }
-}
-
-void
-yasm_x86__ea_data_print(FILE *f, int indent_level, const yasm_effaddr *ea)
-{
- const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
- fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "",
- (unsigned int)x86_ea->segment);
- fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "",
- (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm,
- (unsigned int)x86_ea->need_modrm);
- fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "",
- (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib,
- (unsigned int)x86_ea->need_sib);
-}
-
-void
-yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
-{
- const x86_insn *insn;
- const x86_jmprel *jmprel;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (const x86_insn *)bc;
- fprintf(f, "%*s_Instruction_\n", indent_level, "");
- fprintf(f, "%*sEffective Address:", indent_level, "");
- if (insn->ea) {
- fprintf(f, "\n");
- yasm_ea_print(f, indent_level+1, (yasm_effaddr *)insn->ea);
- } else
- fprintf(f, " (nil)\n");
- fprintf(f, "%*sImmediate Value:", indent_level, "");
- if (!insn->imm)
- fprintf(f, " (nil)\n");
- else {
- indent_level++;
- fprintf(f, "\n%*sVal=", indent_level, "");
- if (insn->imm->val)
- yasm_expr_print(f, insn->imm->val);
- else
- fprintf(f, "(nil-SHOULDN'T HAPPEN)");
- fprintf(f, "\n");
- fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
- (unsigned int)insn->imm->len,
- (unsigned int)insn->imm->sign);
- indent_level--;
- }
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
- "", (unsigned int)insn->opcode[0],
- (unsigned int)insn->opcode[1],
- (unsigned int)insn->opcode[2],
- (unsigned int)insn->opcode_len);
- fprintf(f,
- "%*sAddrSize=%u OperSize=%u LockRepPre=%02x REX=%03o\n",
- indent_level, "",
- (unsigned int)insn->addrsize,
- (unsigned int)insn->opersize,
- (unsigned int)insn->lockrep_pre,
- (unsigned int)insn->rex);
- fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "",
- (unsigned int)insn->shift_op,
- (unsigned int)insn->mode_bits);
- break;
- case X86_BC_JMPREL:
- jmprel = (const x86_jmprel *)bc;
- fprintf(f, "%*s_Relative Jump_\n", indent_level, "");
- fprintf(f, "%*sTarget=", indent_level, "");
- yasm_expr_print(f, jmprel->target);
- fprintf(f, "\n%*sShort Form:\n", indent_level, "");
- if (jmprel->shortop.opcode_len == 0)
- fprintf(f, "%*sNone\n", indent_level+1, "");
- else
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
- indent_level+1, "",
- (unsigned int)jmprel->shortop.opcode[0],
- (unsigned int)jmprel->shortop.opcode[1],
- (unsigned int)jmprel->shortop.opcode[2],
- (unsigned int)jmprel->shortop.opcode_len);
- fprintf(f, "%*sNear Form:\n", indent_level, "");
- if (jmprel->nearop.opcode_len == 0)
- fprintf(f, "%*sNone\n", indent_level+1, "");
- else
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
- indent_level+1, "",
- (unsigned int)jmprel->nearop.opcode[0],
- (unsigned int)jmprel->nearop.opcode[1],
- (unsigned int)jmprel->nearop.opcode[2],
- (unsigned int)jmprel->nearop.opcode_len);
- fprintf(f, "%*sOpSel=", indent_level, "");
- switch (jmprel->op_sel) {
- case JR_NONE:
- fprintf(f, "None");
- break;
- case JR_SHORT:
- fprintf(f, "Short");
- break;
- case JR_NEAR:
- fprintf(f, "Near");
- break;
- case JR_SHORT_FORCED:
- fprintf(f, "Forced Short");
- break;
- case JR_NEAR_FORCED:
- fprintf(f, "Forced Near");
- break;
- default:
- fprintf(f, "UNKNOWN!!");
- break;
- }
- fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
- indent_level, "",
- (unsigned int)jmprel->addrsize,
- (unsigned int)jmprel->opersize,
- (unsigned int)jmprel->lockrep_pre);
- fprintf(f, "%*sBITS=%u\n", indent_level, "",
- (unsigned int)jmprel->mode_bits);
- break;
- }
-}
-
-static yasm_bc_resolve_flags
-x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
- const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- /*@null@*/ yasm_expr *temp;
- x86_effaddr *x86_ea = insn->ea;
- yasm_effaddr *ea = &x86_ea->ea;
- yasm_immval *imm = insn->imm;
- yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
-
- if (ea) {
- /* Create temp copy of disp, etc. */
- x86_effaddr eat = *x86_ea; /* structure copy */
- unsigned char displen = ea->len;
-
- if (ea->disp) {
- temp = yasm_expr_copy(ea->disp);
- assert(temp != NULL);
-
- /* Check validity of effective address and calc R/M bits of
- * Mod/RM byte and SIB byte. We won't know the Mod field
- * of the Mod/RM byte until we know more about the
- * displacement.
- */
- if (!yasm_x86__expr_checkea(&temp, &insn->addrsize,
- insn->mode_bits, ea->nosplit, &displen, &eat.modrm,
- &eat.valid_modrm, &eat.need_modrm, &eat.sib,
- &eat.valid_sib, &eat.need_sib, &insn->rex, calc_bc_dist)) {
- yasm_expr_delete(temp);
- /* failed, don't bother checking rest of insn */
- return YASM_BC_RESOLVE_UNKNOWN_LEN|YASM_BC_RESOLVE_ERROR;
- }
-
- yasm_expr_delete(temp);
-
- if (displen != 1) {
- /* Fits into a word/dword, or unknown. */
- retval = YASM_BC_RESOLVE_NONE; /* may not be smallest size */
-
- /* Handle unknown case, make displen word-sized */
- if (displen == 0xff)
- displen = (insn->addrsize == 32) ? 4U : 2U;
- }
-
- if (save) {
- *x86_ea = eat; /* structure copy */
- ea->len = displen;
- if (displen == 0 && ea->disp) {
- yasm_expr_delete(ea->disp);
- ea->disp = NULL;
- }
- }
- }
-
- /* Compute length of ea and add to total */
- *len += eat.need_modrm + eat.need_sib + displen;
- *len += (eat.segment != 0) ? 1 : 0;
- }
-
- if (imm) {
- const yasm_intnum *num;
- unsigned int immlen = imm->len;
-
- if (imm->val) {
- temp = yasm_expr_copy(imm->val);
- assert(temp != NULL);
-
- /* TODO: check imm->len vs. sized len from expr? */
-
- /* Handle shift_op special-casing */
- if (insn->shift_op && temp &&
- (num = yasm_expr_get_intnum(&temp, calc_bc_dist))) {
- if (num && yasm_intnum_get_uint(num) == 1) {
- /* We can use the ,1 form: subtract out the imm len
- * (as we add it back in below).
- */
- *len -= imm->len;
-
- if (save) {
- /* Make the ,1 form permanent. */
- insn->opcode[0] = insn->opcode[1];
- /* Delete imm, as it's not needed. */
- yasm_expr_delete(imm->val);
- yasm_xfree(imm);
- insn->imm = (yasm_immval *)NULL;
- }
- } else
- retval = YASM_BC_RESOLVE_NONE; /* we could still get ,1 */
-
- /* Not really necessary, but saves confusion over it. */
- if (save)
- insn->shift_op = 0;
- }
-
- yasm_expr_delete(temp);
- }
-
- *len += immlen;
- }
-
- *len += insn->opcode_len;
- *len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0;
- if (insn->opersize != 0 &&
- ((insn->mode_bits != 64 && insn->opersize != insn->mode_bits) ||
- (insn->mode_bits == 64 && insn->opersize == 16)))
- (*len)++;
- *len += (insn->lockrep_pre != 0) ? 1:0;
- *len += (insn->rex != 0 && insn->rex != 0xff) ? 1:0;
-
- return retval;
-}
-
-static yasm_bc_resolve_flags
-x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save,
- const yasm_bytecode *bc, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
- /*@null@*/ yasm_expr *temp;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- long rel;
- unsigned char opersize;
- int jrshort = 0;
-
- /* As opersize may be 0, figure out its "real" value. */
- opersize = (jmprel->opersize == 0) ? jmprel->mode_bits :
- jmprel->opersize;
-
- /* We only check to see if forced forms are actually legal if we're in
- * save mode. Otherwise we assume that they are legal.
- */
- switch (jmprel->op_sel) {
- case JR_SHORT_FORCED:
- /* 1 byte relative displacement */
- jrshort = 1;
- if (save) {
- temp = yasm_expr_copy(jmprel->target);
- num = yasm_expr_get_intnum(&temp, calc_bc_dist);
- if (!num) {
- yasm__error(bc->line,
- N_("short jump target external or out of segment"));
- yasm_expr_delete(temp);
- return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
- } else {
- rel = yasm_intnum_get_int(num);
- rel -= jmprel->shortop.opcode_len+1;
- yasm_expr_delete(temp);
- /* does a short form exist? */
- if (jmprel->shortop.opcode_len == 0) {
- yasm__error(bc->line, N_("short jump does not exist"));
- return YASM_BC_RESOLVE_ERROR |
- YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- /* short displacement must fit in -128 <= rel <= +127 */
- if (rel < -128 || rel > 127) {
- yasm__error(bc->line, N_("short jump out of range"));
- return YASM_BC_RESOLVE_ERROR |
- YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- }
- }
- break;
- case JR_NEAR_FORCED:
- /* 2/4 byte relative displacement (depending on operand size) */
- jrshort = 0;
- if (save) {
- if (jmprel->nearop.opcode_len == 0) {
- yasm__error(bc->line, N_("near jump does not exist"));
- return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- }
- break;
- default:
- /* Try to find shortest displacement based on difference between
- * target expr value and our (this bytecode's) offset. Note this
- * requires offset to be set BEFORE calling calc_len in order for
- * this test to be valid.
- */
- temp = yasm_expr_copy(jmprel->target);
- num = yasm_expr_get_intnum(&temp, calc_bc_dist);
- if (num) {
- rel = yasm_intnum_get_int(num);
- rel -= jmprel->shortop.opcode_len+1;
- /* short displacement must fit within -128 <= rel <= +127 */
- if (jmprel->shortop.opcode_len != 0 && rel >= -128 &&
- rel <= 127) {
- /* It fits into a short displacement. */
- jrshort = 1;
- } else if (jmprel->nearop.opcode_len != 0) {
- /* Near for now, but could get shorter in the future if
- * there's a short form available.
- */
- jrshort = 0;
- if (jmprel->shortop.opcode_len != 0)
- retval = YASM_BC_RESOLVE_NONE;
- } else {
- /* Doesn't fit into short, and there's no near opcode.
- * Error out if saving, otherwise just make it a short
- * (in the hopes that a short might make it possible for
- * it to actually be within short range).
- */
- if (save) {
- yasm__error(bc->line,
- N_("short jump out of range (near jump does not exist)"));
- return YASM_BC_RESOLVE_ERROR |
- YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- jrshort = 1;
- }
- } else {
- /* It's unknown. Thus, assume near displacement. If a near
- * opcode is not available, use a short opcode instead.
- * If we're saving, error if a near opcode is not available.
- */
- if (jmprel->nearop.opcode_len != 0) {
- if (jmprel->shortop.opcode_len != 0)
- retval = YASM_BC_RESOLVE_NONE;
- jrshort = 0;
- } else {
- if (save) {
- yasm__error(bc->line,
- N_("short jump out of range (near jump does not exist)"));
- return YASM_BC_RESOLVE_ERROR |
- YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- jrshort = 1;
- }
- }
- yasm_expr_delete(temp);
- break;
- }
-
- if (jrshort) {
- if (save)
- jmprel->op_sel = JR_SHORT;
- if (jmprel->shortop.opcode_len == 0)
- return YASM_BC_RESOLVE_UNKNOWN_LEN; /* that size not available */
-
- *len += jmprel->shortop.opcode_len + 1;
- } else {
- if (save)
- jmprel->op_sel = JR_NEAR;
- if (jmprel->nearop.opcode_len == 0)
- return YASM_BC_RESOLVE_UNKNOWN_LEN; /* that size not available */
-
- *len += jmprel->nearop.opcode_len;
- *len += (opersize == 32) ? 4 : 2;
- }
- *len += (jmprel->addrsize != 0 && jmprel->addrsize != jmprel->mode_bits) ?
- 1:0;
- *len += (jmprel->opersize != 0 && jmprel->opersize != jmprel->mode_bits) ?
- 1:0;
- *len += (jmprel->lockrep_pre != 0) ? 1:0;
-
- return retval;
-}
-
-yasm_bc_resolve_flags
-yasm_x86__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- return x86_bc_resolve_insn((x86_insn *)bc, &bc->len, save, sect,
- calc_bc_dist);
- case X86_BC_JMPREL:
- return x86_bc_resolve_jmprel((x86_jmprel *)bc, &bc->len, save, bc,
- sect, calc_bc_dist);
- default:
- break;
- }
- yasm_internal_error(N_("Didn't handle bytecode type in x86 arch"));
- /*@notreached@*/
- return YASM_BC_RESOLVE_UNKNOWN_LEN;
-}
-
-static int
-x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
- const yasm_section *sect, const yasm_bytecode *bc, void *d,
- yasm_output_expr_func output_expr)
-{
- /*@null@*/ x86_effaddr *x86_ea = insn->ea;
- /*@null@*/ yasm_effaddr *ea = &x86_ea->ea;
- yasm_immval *imm = insn->imm;
- unsigned int i;
- unsigned char *bufp_orig = *bufp;
-
- /* Prefixes */
- if (insn->lockrep_pre != 0)
- YASM_WRITE_8(*bufp, insn->lockrep_pre);
- if (x86_ea && x86_ea->segment != 0)
- YASM_WRITE_8(*bufp, x86_ea->segment);
- if (insn->opersize != 0 &&
- ((insn->mode_bits != 64 && insn->opersize != insn->mode_bits) ||
- (insn->mode_bits == 64 && insn->opersize == 16)))
- YASM_WRITE_8(*bufp, 0x66);
- if (insn->addrsize != 0 && insn->addrsize != insn->mode_bits)
- YASM_WRITE_8(*bufp, 0x67);
- if (insn->rex != 0 && insn->rex != 0xff) {
- if (insn->mode_bits != 64)
- yasm_internal_error(
- N_("x86: got a REX prefix in non-64-bit mode"));
- YASM_WRITE_8(*bufp, insn->rex);
- }
-
- /* Opcode */
- for (i=0; i<insn->opcode_len; i++)
- YASM_WRITE_8(*bufp, insn->opcode[i]);
-
- /* Effective address: ModR/M (if required), SIB (if required), and
- * displacement (if required).
- */
- if (ea) {
- if (x86_ea->need_modrm) {
- if (!x86_ea->valid_modrm)
- yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn"));
- YASM_WRITE_8(*bufp, x86_ea->modrm);
- }
-
- if (x86_ea->need_sib) {
- if (!x86_ea->valid_sib)
- yasm_internal_error(N_("invalid SIB in x86 tobytes_insn"));
- YASM_WRITE_8(*bufp, x86_ea->sib);
- }
-
- if (ea->disp) {
- x86_effaddr eat = *x86_ea; /* structure copy */
- unsigned char displen = ea->len;
- unsigned char addrsize = insn->addrsize;
-
- eat.valid_modrm = 0; /* force checkea to actually run */
-
- /* Call checkea() to simplify the registers out of the
- * displacement. Throw away all of the return values except for
- * the modified expr.
- */
- if (!yasm_x86__expr_checkea(&ea->disp, &addrsize, insn->mode_bits,
- ea->nosplit, &displen, &eat.modrm,
- &eat.valid_modrm, &eat.need_modrm,
- &eat.sib, &eat.valid_sib,
- &eat.need_sib, &insn->rex,
- yasm_common_calc_bc_dist))
- yasm_internal_error(N_("checkea failed"));
-
- if (ea->disp) {
- if (output_expr(&ea->disp, bufp, ea->len, *bufp-bufp_orig,
- sect, bc, 0, d))
- return 1;
- } else {
- /* 0 displacement, but we didn't know it before, so we have to
- * write out 0 value.
- */
- for (i=0; i<ea->len; i++)
- YASM_WRITE_8(*bufp, 0);
- }
- }
- }
-
- /* Immediate (if required) */
- if (imm && imm->val) {
- /* TODO: check imm->len vs. sized len from expr? */
- if (output_expr(&imm->val, bufp, imm->len, *bufp-bufp_orig, sect, bc,
- 0, d))
- return 1;
- }
-
- return 0;
-}
-
-static int
-x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
- const yasm_section *sect, const yasm_bytecode *bc,
- void *d, yasm_output_expr_func output_expr)
-{
- unsigned char opersize;
- unsigned int i;
- unsigned char *bufp_orig = *bufp;
-
- /* Prefixes */
- if (jmprel->lockrep_pre != 0)
- YASM_WRITE_8(*bufp, jmprel->lockrep_pre);
- /* FIXME: branch hints! */
- if (jmprel->opersize != 0 && jmprel->opersize != jmprel->mode_bits)
- YASM_WRITE_8(*bufp, 0x66);
- if (jmprel->addrsize != 0 && jmprel->addrsize != jmprel->mode_bits)
- YASM_WRITE_8(*bufp, 0x67);
-
- /* As opersize may be 0, figure out its "real" value. */
- opersize = (jmprel->opersize == 0) ? jmprel->mode_bits :
- jmprel->opersize;
-
- /* Check here to see if forced forms are actually legal. */
- switch (jmprel->op_sel) {
- case JR_SHORT_FORCED:
- case JR_SHORT:
- /* 1 byte relative displacement */
- if (jmprel->shortop.opcode_len == 0)
- yasm_internal_error(N_("short jump does not exist"));
-
- /* Opcode */
- for (i=0; i<jmprel->shortop.opcode_len; i++)
- YASM_WRITE_8(*bufp, jmprel->shortop.opcode[i]);
-
- /* Relative displacement */
- if (output_expr(&jmprel->target, bufp, 1, *bufp-bufp_orig, sect,
- bc, 1, d))
- return 1;
- break;
- case JR_NEAR_FORCED:
- case JR_NEAR:
- /* 2/4 byte relative displacement (depending on operand size) */
- if (jmprel->nearop.opcode_len == 0) {
- yasm__error(bc->line, N_("near jump does not exist"));
- return 1;
- }
-
- /* Opcode */
- for (i=0; i<jmprel->nearop.opcode_len; i++)
- YASM_WRITE_8(*bufp, jmprel->nearop.opcode[i]);
-
- /* Relative displacement */
- if (output_expr(&jmprel->target, bufp,
- (opersize == 32) ? 4UL : 2UL, *bufp-bufp_orig,
- sect, bc, 1, d))
- return 1;
- break;
- default:
- yasm_internal_error(N_("unrecognized relative jump op_sel"));
- }
- return 0;
-}
-
-int
-yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr)
-{
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- return x86_bc_tobytes_insn((x86_insn *)bc, bufp, sect, bc, d,
- output_expr);
- case X86_BC_JMPREL:
- return x86_bc_tobytes_jmprel((x86_jmprel *)bc, bufp, sect, bc, d,
- output_expr);
- default:
- break;
- }
- return 0;
-}
-
-int
-yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e,
- const yasm_bytecode *bc, int rel)
-{
- if (rel) {
- long val;
- if (valsize != 1 && valsize != 2 && valsize != 4)
- yasm_internal_error(
- N_("tried to do PC-relative offset from invalid sized value"));
- val = yasm_intnum_get_uint(intn);
- val -= bc->len;
- switch (valsize) {
- case 1:
- YASM_WRITE_8(*bufp, val);
- break;
- case 2:
- YASM_WRITE_16_L(*bufp, val);
- break;
- case 4:
- YASM_WRITE_32_L(*bufp, val);
- break;
- }
- } else {
- /* Write value out. */
- yasm_intnum_get_sized(intn, *bufp, (size_t)valsize);
- *bufp += valsize;
- }
- return 0;
-}
+++ /dev/null
-/*
- * x86 expression handling
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "bitvect.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-#include "arch.h"
-
-#include "x86arch.h"
-
-#include "expr-int.h"
-
-
-typedef struct x86_checkea_reg3264_data {
- int *regs; /* total multiplier for each reg */
- unsigned char bits;
- unsigned char addrsize;
-} x86_checkea_reg3264_data;
-
-/* Only works if ei->type == EXPR_REG (doesn't check).
- * Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
- */
-static /*@null@*/ /*@dependent@*/ int *
-x86_expr_checkea_get_reg3264(yasm_expr__item *ei, int *regnum,
- /*returned*/ void *d)
-{
- x86_checkea_reg3264_data *data = d;
-
- switch ((x86_expritem_reg_size)(ei->data.reg & ~0xF)) {
- case X86_REG32:
- if (data->addrsize != 32)
- return 0;
- *regnum = ei->data.reg & 0x7;
- break;
- case X86_REG64:
- if (data->addrsize != 64)
- return 0;
- *regnum = ei->data.reg & 0xF;
- break;
- case X86_RIP:
- if (data->bits != 64)
- return 0;
- *regnum = 16;
- break;
- default:
- return 0;
- }
-
- /* overwrite with 0 to eliminate register from displacement expr */
- ei->type = YASM_EXPR_INT;
- ei->data.intn = yasm_intnum_new_uint(0);
-
- /* we're okay */
- return &data->regs[*regnum];
-}
-
-typedef struct x86_checkea_reg16_data {
- int bx, si, di, bp; /* total multiplier for each reg */
-} x86_checkea_reg16_data;
-
-/* Only works if ei->type == EXPR_REG (doesn't check).
- * Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
- */
-static /*@null@*/ int *
-x86_expr_checkea_get_reg16(yasm_expr__item *ei, int *regnum, void *d)
-{
- x86_checkea_reg16_data *data = d;
- /* in order: ax,cx,dx,bx,sp,bp,si,di */
- /*@-nullassign@*/
- static int *reg16[8] = {0,0,0,0,0,0,0,0};
- /*@=nullassign@*/
-
- reg16[3] = &data->bx;
- reg16[5] = &data->bp;
- reg16[6] = &data->si;
- reg16[7] = &data->di;
-
- /* don't allow 32-bit registers */
- if ((ei->data.reg & ~0xF) != X86_REG16)
- return 0;
-
- /* & 7 for sanity check */
- *regnum = ei->data.reg & 0x7;
-
- /* only allow BX, SI, DI, BP */
- if (!reg16[*regnum])
- return 0;
-
- /* overwrite with 0 to eliminate register from displacement expr */
- ei->type = YASM_EXPR_INT;
- ei->data.intn = yasm_intnum_new_uint(0);
-
- /* we're okay */
- return reg16[*regnum];
-}
-
-/* Distribute over registers to help bring them to the topmost level of e.
- * Also check for illegal operations against registers.
- * Returns 0 if something was illegal, 1 if legal and nothing in e changed,
- * and 2 if legal and e needs to be simplified.
- *
- * Only half joking: Someday make this/checkea able to accept crazy things
- * like: (bx+di)*(bx+di)-bx*bx-2*bx*di-di*di+di? Probably not: NASM never
- * accepted such things, and it's doubtful such an expn is valid anyway
- * (even though the above one is). But even macros would be hard-pressed
- * to generate something like this.
- *
- * e must already have been simplified for this function to work properly
- * (as it doesn't think things like SUB are valid).
- *
- * IMPLEMENTATION NOTE: About the only thing this function really needs to
- * "distribute" is: (non-float-expn or intnum) * (sum expn of registers).
- *
- * TODO: Clean up this code, make it easier to understand.
- */
-static int
-x86_expr_checkea_distcheck_reg(yasm_expr **ep)
-{
- yasm_expr *e = *ep;
- int i;
- int havereg = -1, havereg_expr = -1;
- int retval = 1; /* default to legal, no changes */
-
- for (i=0; i<e->numterms; i++) {
- switch (e->terms[i].type) {
- case YASM_EXPR_REG:
- /* Check op to make sure it's valid to use w/register. */
- if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL &&
- e->op != YASM_EXPR_IDENT)
- return 0;
- /* Check for reg*reg */
- if (e->op == YASM_EXPR_MUL && havereg != -1)
- return 0;
- havereg = i;
- break;
- case YASM_EXPR_FLOAT:
- /* Floats not allowed. */
- return 0;
- case YASM_EXPR_EXPR:
- if (yasm_expr__contains(e->terms[i].data.expn,
- YASM_EXPR_REG)) {
- int ret2;
-
- /* Check op to make sure it's valid to use w/register. */
- if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL)
- return 0;
- /* Check for reg*reg */
- if (e->op == YASM_EXPR_MUL && havereg != -1)
- return 0;
- havereg = i;
- havereg_expr = i;
- /* Recurse to check lower levels */
- ret2 =
- x86_expr_checkea_distcheck_reg(&e->terms[i].data.expn);
- if (ret2 == 0)
- return 0;
- if (ret2 == 2)
- retval = 2;
- } else if (yasm_expr__contains(e->terms[i].data.expn,
- YASM_EXPR_FLOAT))
- return 0; /* Disallow floats */
- break;
- default:
- break;
- }
- }
-
- /* just exit if no registers were used */
- if (havereg == -1)
- return retval;
-
- /* Distribute */
- if (e->op == YASM_EXPR_MUL && havereg_expr != -1) {
- yasm_expr *ne;
-
- retval = 2; /* we're going to change it */
-
- /* The reg expn *must* be EXPR_ADD at this point. Sanity check. */
- if (e->terms[havereg_expr].type != YASM_EXPR_EXPR ||
- e->terms[havereg_expr].data.expn->op != YASM_EXPR_ADD)
- yasm_internal_error(N_("Register expression not ADD or EXPN"));
-
- /* Iterate over each term in reg expn */
- for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
- /* Copy everything EXCEPT havereg_expr term into new expression */
- ne = yasm_expr__copy_except(e, havereg_expr);
- assert(ne != NULL);
- /* Copy reg expr term into uncopied (empty) term in new expn */
- ne->terms[havereg_expr] =
- e->terms[havereg_expr].data.expn->terms[i]; /* struct copy */
- /* Overwrite old reg expr term with new expn */
- e->terms[havereg_expr].data.expn->terms[i].type = YASM_EXPR_EXPR;
- e->terms[havereg_expr].data.expn->terms[i].data.expn = ne;
- }
-
- /* Replace e with expanded reg expn */
- ne = e->terms[havereg_expr].data.expn;
- e->terms[havereg_expr].type = YASM_EXPR_NONE; /* don't delete it! */
- yasm_expr_delete(e); /* but everything else */
- e = ne;
- /*@-onlytrans@*/
- *ep = ne;
- /*@=onlytrans@*/
- }
-
- return retval;
-}
-
-/* Simplify and determine if expression is superficially valid:
- * Valid expr should be [(int-equiv expn)]+[reg*(int-equiv expn)+...]
- * where the [...] parts are optional.
- *
- * Don't simplify out constant identities if we're looking for an indexreg: we
- * may need the multiplier for determining what the indexreg is!
- *
- * Returns 0 if invalid register usage, 1 if unable to determine all values,
- * and 2 if all values successfully determined and saved in data.
- */
-static int
-x86_expr_checkea_getregusage(yasm_expr **ep, /*@null@*/ int *indexreg,
- void *data, int *(*get_reg)(yasm_expr__item *ei, int *regnum, void *d),
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- int i;
- int *reg;
- int regnum;
- yasm_expr *e;
-
- /*@-unqualifiedtrans@*/
- *ep = yasm_expr__level_tree(*ep, 1, indexreg == 0, calc_bc_dist, NULL,
- NULL, NULL);
- /*@=unqualifiedtrans@*/
- assert(*ep != NULL);
- e = *ep;
- switch (x86_expr_checkea_distcheck_reg(ep)) {
- case 0:
- return 0;
- case 2:
- /* Need to simplify again */
- *ep = yasm_expr__level_tree(*ep, 1, indexreg == 0, NULL, NULL,
- NULL, NULL);
- e = *ep;
- break;
- default:
- break;
- }
-
- switch (e->op) {
- case YASM_EXPR_ADD:
- /* Prescan for non-int multipliers.
- * This is because if any of the terms is a more complex
- * expr (eg, undetermined value), we don't want to try to
- * figure out *any* of the expression, because each register
- * lookup overwrites the register with a 0 value! And storing
- * the state of this routine from one excution to the next
- * would be a major chore.
- */
- for (i=0; i<e->numterms; i++)
- if (e->terms[i].type == YASM_EXPR_EXPR) {
- if (e->terms[i].data.expn->numterms > 2)
- return 1;
- yasm_expr__order_terms(e->terms[i].data.expn);
- if (e->terms[i].data.expn->terms[1].type != YASM_EXPR_INT)
- return 1;
- }
-
- /*@fallthrough@*/
- case YASM_EXPR_IDENT:
- /* Check each term for register (and possible multiplier). */
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_REG) {
- reg = get_reg(&e->terms[i], ®num, data);
- if (!reg)
- return 0;
- (*reg)++;
- if (indexreg)
- *indexreg = regnum;
- } else if (e->terms[i].type == YASM_EXPR_EXPR) {
- /* Already ordered from ADD above, just grab the value.
- * Sanity check for EXPR_INT.
- */
- if (e->terms[i].data.expn->terms[0].type != YASM_EXPR_REG)
- yasm_internal_error(
- N_("Register not found in reg expn"));
- if (e->terms[i].data.expn->terms[1].type != YASM_EXPR_INT)
- yasm_internal_error(
- N_("Non-integer value in reg expn"));
- reg = get_reg(&e->terms[i].data.expn->terms[0], ®num,
- data);
- if (!reg)
- return 0;
- (*reg) +=
- yasm_intnum_get_int(
- e->terms[i].data.expn->terms[1].data.intn);
- if (indexreg && *reg > 0)
- *indexreg = regnum;
- }
- }
- break;
- case YASM_EXPR_MUL:
- /* Here, too, check for non-int multipliers. */
- if (e->numterms > 2)
- return 1;
- yasm_expr__order_terms(e);
- if (e->terms[1].type != YASM_EXPR_INT)
- return 1;
- reg = get_reg(&e->terms[0], ®num, data);
- if (!reg)
- return 0;
- (*reg) += yasm_intnum_get_int(e->terms[1].data.intn);
- if (indexreg)
- *indexreg = regnum;
- break;
- default:
- /* Should never get here! */
- break;
- }
-
- /* Simplify expr, which is now really just the displacement. This
- * should get rid of the 0's we put in for registers in the callback.
- */
- *ep = yasm_expr_simplify(*ep, NULL);
- /* e = *ep; */
-
- return 2;
-}
-
-/* Calculate the displacement length, if possible.
- * Takes several extra inputs so it can be used by both 32-bit and 16-bit
- * expressions:
- * wordsize=2 for 16-bit, =4 for 32-bit.
- * noreg=1 if the *ModRM byte* has no registers used.
- * dispreq=1 if a displacement value is *required* (even if =0).
- */
-/*@-nullstate@*/
-static int
-x86_checkea_calc_displen(yasm_expr **ep, unsigned int wordsize, int noreg,
- int dispreq, unsigned char *displen,
- unsigned char *modrm, unsigned char *v_modrm)
-{
- yasm_expr *e = *ep;
- const yasm_intnum *intn;
- long dispval;
-
- *v_modrm = 0; /* default to not yet valid */
-
- switch (*displen) {
- case 0:
- /* the displacement length hasn't been forced, try to
- * determine what it is.
- */
- if (noreg) {
- /* no register in ModRM expression, so it must be disp16/32,
- * and as the Mod bits are set to 0 by the caller, we're done
- * with the ModRM byte.
- */
- *displen = wordsize;
- *v_modrm = 1;
- break;
- } else if (dispreq) {
- /* for BP/EBP, there *must* be a displacement value, but we
- * may not know the size (8 or 16/32) for sure right now.
- * We can't leave displen at 0, because that just means
- * unknown displacement, including none.
- */
- *displen = 0xff;
- }
-
- intn = yasm_expr_get_intnum(ep, NULL);
- if (!intn) {
- /* expr still has unknown values: assume 16/32-bit disp */
- *displen = wordsize;
- *modrm |= 0200;
- *v_modrm = 1;
- break;
- }
-
- /* make sure the displacement will fit in 16/32 bits if unsigned,
- * and 8 bits if signed.
- */
- if (!yasm_intnum_check_size(intn, (size_t)wordsize, 0) &&
- !yasm_intnum_check_size(intn, 1, 1)) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* don't try to find out what size displacement we have if
- * displen is known.
- */
- if (*displen != 0 && *displen != 0xff) {
- if (*displen == 1)
- *modrm |= 0100;
- else
- *modrm |= 0200;
- *v_modrm = 1;
- break;
- }
-
- /* Don't worry about overflows here (it's already guaranteed
- * to be 16/32 or 8 bits).
- */
- dispval = yasm_intnum_get_int(intn);
-
- /* Figure out what size displacement we will have. */
- if (*displen != 0xff && dispval == 0) {
- /* if we know that the displacement is 0 right now,
- * go ahead and delete the expr (making it so no
- * displacement value is included in the output).
- * The Mod bits of ModRM are set to 0 above, and
- * we're done with the ModRM byte!
- *
- * Don't do this if we came from dispreq check above, so
- * check *displen.
- */
- yasm_expr_delete(e);
- *ep = (yasm_expr *)NULL;
- } else if (dispval >= -128 && dispval <= 127) {
- /* It fits into a signed byte */
- *displen = 1;
- *modrm |= 0100;
- } else {
- /* It's a 16/32-bit displacement */
- *displen = wordsize;
- *modrm |= 0200;
- }
- *v_modrm = 1; /* We're done with ModRM */
-
- break;
-
- /* If not 0, the displacement length was forced; set the Mod bits
- * appropriately and we're done with the ModRM byte. We assume
- * that the user knows what they're doing if they do an explicit
- * override, so we don't check for overflow (we'll just truncate
- * when we output).
- */
- case 1:
- /* TODO: Add optional warning here about byte not being valid
- * override in noreg case.
- */
- if (!noreg)
- *modrm |= 0100;
- *v_modrm = 1;
- break;
- case 2:
- case 4:
- if (wordsize != *displen) {
- yasm__error(e->line,
- N_("invalid effective address (displacement size)"));
- return 0;
- }
- /* TODO: Add optional warning here about 2/4 not being valid
- * override in noreg case.
- */
- if (!noreg)
- *modrm |= 0200;
- *v_modrm = 1;
- break;
- default:
- /* we shouldn't ever get any other size! */
- yasm_internal_error(N_("strange EA displacement size"));
- }
-
- return 1;
-}
-/*@=nullstate@*/
-
-static int
-x86_expr_checkea_getregsize_callback(yasm_expr__item *ei, void *d)
-{
- unsigned char *addrsize = (unsigned char *)d;
-
- if (ei->type == YASM_EXPR_REG) {
- switch ((x86_expritem_reg_size)(ei->data.reg & ~0xF)) {
- case X86_REG16:
- *addrsize = 16;
- break;
- case X86_REG32:
- *addrsize = 32;
- break;
- case X86_REG64:
- case X86_RIP:
- *addrsize = 64;
- break;
- default:
- return 0;
- }
- return 1;
- } else
- return 0;
-}
-
-int
-yasm_x86__expr_checkea(yasm_expr **ep, unsigned char *addrsize,
- unsigned char bits, unsigned char nosplit,
- unsigned char *displen, unsigned char *modrm,
- unsigned char *v_modrm, unsigned char *n_modrm,
- unsigned char *sib, unsigned char *v_sib,
- unsigned char *n_sib, unsigned char *rex,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- yasm_expr *e = *ep;
-
- if (*addrsize == 0) {
- /* we need to figure out the address size from what we know about:
- * - the displacement length
- * - what registers are used in the expression
- * - the bits setting
- */
- switch (*displen) {
- case 2:
- /* must be 16-bit */
- *addrsize = 16;
- break;
- case 8:
- /* We have to support this for the MemOffs case, but it's
- * otherwise illegal. It's also illegal in non-64-bit mode.
- */
- if (*n_modrm || *n_sib) {
- yasm__error(e->line,
- N_("invalid effective address (displacement size)"));
- return 0;
- }
- *addrsize = 64;
- break;
- case 4:
- /* Must be 32-bit in 16-bit or 32-bit modes. In 64-bit mode,
- * we don't know unless we look at the registers, except in the
- * MemOffs case (see the end of this function).
- */
- if (bits != 64 || (!*n_modrm && !*n_sib)) {
- *addrsize = 32;
- break;
- }
- /*@fallthrough@*/
- default:
- /* check for use of 16 or 32-bit registers; if none are used
- * default to bits setting.
- */
- if (!yasm_expr__traverse_leaves_in(e, addrsize,
- x86_expr_checkea_getregsize_callback))
- *addrsize = bits;
- /* TODO: Add optional warning here if switched address size
- * from bits setting just by register use.. eg [ax] in
- * 32-bit mode would generate a warning.
- */
- }
- }
-
- if ((*addrsize == 32 || *addrsize == 64) &&
- ((*n_modrm && !*v_modrm) || (*n_sib && !*v_sib))) {
- int i;
- unsigned char low3;
- typedef enum {
- REG3264_NONE = -1,
- REG3264_EAX = 0,
- REG3264_ECX,
- REG3264_EDX,
- REG3264_EBX,
- REG3264_ESP,
- REG3264_EBP,
- REG3264_ESI,
- REG3264_EDI,
- REG64_R8,
- REG64_R9,
- REG64_R10,
- REG64_R11,
- REG64_R12,
- REG64_R13,
- REG64_R14,
- REG64_R15,
- REG64_RIP
- } reg3264type;
- int reg3264mult[17] = {0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0};
- x86_checkea_reg3264_data reg3264_data;
- int basereg = REG3264_NONE; /* "base" register (for SIB) */
- int indexreg = REG3264_NONE; /* "index" register (for SIB) */
-
- /* We can only do 64-bit addresses in 64-bit mode. */
- if (*addrsize == 64 && bits != 64) {
- yasm__error(e->line,
- N_("invalid effective address (64-bit in non-64-bit mode)"));
- return 0;
- }
-
- reg3264_data.regs = reg3264mult;
- reg3264_data.bits = bits;
- reg3264_data.addrsize = *addrsize;
- switch (x86_expr_checkea_getregusage(ep, &indexreg, ®3264_data,
- x86_expr_checkea_get_reg3264,
- calc_bc_dist)) {
- case 0:
- e = *ep;
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- case 1:
- return 1;
- default:
- e = *ep;
- break;
- }
-
- /* If indexreg mult is 0, discard it.
- * This is possible because of the way indexreg is found in
- * expr_checkea_getregusage().
- */
- if (indexreg != REG3264_NONE && reg3264mult[indexreg] == 0)
- indexreg = REG3264_NONE;
-
- /* Find a basereg (*1, but not indexreg), if there is one.
- * Also, if an indexreg hasn't been assigned, try to find one.
- * Meanwhile, check to make sure there's no negative register mults.
- */
- for (i=0; i<17; i++) {
- if (reg3264mult[i] < 0) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
- if (i != indexreg && reg3264mult[i] == 1 &&
- basereg == REG3264_NONE)
- basereg = i;
- else if (indexreg == REG3264_NONE && reg3264mult[i] > 0)
- indexreg = i;
- }
-
- /* Handle certain special cases of indexreg mults when basereg is
- * empty.
- */
- if (indexreg != REG3264_NONE && basereg == REG3264_NONE)
- switch (reg3264mult[indexreg]) {
- case 1:
- /* Only optimize this way if nosplit wasn't specified */
- if (!nosplit) {
- basereg = indexreg;
- indexreg = -1;
- }
- break;
- case 2:
- /* Only split if nosplit wasn't specified */
- if (!nosplit) {
- basereg = indexreg;
- reg3264mult[indexreg] = 1;
- }
- break;
- case 3:
- case 5:
- case 9:
- basereg = indexreg;
- reg3264mult[indexreg]--;
- break;
- }
-
- /* Make sure there's no other registers than the basereg and indexreg
- * we just found.
- */
- for (i=0; i<17; i++)
- if (i != basereg && i != indexreg && reg3264mult[i] != 0) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* Check the index multiplier value for validity if present. */
- if (indexreg != REG3264_NONE && reg3264mult[indexreg] != 1 &&
- reg3264mult[indexreg] != 2 && reg3264mult[indexreg] != 4 &&
- reg3264mult[indexreg] != 8) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* ESP is not a legal indexreg. */
- if (indexreg == REG3264_ESP) {
- /* If mult>1 or basereg is ESP also, there's no way to make it
- * legal.
- */
- if (reg3264mult[REG3264_ESP] > 1 || basereg == REG3264_ESP) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
- /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
- indexreg = basereg;
- basereg = REG3264_ESP;
- }
-
- /* RIP is only legal if it's the ONLY register used. */
- if (indexreg == REG64_RIP ||
- (basereg == REG64_RIP && indexreg != REG3264_NONE)) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* At this point, we know the base and index registers and that the
- * memory expression is (essentially) valid. Now build the ModRM and
- * (optional) SIB bytes.
- */
-
- /* First determine R/M (Mod is later determined from disp size) */
- *n_modrm = 1; /* we always need ModRM */
- if (basereg == REG3264_NONE && indexreg == REG3264_NONE) {
- /* Just a disp32: in 64-bit mode the RM encoding is used for RIP
- * offset addressing, so we need to use the SIB form instead.
- */
- if (bits == 64) {
- *modrm |= 4;
- *n_sib = 1;
- } else {
- *modrm |= 5;
- *sib = 0;
- *v_sib = 0;
- *n_sib = 0;
- }
- } else if (basereg == REG64_RIP) {
- *modrm |= 5;
- *sib = 0;
- *v_sib = 0;
- *n_sib = 0;
- } else if (indexreg == REG3264_NONE) {
- /* basereg only */
- /* Don't need to go to the full effort of determining what type
- * of register basereg is, as x86_set_rex_from_reg doesn't pay
- * much attention.
- */
- if (yasm_x86__set_rex_from_reg(rex, &low3, X86_REG64 | basereg,
- bits, X86_REX_B)) {
- yasm__error(e->line,
- N_("invalid combination of operands and effective address"));
- return 0;
- }
- *modrm |= low3;
- /* we don't need an SIB *unless* basereg is ESP or R12 */
- if (basereg == REG3264_ESP || basereg == REG64_R12)
- *n_sib = 1;
- else {
- *sib = 0;
- *v_sib = 0;
- *n_sib = 0;
- }
- } else {
- /* index or both base and index */
- *modrm |= 4;
- *n_sib = 1;
- }
-
- /* Determine SIB if needed */
- if (*n_sib == 1) {
- *sib = 0; /* start with 0 */
-
- /* Special case: no basereg */
- if (basereg == REG3264_NONE)
- *sib |= 5;
- else {
- if (yasm_x86__set_rex_from_reg(rex, &low3, X86_REG64 | basereg,
- bits, X86_REX_B)) {
- yasm__error(e->line,
- N_("invalid combination of operands and effective address"));
- return 0;
- }
- *sib |= low3;
- }
-
- /* Put in indexreg, checking for none case */
- if (indexreg == REG3264_NONE)
- *sib |= 040;
- /* Any scale field is valid, just leave at 0. */
- else {
- if (yasm_x86__set_rex_from_reg(rex, &low3,
- X86_REG64 | indexreg, bits,
- X86_REX_X)) {
- yasm__error(e->line,
- N_("invalid combination of operands and effective address"));
- return 0;
- }
- *sib |= low3 << 3;
- /* Set scale field, 1 case -> 0, so don't bother. */
- switch (reg3264mult[indexreg]) {
- case 2:
- *sib |= 0100;
- break;
- case 4:
- *sib |= 0200;
- break;
- case 8:
- *sib |= 0300;
- break;
- }
- }
-
- *v_sib = 1; /* Done with SIB */
- }
-
- /* Calculate displacement length (if possible) */
- return x86_checkea_calc_displen(ep, 4, basereg == REG3264_NONE,
- (basereg == REG3264_EBP || basereg == REG64_R13) &&
- indexreg == REG3264_NONE, displen, modrm, v_modrm);
- } else if (*addrsize == 16 && *n_modrm && !*v_modrm) {
- static const unsigned char modrm16[16] = {
- 0006 /* disp16 */, 0007 /* [BX] */, 0004 /* [SI] */,
- 0000 /* [BX+SI] */, 0005 /* [DI] */, 0001 /* [BX+DI] */,
- 0377 /* invalid */, 0377 /* invalid */, 0006 /* [BP]+d */,
- 0377 /* invalid */, 0002 /* [BP+SI] */, 0377 /* invalid */,
- 0003 /* [BP+DI] */, 0377 /* invalid */, 0377 /* invalid */,
- 0377 /* invalid */
- };
- x86_checkea_reg16_data reg16mult = {0, 0, 0, 0};
- enum {
- HAVE_NONE = 0,
- HAVE_BX = 1<<0,
- HAVE_SI = 1<<1,
- HAVE_DI = 1<<2,
- HAVE_BP = 1<<3
- } havereg = HAVE_NONE;
-
- /* 64-bit mode does not allow 16-bit addresses */
- if (bits == 64) {
- yasm__error(e->line,
- N_("16-bit addresses not supported in 64-bit mode"));
- return 0;
- }
-
- /* 16-bit cannot have SIB */
- *sib = 0;
- *v_sib = 0;
- *n_sib = 0;
-
- switch (x86_expr_checkea_getregusage(ep, (int *)NULL, ®16mult,
- x86_expr_checkea_get_reg16,
- calc_bc_dist)) {
- case 0:
- e = *ep;
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- case 1:
- return 1;
- default:
- e = *ep;
- break;
- }
-
- /* reg multipliers not 0 or 1 are illegal. */
- if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
- reg16mult.bp & ~1) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* Set havereg appropriately */
- if (reg16mult.bx > 0)
- havereg |= HAVE_BX;
- if (reg16mult.si > 0)
- havereg |= HAVE_SI;
- if (reg16mult.di > 0)
- havereg |= HAVE_DI;
- if (reg16mult.bp > 0)
- havereg |= HAVE_BP;
-
- /* Check the modrm value for invalid combinations. */
- if (modrm16[havereg] & 0070) {
- yasm__error(e->line, N_("invalid effective address"));
- return 0;
- }
-
- /* Set ModRM byte for registers */
- *modrm |= modrm16[havereg];
-
- /* Calculate displacement length (if possible) */
- return x86_checkea_calc_displen(ep, 2, havereg == HAVE_NONE,
- havereg == HAVE_BP, displen, modrm,
- v_modrm);
- } else if (!*n_modrm && !*n_sib) {
- /* Special case for MOV MemOffs opcode: displacement but no modrm. */
- switch (*addrsize) {
- case 64:
- if (bits != 64) {
- yasm__error(e->line,
- N_("invalid effective address (64-bit in non-64-bit mode)"));
- return 0;
- }
- *displen = 8;
- break;
- case 32:
- *displen = 4;
- break;
- case 16:
- /* 64-bit mode does not allow 16-bit addresses */
- if (bits == 64) {
- yasm__error(e->line,
- N_("16-bit addresses not supported in 64-bit mode"));
- return 0;
- }
- *displen = 2;
- break;
- }
- }
- return 1;
-}
-
-int
-yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char **bufp,
- unsigned long valsize, const yasm_expr *e)
-{
- int fltret;
-
- if (!yasm_floatnum_check_size(flt, (size_t)valsize)) {
- yasm__error(e->line, N_("invalid floating point constant size"));
- return 1;
- }
-
- fltret = yasm_floatnum_get_sized(flt, *bufp, (size_t)valsize);
- if (fltret < 0) {
- yasm__error(e->line, N_("underflow in floating point expression"));
- return 1;
- }
- if (fltret > 0) {
- yasm__error(e->line, N_("overflow in floating point expression"));
- return 1;
- }
- *bufp += valsize;
- return 0;
-}
+++ /dev/null
-/*
- * x86 identifier recognition and instruction handling
- *
- * Copyright (C) 2002 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.
- *
- * 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("$IdPath$");
-
-#include "bitvect.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-
-#include "arch.h"
-#include "src/arch/x86/x86arch.h"
-
-#include "expr-int.h"
-#include "bc-int.h"
-
-
-/* Available CPU feature flags */
-#define CPU_Any (0UL) /* Any old cpu will do */
-#define CPU_086 CPU_Any
-#define CPU_186 (1UL<<0) /* i186 or better required */
-#define CPU_286 (1UL<<1) /* i286 or better required */
-#define CPU_386 (1UL<<2) /* i386 or better required */
-#define CPU_486 (1UL<<3) /* i486 or better required */
-#define CPU_586 (1UL<<4) /* i585 or better required */
-#define CPU_686 (1UL<<5) /* i686 or better required */
-#define CPU_P3 (1UL<<6) /* Pentium3 or better required */
-#define CPU_P4 (1UL<<7) /* Pentium4 or better required */
-#define CPU_IA64 (1UL<<8) /* IA-64 or better required */
-#define CPU_K6 (1UL<<9) /* AMD K6 or better required */
-#define CPU_Athlon (1UL<<10) /* AMD Athlon or better required */
-#define CPU_Hammer (1UL<<11) /* AMD Sledgehammer or better required */
-#define CPU_FPU (1UL<<12) /* FPU support required */
-#define CPU_MMX (1UL<<13) /* MMX support required */
-#define CPU_SSE (1UL<<14) /* Streaming SIMD extensions required */
-#define CPU_SSE2 (1UL<<15) /* Streaming SIMD extensions 2 required */
-#define CPU_3DNow (1UL<<16) /* 3DNow! support required */
-#define CPU_Cyrix (1UL<<17) /* Cyrix-specific instruction */
-#define CPU_AMD (1UL<<18) /* AMD-specific inst. (older than K6) */
-#define CPU_SMM (1UL<<19) /* System Management Mode instruction */
-#define CPU_Prot (1UL<<20) /* Protected mode only instruction */
-#define CPU_Undoc (1UL<<21) /* Undocumented instruction */
-#define CPU_Obs (1UL<<22) /* Obsolete instruction */
-#define CPU_Priv (1UL<<23) /* Priveleged instruction */
-
-/* Technically not CPU capabilities, they do affect what instructions are
- * available. These are tested against BITS==64.
- */
-#define CPU_64 (1UL<<24) /* Only available in 64-bit mode */
-#define CPU_Not64 (1UL<<25) /* Not available (invalid) in 64-bit mode */
-
-/* What instructions/features are enabled? Defaults to all. */
-static unsigned long cpu_enabled = ~CPU_Any;
-
-/* Opcode modifiers. The opcode bytes are in "reverse" order because the
- * parameters are read from the arch-specific data in LSB->MSB order.
- * (only for asthetic reasons in the lexer code below, no practical reason).
- */
-#define MOD_Op2Add (1UL<<0) /* Parameter adds to opcode byte 2 */
-#define MOD_Gap0 (1UL<<1) /* Eats a parameter */
-#define MOD_Op1Add (1UL<<2) /* Parameter adds to opcode byte 1 */
-#define MOD_Gap1 (1UL<<3) /* Eats a parameter */
-#define MOD_Op0Add (1UL<<4) /* Parameter adds to opcode byte 0 */
-#define MOD_SpAdd (1UL<<5) /* Parameter adds to "spare" value */
-#define MOD_OpSizeR (1UL<<6) /* Parameter replaces opersize */
-#define MOD_Imm8 (1UL<<7) /* Parameter is included as immediate byte */
-#define MOD_AdSizeR (1UL<<8) /* Parameter replaces addrsize (jmprel only) */
-
-/* Modifiers that aren't actually used as modifiers. Rather, if set, bits
- * 20-27 in the modifier are used as an index into an array.
- * Obviously, only one of these may be set at a time.
- */
-#define MOD_ExtNone (0UL<<28) /* No extended modifier */
-#define MOD_ExtErr (1UL<<28) /* Extended error: index into error strings */
-#define MOD_ExtWarn (2UL<<28) /* Extended warning: index into warning strs */
-#define MOD_Ext_MASK (0xFUL<<28)
-#define MOD_ExtIndex_SHIFT 20
-#define MOD_ExtIndex(indx) (((unsigned long)(indx))<<MOD_ExtIndex_SHIFT)
-#define MOD_ExtIndex_MASK (0xFFUL<<MOD_ExtIndex_SHIFT)
-
-/* Operand types. These are more detailed than the "general" types for all
- * architectures, as they include the size, for instance.
- * Bit Breakdown (from LSB to MSB):
- * - 5 bits = general type (must be exact match, except for =3):
- * 0 = immediate
- * 1 = any general purpose or FPU register
- * 2 = memory
- * 3 = any general purpose or FPU register OR memory
- * 4 = any MMX or XMM register
- * 5 = any MMX or XMM register OR memory
- * 6 = any segment register
- * 7 = any CR register
- * 8 = any DR register
- * 9 = any TR register
- * A = ST0
- * B = AL/AX/EAX/RAX (depending on size)
- * C = CL/CX/ECX/RCX (depending on size)
- * D = DL/DX/EDX/RDX (depending on size)
- * E = CS
- * F = DS
- * 10 = ES
- * 11 = FS
- * 12 = GS
- * 13 = SS
- * 14 = CR4
- * 15 = memory offset (an EA, but with no registers allowed)
- * [special case for MOV opcode]
- * - 3 bits = size (user-specified, or from register size):
- * 0 = any size acceptable/no size spec acceptable (dep. on strict)
- * 1/2/3/4 = 8/16/32/64 bits (from user or reg size)
- * 5/6 = 80/128 bits (from user)
- * - 1 bit = size implicit or explicit ("strictness" of size matching on
- * non-registers -- registers are always strictly matched):
- * 0 = user size must exactly match size above.
- * 1 = user size either unspecified or exactly match size above.
- * - 3 bits = target modification.
- * 0 = no target mod acceptable
- * 1 = NEAR
- * 2 = SHORT
- * 3 = FAR
- * 4 = TO
- *
- * MSBs than the above are actions: what to do with the operand if the
- * instruction matches. Essentially describes what part of the output bytecode
- * gets the operand. This may require conversion (e.g. a register going into
- * an ea field). Naturally, only one of each of these may be contained in the
- * operands of a single insn_info structure.
- * - 4 bits = action:
- * 0 = does nothing (operand data is discarded)
- * 1 = operand data goes into ea field
- * 2 = operand data goes into imm field
- * 3 = operand data goes into sign-extended imm field
- * 4 = operand data goes into "spare" field
- * 5 = operand data is added to opcode byte 0
- * 6 = operand data is added to opcode byte 1
- * 7 = operand data goes into BOTH ea and spare
- * [special case for imul opcode]
- * 8 = relative jump (outputs a jmprel instead of normal insn)
- * 9 = operand size goes into address size (jmprel only)
- * The below describes postponed actions: actions which can't be completed at
- * parse-time due to things like EQU and complex expressions. For these, some
- * additional data (stored in the second byte of the opcode with a one-byte
- * opcode) is passed to later stages of the assembler with flags set to
- * indicate postponed actions.
- * - 2 bits = postponed action:
- * 0 = none
- * 1 = shift operation with a ,1 short form (instead of imm8).
- * 2 = large imm16/32 that can become a sign-extended imm8.
- */
-#define OPT_Imm 0x0
-#define OPT_Reg 0x1
-#define OPT_Mem 0x2
-#define OPT_RM 0x3
-#define OPT_SIMDReg 0x4
-#define OPT_SIMDRM 0x5
-#define OPT_SegReg 0x6
-#define OPT_CRReg 0x7
-#define OPT_DRReg 0x8
-#define OPT_TRReg 0x9
-#define OPT_ST0 0xA
-#define OPT_Areg 0xB
-#define OPT_Creg 0xC
-#define OPT_Dreg 0xD
-#define OPT_CS 0xE
-#define OPT_DS 0xF
-#define OPT_ES 0x10
-#define OPT_FS 0x11
-#define OPT_GS 0x12
-#define OPT_SS 0x13
-#define OPT_CR4 0x14
-#define OPT_MemOffs 0x15
-#define OPT_MASK 0x1F
-
-#define OPS_Any (0UL<<5)
-#define OPS_8 (1UL<<5)
-#define OPS_16 (2UL<<5)
-#define OPS_32 (3UL<<5)
-#define OPS_64 (4UL<<5)
-#define OPS_80 (5UL<<5)
-#define OPS_128 (6UL<<5)
-#define OPS_MASK (7UL<<5)
-#define OPS_SHIFT 5
-
-#define OPS_Relaxed (1UL<<8)
-#define OPS_RMASK (1UL<<8)
-
-#define OPTM_None (0UL<<9)
-#define OPTM_Near (1UL<<9)
-#define OPTM_Short (2UL<<9)
-#define OPTM_Far (3UL<<9)
-#define OPTM_To (4UL<<9)
-#define OPTM_MASK (7UL<<9)
-
-#define OPA_None (0UL<<12)
-#define OPA_EA (1UL<<12)
-#define OPA_Imm (2UL<<12)
-#define OPA_SImm (3UL<<12)
-#define OPA_Spare (4UL<<12)
-#define OPA_Op0Add (5UL<<12)
-#define OPA_Op1Add (6UL<<12)
-#define OPA_SpareEA (7UL<<12)
-#define OPA_JmpRel (8UL<<12)
-#define OPA_AdSizeR (9UL<<12)
-#define OPA_MASK (0xFUL<<12)
-
-#define OPAP_None (0UL<<16)
-#define OPAP_ShiftOp (1UL<<16)
-#define OPAP_SImm8Avail (2UL<<16)
-#define OPAP_MASK (3UL<<16)
-
-typedef struct x86_insn_info {
- /* The CPU feature flags needed to execute this instruction. This is OR'ed
- * with arch-specific data[2]. This combined value is compared with
- * cpu_enabled to see if all bits set here are set in cpu_enabled--if so,
- * the instruction is available on this CPU.
- */
- unsigned long cpu;
-
- /* Opcode modifiers for variations of instruction. As each modifier reads
- * its parameter in LSB->MSB order from the arch-specific data[1] from the
- * lexer data, and the LSB of the arch-specific data[1] is reserved for the
- * count of insn_info structures in the instruction grouping, there can
- * only be a maximum of 3 modifiers.
- */
- unsigned long modifiers;
-
- /* Operand Size */
- unsigned char opersize;
-
- /* The length of the basic opcode */
- unsigned char opcode_len;
-
- /* The basic 1-3 byte opcode */
- unsigned char opcode[3];
-
- /* The 3-bit "spare" value (extended opcode) for the R/M byte field */
- unsigned char spare;
-
- /* The number of operands this form of the instruction takes */
- unsigned char num_operands;
-
- /* The types of each operand, see above */
- unsigned long operands[3];
-} x86_insn_info;
-
-/* Define lexer arch-specific data with 0-3 modifiers. */
-#define DEF_INSN_DATA(group, mod, cpu) do { \
- data[0] = (unsigned long)group##_insn; \
- data[1] = ((mod)<<8) | \
- ((unsigned char)(sizeof(group##_insn)/sizeof(x86_insn_info))); \
- data[2] = cpu; \
- } while (0)
-
-#define RET_INSN(group, mod, cpu) do { \
- DEF_INSN_DATA(group, mod, cpu); \
- return YASM_ARCH_CHECK_ID_INSN; \
- } while (0)
-
-/*
- * General instruction groupings
- */
-
-/* Placeholder for instructions invalid in 64-bit mode */
-static const x86_insn_info not64_insn[] = {
- { CPU_Not64, 0, 0, 0, {0, 0, 0}, 0, 0, {0, 0, 0} }
-};
-
-/* One byte opcode instructions with no operands */
-static const x86_insn_info onebyte_insn[] = {
- { CPU_Any, MOD_Op0Add|MOD_OpSizeR, 0, 1, {0, 0, 0}, 0, 0, {0, 0, 0} }
-};
-
-/* Two byte opcode instructions with no operands */
-static const x86_insn_info twobyte_insn[] = {
- { CPU_Any, MOD_Op1Add|MOD_Op0Add, 0, 2, {0, 0, 0}, 0, 0, {0, 0, 0} }
-};
-
-/* Three byte opcode instructions with no operands */
-static const x86_insn_info threebyte_insn[] = {
- { CPU_Any, MOD_Op2Add|MOD_Op1Add|MOD_Op0Add, 0, 3, {0, 0, 0}, 0, 0,
- {0, 0, 0} }
-};
-
-/* One byte opcode instructions with general memory operand */
-static const x86_insn_info onebytemem_insn[] = {
- { CPU_Any, MOD_Op0Add|MOD_SpAdd, 0, 1, {0, 0, 0}, 0, 1,
- {OPT_Mem|OPS_Any|OPA_EA, 0, 0} }
-};
-
-/* Two byte opcode instructions with general memory operand */
-static const x86_insn_info twobytemem_insn[] = {
- { CPU_Any, MOD_Op1Add|MOD_Op0Add|MOD_SpAdd, 0, 1, {0, 0, 0}, 0, 1,
- {OPT_Mem|OPS_Any|OPA_EA, 0, 0} }
-};
-
-/* Move instructions */
-static const x86_insn_info mov_insn[] = {
- { CPU_Any, 0, 0, 1, {0xA0, 0, 0}, 0, 2,
- {OPT_Areg|OPS_8|OPA_None, OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Any, 0, 16, 1, {0xA1, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0xA1, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xA1, 0, 0}, 0, 2,
- {OPT_Areg|OPS_64|OPA_None, OPT_MemOffs|OPS_64|OPS_Relaxed|OPA_EA, 0} },
-
- { CPU_Any, 0, 0, 1, {0xA2, 0, 0}, 0, 2,
- {OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_8|OPA_None, 0} },
- { CPU_Any, 0, 16, 1, {0xA3, 0, 0}, 0, 2,
- {OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_16|OPA_None, 0} },
- { CPU_386, 0, 32, 1, {0xA3, 0, 0}, 0, 2,
- {OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_32|OPA_None, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xA3, 0, 0}, 0, 2,
- {OPT_MemOffs|OPS_64|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_64|OPA_None, 0} },
-
- { CPU_Any, 0, 0, 1, {0x88, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_Any, 0, 16, 1, {0x89, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386, 0, 32, 1, {0x89, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x89, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
-
- { CPU_Any, 0, 0, 1, {0x8A, 0, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Any, 0, 16, 1, {0x8B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0x8B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x8B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} },
-
- { CPU_Any, 0, 0, 1, {0x8C, 0, 0}, 0, 2,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA,
- OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
- { CPU_Any, 0, 16, 1, {0x8C, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
- { CPU_386, 0, 32, 1, {0x8C, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x8C, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} },
-
- { CPU_Any, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
- {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare,
- OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
- {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0x8E, 0, 0}, 0, 2,
- {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
-
- { CPU_Any, 0, 0, 1, {0xB0, 0, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Op0Add, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xB8, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Op0Add, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xB8, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Op0Add, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xB8, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Imm|OPS_64|OPS_Relaxed|OPA_Imm, 0} },
- /* Need two sets here, one for strictness on left side, one for right. */
- { CPU_Any, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
- { CPU_Any, 0, 0, 1, {0xC6, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xC7, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-
- { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
- {OPT_CR4|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
- { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
- {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
- { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2,
- {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
- { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_CR4|OPS_32|OPA_Spare, 0} },
- { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} },
-
- { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2,
- {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} },
- { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2,
- {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} },
- { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} }
-};
-
-/* Move with sign/zero extend */
-static const x86_insn_info movszx_insn[] = {
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_8|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_8|OPA_EA, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 1, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_16|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 1, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPA_EA, 0} }
-};
-
-/* Move with sign-extend doubleword (64-bit mode only) */
-static const x86_insn_info movsxd_insn[] = {
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x63, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_32|OPA_EA, 0} }
-};
-
-/* Push instructions */
-static const x86_insn_info push_insn[] = {
- { CPU_Any, 0, 16, 1, {0x50, 0, 0}, 0, 1,
- {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0x50, 0, 0}, 0, 1,
- {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0x50, 0, 0}, 0, 1,
- {OPT_Reg|OPS_64|OPA_Op0Add, 0, 0} },
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 6, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0xFF, 0, 0}, 6, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0xFF, 0, 0}, 6, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0x6A, 0, 0}, 0, 1, {OPT_Imm|OPS_8|OPA_Imm, 0, 0} },
- { CPU_Any, 0, 16, 1, {0x68, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPA_Imm, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0x68, 0, 0}, 0, 1,
- {OPT_Imm|OPS_32|OPA_Imm, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x68, 0, 0}, 0, 1,
- {OPT_Imm|OPS_64|OPA_Imm, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_32|OPA_None, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_32|OPA_None, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_32|OPA_None, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_32|OPA_None, 0, 0} },
- { CPU_386, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1,
- {OPT_FS|OPS_Any|OPA_None, 0, 0} },
- { CPU_386, 0, 16, 2, {0x0F, 0xA0, 0}, 0, 1,
- {OPT_FS|OPS_16|OPA_None, 0, 0} },
- { CPU_386, 0, 32, 2, {0x0F, 0xA0, 0}, 0, 1,
- {OPT_FS|OPS_32|OPA_None, 0, 0} },
- { CPU_386, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1,
- {OPT_GS|OPS_Any|OPA_None, 0, 0} },
- { CPU_386, 0, 16, 2, {0x0F, 0xA8, 0}, 0, 1,
- {OPT_GS|OPS_16|OPA_None, 0, 0} },
- { CPU_386, 0, 32, 2, {0x0F, 0xA8, 0}, 0, 1,
- {OPT_GS|OPS_32|OPA_None, 0, 0} }
-};
-
-/* Pop instructions */
-static const x86_insn_info pop_insn[] = {
- { CPU_Any, 0, 16, 1, {0x58, 0, 0}, 0, 1,
- {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0x58, 0, 0}, 0, 1,
- {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0x58, 0, 0}, 0, 1,
- {OPT_Reg|OPS_64|OPA_Op0Add, 0, 0} },
- { CPU_Any, 0, 16, 1, {0x8F, 0, 0}, 0, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0x8F, 0, 0}, 0, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0x8F, 0, 0}, 0, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
- /* POP CS is debateably valid on the 8086, if obsolete and undocumented.
- * We don't include it because it's VERY unlikely it will ever be used
- * anywhere. If someone really wants it they can db 0x0F it.
- */
- /*{ CPU_Any|CPU_Undoc|CPU_Obs, 0, 0, 1, {0x0F, 0, 0}, 0, 1,
- {OPT_CS|OPS_Any|OPA_None, 0, 0} },*/
- { CPU_Not64, 0, 0, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_32|OPA_None, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_32|OPA_None, 0, 0} },
- { CPU_Not64, 0, 0, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_Any|OPA_None, 0, 0} },
- { CPU_Not64, 0, 16, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_16|OPA_None, 0, 0} },
- { CPU_Not64, 0, 32, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_32|OPA_None, 0, 0} },
- { CPU_386, 0, 0, 2, {0x0F, 0xA1, 0}, 0, 1,
- {OPT_FS|OPS_Any|OPA_None, 0, 0} },
- { CPU_386, 0, 16, 2, {0x0F, 0xA1, 0}, 0, 1,
- {OPT_FS|OPS_16|OPA_None, 0, 0} },
- { CPU_386, 0, 32, 2, {0x0F, 0xA1, 0}, 0, 1,
- {OPT_FS|OPS_32|OPA_None, 0, 0} },
- { CPU_386, 0, 0, 2, {0x0F, 0xA9, 0}, 0, 1,
- {OPT_GS|OPS_Any|OPA_None, 0, 0} },
- { CPU_386, 0, 16, 2, {0x0F, 0xA9, 0}, 0, 1,
- {OPT_GS|OPS_16|OPA_None, 0, 0} },
- { CPU_386, 0, 32, 2, {0x0F, 0xA9, 0}, 0, 1,
- {OPT_GS|OPS_32|OPA_None, 0, 0} }
-};
-
-/* Exchange instructions */
-static const x86_insn_info xchg_insn[] = {
- { CPU_Any, 0, 0, 1, {0x86, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_Any, 0, 0, 1, {0x86, 0, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Any, 0, 16, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_Reg|OPS_16|OPA_Op0Add, 0} },
- { CPU_Any, 0, 16, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Op0Add, OPT_Areg|OPS_16|OPA_None, 0} },
- { CPU_Any, 0, 16, 1, {0x87, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_Any, 0, 16, 1, {0x87, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_Reg|OPS_32|OPA_Op0Add, 0} },
- { CPU_386, 0, 32, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Op0Add, OPT_Areg|OPS_32|OPA_None, 0} },
- { CPU_386, 0, 32, 1, {0x87, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_386, 0, 32, 1, {0x87, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Areg|OPS_64|OPA_None, OPT_Reg|OPS_64|OPA_Op0Add, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x90, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Areg|OPS_64|OPA_None, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x87, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x87, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* In/out from ports */
-static const x86_insn_info in_insn[] = {
- { CPU_Any, 0, 0, 1, {0xE4, 0, 0}, 0, 2,
- {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xE5, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xE5, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 0, 1, {0xEC, 0, 0}, 0, 2,
- {OPT_Areg|OPS_8|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} },
- { CPU_Any, 0, 16, 1, {0xED, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} },
- { CPU_386, 0, 32, 1, {0xED, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} }
-};
-static const x86_insn_info out_insn[] = {
- { CPU_Any, 0, 0, 1, {0xE6, 0, 0}, 0, 2,
- {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_8|OPA_None, 0} },
- { CPU_Any, 0, 16, 1, {0xE7, 0, 0}, 0, 2,
- {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_16|OPA_None, 0} },
- { CPU_386, 0, 32, 1, {0xE7, 0, 0}, 0, 2,
- {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_32|OPA_None, 0} },
- { CPU_Any, 0, 0, 1, {0xEE, 0, 0}, 0, 2,
- {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_8|OPA_None, 0} },
- { CPU_Any, 0, 16, 1, {0xEF, 0, 0}, 0, 2,
- {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_16|OPA_None, 0} },
- { CPU_386, 0, 32, 1, {0xEF, 0, 0}, 0, 2,
- {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_32|OPA_None, 0} }
-};
-
-/* Load effective address */
-static const x86_insn_info lea_insn[] = {
- { CPU_Any, 0, 16, 1, {0x8D, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0x8D, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x8D, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Load segment registers from memory */
-static const x86_insn_info ldes_insn[] = {
- { CPU_Not64, MOD_Op0Add, 16, 1, {0, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} },
- { CPU_386|CPU_Not64, MOD_Op0Add, 32, 1, {0, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} }
-};
-static const x86_insn_info lfgss_insn[] = {
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} }
-};
-
-/* Arithmetic - general */
-static const x86_insn_info arith_insn[] = {
- { CPU_Any, MOD_Op0Add, 0, 1, {0x04, 0, 0}, 0, 2,
- {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, MOD_Op0Add, 16, 1, {0x05, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, MOD_Op0Add, 32, 1, {0x05, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 1, {0x05, 0, 0}, 0, 2,
- {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 1, {0x80, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 1, {0x80, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 1, {0x83, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 1, {0x81, 0x83, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA,
- OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 1, {0x81, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 1, {0x83, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 1, {0x81, 0x83, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 1, {0x81, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 1, {0x83, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} },
- { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 1, {0x81, 0x83, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} },
- { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 1, {0x81, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
-
- { CPU_Any, MOD_Op0Add, 0, 1, {0x00, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_Any, MOD_Op0Add, 16, 1, {0x01, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386, MOD_Op0Add, 32, 1, {0x01, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 1, {0x01, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
- { CPU_Any, MOD_Op0Add, 0, 1, {0x02, 0, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Any, MOD_Op0Add, 16, 1, {0x03, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, MOD_Op0Add, 32, 1, {0x03, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 1, {0x03, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Arithmetic - inc/dec */
-static const x86_insn_info incdec_insn[] = {
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 1, {0xFE, 0, 0}, 0, 1,
- {OPT_RM|OPS_8|OPA_EA, 0, 0} },
- { CPU_Not64, MOD_Op0Add, 16, 1, {0, 0, 0}, 0, 1,
- {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} },
- { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 1, {0xFF, 0, 0}, 0, 1,
- {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, MOD_Op0Add, 32, 1, {0, 0, 0}, 0, 1,
- {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 1, {0xFF, 0, 0}, 0, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 1, {0xFF, 0, 0}, 0, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
-};
-
-/* Arithmetic - "F6" opcodes (div/idiv/mul/neg/not) */
-static const x86_insn_info f6_insn[] = {
- { CPU_Any, MOD_SpAdd, 0, 1, {0xF6, 0, 0}, 0, 1,
- {OPT_RM|OPS_8|OPA_EA, 0, 0} },
- { CPU_Any, MOD_SpAdd, 16, 1, {0xF7, 0, 0}, 0, 1,
- {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386, MOD_SpAdd, 32, 1, {0xF7, 0, 0}, 0, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 1, {0xF7, 0, 0}, 0, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
-};
-
-/* Arithmetic - test instruction */
-static const x86_insn_info test_insn[] = {
- { CPU_Any, 0, 0, 1, {0xA8, 0, 0}, 0, 2,
- {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xA9, 0, 0}, 0, 2,
- {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xA9, 0, 0}, 0, 2,
- {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xA9, 0, 0}, 0, 2,
- {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
-
- { CPU_Any, 0, 0, 1, {0xF6, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 0, 1, {0xF6, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Any, 0, 16, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_386, 0, 32, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xF7, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} },
-
- { CPU_Any, 0, 0, 1, {0x84, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_Any, 0, 16, 1, {0x85, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386, 0, 32, 1, {0x85, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x85, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
-
- { CPU_Any, 0, 0, 1, {0x84, 0, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Any, 0, 16, 1, {0x85, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0x85, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x85, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Arithmetic - aad/aam */
-static const x86_insn_info aadm_insn[] = {
- { CPU_Any, MOD_Op0Add, 0, 2, {0xD4, 0x0A, 0}, 0, 0, {0, 0, 0} },
- { CPU_Any, MOD_Op0Add, 0, 1, {0xD4, 0, 0}, 0, 1,
- {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0, 0} }
-};
-
-/* Arithmetic - imul */
-static const x86_insn_info imul_insn[] = {
- { CPU_Any, 0, 0, 1, {0xF6, 0, 0}, 5, 1, {OPT_RM|OPS_8|OPA_EA, 0, 0} },
- { CPU_Any, 0, 16, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386, 0, 32, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0xF7, 0, 0}, 5, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
-
- { CPU_386, 0, 16, 2, {0x0F, 0xAF, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 2, {0x0F, 0xAF, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0xAF, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} },
-
- { CPU_186, 0, 16, 1, {0x6B, 0, 0}, 0, 3,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPA_SImm} },
- { CPU_386, 0, 32, 1, {0x6B, 0, 0}, 0, 3,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPA_SImm} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x6B, 0, 0}, 0, 3,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPA_SImm} },
-
- { CPU_186, 0, 16, 1, {0x6B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} },
- { CPU_386, 0, 32, 1, {0x6B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x6B, 0, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} },
-
- { CPU_186, 0, 16, 1, {0x69, 0x6B, 0}, 0, 3,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} },
- { CPU_386, 0, 32, 1, {0x69, 0x6B, 0}, 0, 3,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x69, 0x6B, 0}, 0, 3,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} },
-
- { CPU_186, 0, 16, 1, {0x69, 0x6B, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_SpareEA,
- OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} },
- { CPU_386, 0, 32, 1, {0x69, 0x6B, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_SpareEA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 1, {0x69, 0x6B, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_SpareEA,
- OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} }
-};
-
-/* Shifts - standard */
-static const x86_insn_info shift_insn[] = {
- { CPU_Any, MOD_SpAdd, 0, 1, {0xD2, 0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} },
- /* FIXME: imm8 is only avail on 186+, but we use imm8 to get to postponed
- * ,1 form, so it has to be marked as Any. We need to store the active
- * CPU flags somewhere to pass that parse-time info down the line.
- */
- { CPU_Any, MOD_SpAdd, 0, 1, {0xC0, 0xD0, 0}, 0, 2,
- {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp,
- 0} },
- { CPU_Any, MOD_SpAdd, 16, 1, {0xD3, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} },
- { CPU_Any, MOD_SpAdd, 16, 1, {0xC1, 0xD1, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp,
- 0} },
- { CPU_Any, MOD_SpAdd, 32, 1, {0xD3, 0, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} },
- { CPU_Any, MOD_SpAdd, 32, 1, {0xC1, 0xD1, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp,
- 0} },
- { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 1, {0xD3, 0, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} },
- { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 1, {0xC1, 0xD1, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp,
- 0} }
-};
-
-/* Shifts - doubleword */
-static const x86_insn_info shlrd_insn[] = {
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0x00, 0}, 0, 3,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0x01, 0}, 0, 3,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare,
- OPT_Creg|OPS_8|OPA_None} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x00, 0}, 0, 3,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x01, 0}, 0, 3,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare,
- OPT_Creg|OPS_8|OPA_None} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x00, 0}, 0, 3,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x01, 0}, 0, 3,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare,
- OPT_Creg|OPS_8|OPA_None} }
-};
-
-/* Control transfer instructions (unconditional) */
-static const x86_insn_info call_insn[] = {
- { CPU_Any, 0, 0, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 16, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} },
- { CPU_386, 0, 32, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
-
- { CPU_Any, 0, 16, 1, {0xE8, 0, 0}, 0, 1,
- {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_386, 0, 32, 1, {0xE8, 0, 0}, 0, 1,
- {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xE8, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel, 0, 0} },
-
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 2, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 2, 1, {OPT_Mem|OPS_Any|OPA_EA, 0, 0} },
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_RM|OPS_16|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_RM|OPS_32|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_RM|OPS_64|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 2, 1,
- {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} },
-
- /* TODO: Far Imm 16:16/32 */
-
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 3, 1,
- {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} },
- { CPU_386, 0, 32, 1, {0xFF, 0, 0}, 3, 1,
- {OPT_Mem|OPS_32|OPTM_Far|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 3, 1,
- {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} }
-};
-static const x86_insn_info jmp_insn[] = {
- { CPU_Any, 0, 0, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 16, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} },
- { CPU_386, 0, 32, 1, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
-
- { CPU_Any, 0, 0, 1, {0xEB, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 16, 1, {0xE9, 0, 0}, 0, 1,
- {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_386, 0, 32, 1, {0xE9, 0, 0}, 0, 1,
- {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xE9, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel, 0, 0} },
-
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 4, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_RM|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_RM|OPS_64|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 4, 1, {OPT_Mem|OPS_Any|OPA_EA, 0, 0} },
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_RM|OPS_16|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_386|CPU_Not64, 0, 32, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_RM|OPS_32|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_RM|OPS_64|OPTM_Near|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 4, 1,
- {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} },
-
- /* TODO: Far Imm 16:16/32 */
-
- { CPU_Any, 0, 16, 1, {0xFF, 0, 0}, 5, 1,
- {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} },
- { CPU_386, 0, 32, 1, {0xFF, 0, 0}, 5, 1,
- {OPT_Mem|OPS_32|OPTM_Far|OPA_EA, 0, 0} },
- { CPU_Any, 0, 0, 1, {0xFF, 0, 0}, 5, 1,
- {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} }
-};
-static const x86_insn_info retnf_insn[] = {
- { CPU_Any, MOD_Op0Add, 0, 1, {0x01, 0, 0}, 0, 0, {0, 0, 0} },
- { CPU_Any, MOD_Op0Add, 0, 1, {0x00, 0, 0}, 0, 1,
- {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} }
-};
-static const x86_insn_info enter_insn[] = {
- { CPU_186, 0, 0, 1, {0xC8, 0, 0}, 0, 2,
- {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm,
- 0} }
-};
-
-/* Conditional jumps */
-static const x86_insn_info jcc_insn[] = {
- { CPU_Any, 0, 0, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
- { CPU_Any, 0, 16, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} },
- { CPU_386, 0, 32, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
- { CPU_Any, MOD_Op0Add, 0, 1, {0x70, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} },
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0x80, 0}, 0, 1,
- {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x80, 0}, 0, 1,
- {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} },
- { CPU_386, MOD_Op1Add, 0, 2, {0x0F, 0x80, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel, 0, 0} }
-};
-static const x86_insn_info jcxz_insn[] = {
- { CPU_Any, MOD_AdSizeR, 0, 0, {0, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
- { CPU_Any, MOD_AdSizeR, 0, 1, {0xE3, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} }
-};
-
-/* Loop instructions */
-static const x86_insn_info loop_insn[] = {
- { CPU_Any, 0, 0, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
- { CPU_Not64, 0, 0, 0, {0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_16|OPA_AdSizeR, 0} },
- { CPU_386, 0, 0, 0, {0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_32|OPA_AdSizeR, 0} },
- { CPU_Hammer|CPU_64, 0, 0, 0, {0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_64|OPA_AdSizeR, 0} },
-
- { CPU_Not64, MOD_Op0Add, 0, 1, {0xE0, 0, 0}, 0, 1,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} },
- { CPU_Any, MOD_Op0Add, 0, 1, {0xE0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_16|OPA_AdSizeR, 0}
- },
- { CPU_386, MOD_Op0Add, 0, 1, {0xE0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_32|OPA_AdSizeR, 0}
- },
- { CPU_Hammer|CPU_64, MOD_Op0Add, 0, 1, {0xE0, 0, 0}, 0, 2,
- {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_64|OPA_AdSizeR, 0} }
-};
-
-/* Set byte on flag instructions */
-static const x86_insn_info setcc_insn[] = {
- { CPU_386, MOD_Op1Add, 0, 2, {0x0F, 0x90, 0}, 2, 1,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-
-/* Bit manipulation - bit tests */
-static const x86_insn_info bittest_insn[] = {
- { CPU_386, MOD_Op1Add, 16, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 16, 2, {0x0F, 0xBA, 0}, 0, 2,
- {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
- { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 2, {0x0F, 0xBA, 0}, 0, 2,
- {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} },
- { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 2, {0x0F, 0xBA, 0}, 0, 2,
- {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} }
-};
-
-/* Bit manipulation - bit scans - also used for lar/lsl */
-static const x86_insn_info bsfr_insn[] = {
- { CPU_286, MOD_Op1Add, 16, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, MOD_Op1Add, 32, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Interrupts and operating system instructions */
-static const x86_insn_info int_insn[] = {
- { CPU_Any, 0, 0, 1, {0xCD, 0, 0}, 0, 1,
- {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0, 0} }
-};
-static const x86_insn_info bound_insn[] = {
- { CPU_186, 0, 16, 1, {0x62, 0, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386, 0, 32, 1, {0x62, 0, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Protection control */
-static const x86_insn_info arpl_insn[] = {
- { CPU_286|CPU_Prot, 0, 0, 1, {0x63, 0, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }
-};
-static const x86_insn_info str_insn[] = {
- { CPU_Hammer, 0, 16, 2, {0x0F, 0x00, 0}, 1, 1,
- {OPT_Reg|OPS_16|OPA_EA, 0, 0} },
- { CPU_Hammer, 0, 32, 2, {0x0F, 0x00, 0}, 1, 1,
- {OPT_Reg|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0x00, 0}, 1, 1,
- {OPT_Reg|OPS_64|OPA_EA, 0, 0} },
- { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info prot286_insn[] = {
- { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info sldtmsw_insn[] = {
- { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
- { CPU_386, MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0, 0} },
- { CPU_286, MOD_Op1Add|MOD_SpAdd, 16, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_16|OPA_EA, 0, 0} },
- { CPU_386, MOD_Op1Add|MOD_SpAdd, 32, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_32|OPA_EA, 0, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_SpAdd, 64, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_64|OPA_EA, 0, 0} }
-};
-
-/* Floating point instructions - load/store with pop (integer and normal) */
-static const x86_insn_info fldstp_insn[] = {
- { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDD, 0, 0}, 0, 1,
- {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
- {OPT_Mem|OPS_80|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xD9, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
-};
-static const x86_insn_info fildstp_insn[] = {
- { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
- {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
- {OPT_Mem|OPS_64|OPA_EA, 0, 0} }
-};
-static const x86_insn_info fbldstp_insn[] = {
- { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
- {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-/* Floating point instructions - store (normal) */
-static const x86_insn_info fst_insn[] = {
- { CPU_FPU, 0, 0, 1, {0xD9, 0, 0}, 2, 1, {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
- { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 2, 1, {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
- { CPU_FPU, 0, 0, 2, {0xDD, 0xD0, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
-};
-/* Floating point instructions - exchange (with ST0) */
-static const x86_insn_info fxch_insn[] = {
- { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
- { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
- {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
- { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
- {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} },
- { CPU_FPU, 0, 0, 2, {0xD9, 0xC9, 0}, 0, 0, {0, 0, 0} }
-};
-/* Floating point instructions - comparisons */
-static const x86_insn_info fcom_insn[] = {
- { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
- {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
- {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
-};
-/* Floating point instructions - extended comparisons */
-static const x86_insn_info fcom2_insn[] = {
- { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
- { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 2,
- {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
-};
-/* Floating point instructions - arithmetic */
-static const x86_insn_info farith_insn[] = {
- { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
- {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
- { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
- {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPTM_To|OPA_Op1Add, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
-};
-static const x86_insn_info farithp_insn[] = {
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x01, 0}, 0, 0, {0, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
- { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 2,
- {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
-};
-/* Floating point instructions - integer arith/store wo pop/compare */
-static const x86_insn_info fiarith_insn[] = {
- { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x04, 0, 0}, 0, 1,
- {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
- { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x00, 0, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPA_EA, 0, 0} }
-};
-/* Floating point instructions - processor control */
-static const x86_insn_info fldnstcw_insn[] = {
- { CPU_FPU, MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info fstcw_insn[] = {
- { CPU_FPU, 0, 0, 2, {0x9B, 0xD9, 0}, 7, 1,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info fnstsw_insn[] = {
- { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 7, 1,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
- { CPU_FPU, 0, 0, 2, {0xDF, 0xE0, 0}, 0, 1,
- {OPT_Areg|OPS_16|OPA_None, 0, 0} }
-};
-static const x86_insn_info fstsw_insn[] = {
- { CPU_FPU, 0, 0, 2, {0x9B, 0xDD, 0}, 7, 1,
- {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
- { CPU_FPU, 0, 0, 3, {0x9B, 0xDF, 0xE0}, 0, 1,
- {OPT_Areg|OPS_16|OPA_None, 0, 0} }
-};
-static const x86_insn_info ffree_insn[] = {
- { CPU_FPU, MOD_Op0Add, 0, 2, {0x00, 0xC0, 0}, 0, 1,
- {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
-};
-
-/* 486 extensions */
-static const x86_insn_info bswap_insn[] = {
- { CPU_486, 0, 32, 2, {0x0F, 0xC8, 0}, 0, 1,
- {OPT_Reg|OPS_32|OPA_Op1Add, 0, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0xC8, 0}, 0, 1,
- {OPT_Reg|OPS_64|OPA_Op1Add, 0, 0} }
-};
-static const x86_insn_info cmpxchgxadd_insn[] = {
- { CPU_486, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_486, MOD_Op1Add, 16, 2, {0x0F, 0x01, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_486, MOD_Op1Add, 32, 2, {0x0F, 0x01, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x01, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }
-};
-
-/* Pentium extensions */
-static const x86_insn_info cmpxchg8b_insn[] = {
- { CPU_586, 0, 0, 2, {0x0F, 0xC7, 0}, 1, 1,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-
-/* Pentium II/Pentium Pro extensions */
-static const x86_insn_info cmovcc_insn[] = {
- { CPU_686, MOD_Op1Add, 16, 2, {0x0F, 0x40, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_686, MOD_Op1Add, 32, 2, {0x0F, 0x40, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 2, {0x0F, 0x40, 0}, 0, 2,
- {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-static const x86_insn_info fcmovcc_insn[] = {
- { CPU_686|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 2,
- {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
-};
-
-/* Pentium4 extensions */
-static const x86_insn_info movnti_insn[] = {
- { CPU_P4, 0, 0, 2, {0x0F, 0xC3, 0}, 0, 2,
- {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0xC3, 0}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }
-};
-static const x86_insn_info clflush_insn[] = {
- { CPU_P3, 0, 0, 2, {0x0F, 0xAE, 0}, 7, 1,
- {OPT_Mem|OPS_8|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-
-/* MMX/SSE2 instructions */
-static const x86_insn_info movd_insn[] = {
- { CPU_MMX, 0, 0, 2, {0x0F, 0x6E, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_MMX|CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0x6E, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_MMX, 0, 0, 2, {0x0F, 0x7E, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} },
- { CPU_MMX|CPU_Hammer|CPU_64, 0, 64, 2, {0x0F, 0x7E, 0}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0x6E}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE2|CPU_Hammer|CPU_64, 0, 64, 3, {0x66, 0x0F, 0x6E}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0x7E}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} },
- { CPU_SSE2|CPU_Hammer|CPU_64, 0, 64, 3, {0x66, 0x0F, 0x7E}, 0, 2,
- {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movq_insn[] = {
- { CPU_MMX, 0, 0, 2, {0x0F, 0x6F, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_MMX, 0, 0, 2, {0x0F, 0x7F, 0}, 0, 2,
- {OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0}
- },
- { CPU_SSE2, 0, 0, 3, {0xF3, 0x0F, 0x7E}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} },
- { CPU_SSE2, 0, 0, 3, {0xF3, 0x0F, 0x7E}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xD6}, 0, 2,
- {OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0}
- }
-};
-static const x86_insn_info mmxsse2_insn[] = {
- { CPU_MMX, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- }
-};
-static const x86_insn_info pshift_insn[] = {
- { CPU_MMX, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_MMX, MOD_Gap0|MOD_Op1Add|MOD_SpAdd, 0, 2, {0x0F, 0x00, 0}, 0,
- 2, {OPT_SIMDReg|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} },
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE2, MOD_Gap0|MOD_Op2Add|MOD_SpAdd, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }
-};
-
-/* PIII (Katmai) new instructions / SIMD instructiosn */
-static const x86_insn_info sseps_insn[] = {
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- }
-};
-static const x86_insn_info ssess_insn[] = {
- { CPU_SSE, MOD_Op0Add|MOD_Op2Add, 0, 3, {0x00, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- }
-};
-static const x86_insn_info ssecmpps_insn[] = {
- { CPU_SSE, MOD_Imm8, 0, 2, {0x0F, 0xC2, 0}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- }
-};
-static const x86_insn_info ssecmpss_insn[] = {
- { CPU_SSE, MOD_Op0Add|MOD_Imm8, 0, 3, {0x00, 0x0F, 0xC2}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- }
-};
-static const x86_insn_info ssepsimm_insn[] = {
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 3,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-static const x86_insn_info ssessimm_insn[] = {
- { CPU_SSE, MOD_Op0Add|MOD_Op2Add, 0, 3, {0x00, 0x0F, 0x00}, 0, 3,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-static const x86_insn_info ldstmxcsr_insn[] = {
- { CPU_SSE, MOD_SpAdd, 0, 2, {0x0F, 0xAE, 0}, 0, 1,
- {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info maskmovq_insn[] = {
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0xF7, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDReg|OPS_64|OPA_EA, 0} }
-};
-static const x86_insn_info movaups_insn[] = {
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x01, 0}, 0, 2,
- {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0}
- }
-};
-static const x86_insn_info movhllhps_insn[] = {
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
-};
-static const x86_insn_info movhlps_insn[] = {
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE, MOD_Op1Add, 0, 2, {0x0F, 0x01, 0}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movmskps_insn[] = {
- { CPU_SSE, 0, 0, 2, {0x0F, 0x50, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movntps_insn[] = {
- { CPU_SSE, 0, 0, 2, {0x0F, 0x2B, 0}, 0, 2,
- {OPT_Mem|OPS_128|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movntq_insn[] = {
- { CPU_SSE, 0, 0, 2, {0x0F, 0xE7, 0}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movss_insn[] = {
- { CPU_SSE, 0, 0, 3, {0xF3, 0x0F, 0x10}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} },
- { CPU_SSE, 0, 0, 3, {0xF3, 0x0F, 0x10}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE, 0, 0, 3, {0xF3, 0x0F, 0x11}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info pextrw_insn[] = {
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0xC5, 0}, 0, 3,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xC5}, 0, 3,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-static const x86_insn_info pinsrw_insn[] = {
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0xC4, 0}, 0, 3,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_Reg|OPS_32|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0xC4, 0}, 0, 3,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xC4}, 0, 3,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Reg|OPS_32|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xC4}, 0, 3,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-static const x86_insn_info pmovmskb_insn[] = {
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0xD7, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} },
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xD7}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info pshufw_insn[] = {
- { CPU_P3|CPU_MMX, 0, 0, 2, {0x0F, 0x70, 0}, 0, 3,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-
-/* SSE2 instructions */
-static const x86_insn_info cmpsd_insn[] = {
- { CPU_Any, 0, 32, 1, {0xA7, 0, 0}, 0, 0, {0, 0, 0} },
- { CPU_SSE2, 0, 0, 3, {0xF2, 0x0F, 0xC2}, 0, 3,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA,
- OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }
-};
-static const x86_insn_info movaupd_insn[] = {
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x01}, 0, 2,
- {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0}
- }
-};
-static const x86_insn_info movhlpd_insn[] = {
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x01}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movmskpd_insn[] = {
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0x50}, 0, 2,
- {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movntpddq_insn[] = {
- { CPU_SSE2, MOD_Op2Add, 0, 3, {0x66, 0x0F, 0x00}, 0, 2,
- {OPT_Mem|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info movsd_insn[] = {
- { CPU_Any, 0, 32, 1, {0xA5, 0, 0}, 0, 0, {0, 0, 0} },
- { CPU_SSE2, 0, 0, 3, {0xF2, 0x0F, 0x10}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} },
- { CPU_SSE2, 0, 0, 3, {0xF2, 0x0F, 0x10}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} },
- { CPU_SSE2, 0, 0, 3, {0xF2, 0x0F, 0x11}, 0, 2,
- {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }
-};
-static const x86_insn_info maskmovdqu_insn[] = {
- { CPU_SSE2, 0, 0, 3, {0x66, 0x0F, 0xF7}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
-};
-static const x86_insn_info movdqau_insn[] = {
- { CPU_SSE2, MOD_Op0Add, 0, 3, {0x00, 0x0F, 0x6F}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0}
- },
- { CPU_SSE2, MOD_Op0Add, 0, 3, {0x00, 0x0F, 0x7F}, 0, 2,
- {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0}
- }
-};
-static const x86_insn_info movdq2q_insn[] = {
- { CPU_SSE2, 0, 0, 3, {0xF2, 0x0F, 0xD6}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }
-};
-static const x86_insn_info movq2dq_insn[] = {
- { CPU_SSE2, 0, 0, 3, {0xF3, 0x0F, 0xD6}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_64|OPA_EA, 0} }
-};
-static const x86_insn_info pslrldq_insn[] = {
- { CPU_SSE2, MOD_SpAdd, 0, 3, {0x66, 0x0F, 0x73}, 0, 2,
- {OPT_SIMDReg|OPS_128|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }
-};
-
-/* AMD 3DNow! instructions */
-static const x86_insn_info now3d_insn[] = {
- { CPU_3DNow, MOD_Imm8, 0, 2, {0x0F, 0x0F, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Cyrix MMX instructions */
-static const x86_insn_info cyrixmmx_insn[] = {
- { CPU_Cyrix|CPU_MMX, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-static const x86_insn_info pmachriw_insn[] = {
- { CPU_Cyrix|CPU_MMX, 0, 0, 2, {0x0F, 0x5E, 0}, 0, 2,
- {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }
-};
-
-/* Cyrix extensions */
-static const x86_insn_info rsdc_insn[] = {
- { CPU_486|CPU_Cyrix|CPU_SMM, 0, 0, 2, {0x0F, 0x79, 0}, 0, 2,
- {OPT_SegReg|OPS_16|OPA_Spare, OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0} }
-};
-static const x86_insn_info cyrixsmm_insn[] = {
- { CPU_486|CPU_Cyrix|CPU_SMM, MOD_Op1Add, 0, 2, {0x0F, 0x00, 0}, 0, 1,
- {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} }
-};
-static const x86_insn_info svdc_insn[] = {
- { CPU_486|CPU_Cyrix|CPU_SMM, 0, 0, 2, {0x0F, 0x78, 0}, 0, 2,
- {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, OPT_SegReg|OPS_16|OPA_Spare, 0} }
-};
-
-/* Obsolete/undocumented instructions */
-static const x86_insn_info ibts_insn[] = {
- { CPU_386|CPU_Undoc|CPU_Obs, 0, 16, 2, {0x0F, 0xA7, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386|CPU_Undoc|CPU_Obs, 0, 32, 2, {0x0F, 0xA7, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }
-};
-static const x86_insn_info umov_insn[] = {
- { CPU_386|CPU_Undoc, 0, 0, 2, {0x0F, 0x10, 0}, 0, 2,
- {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} },
- { CPU_386|CPU_Undoc, 0, 16, 2, {0x0F, 0x11, 0}, 0, 2,
- {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} },
- { CPU_386|CPU_Undoc, 0, 32, 2, {0x0F, 0x11, 0}, 0, 2,
- {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} },
- { CPU_386|CPU_Undoc, 0, 0, 2, {0x0F, 0x12, 0}, 0, 2,
- {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386|CPU_Undoc, 0, 16, 2, {0x0F, 0x13, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386|CPU_Undoc, 0, 32, 2, {0x0F, 0x13, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }
-};
-static const x86_insn_info xbts_insn[] = {
- { CPU_386|CPU_Undoc|CPU_Obs, 0, 16, 2, {0x0F, 0xA6, 0}, 0, 2,
- {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} },
- { CPU_386|CPU_Undoc|CPU_Obs, 0, 32, 2, {0x0F, 0xA6, 0}, 0, 2,
- {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} }
-};
-
-
-static yasm_bytecode *
-x86_new_jmprel(const unsigned long data[4], int num_operands,
- yasm_insn_operandhead *operands, x86_insn_info *jrinfo,
- yasm_section *cur_section, /*@null@*/ yasm_bytecode *prev_bc,
- unsigned long lindex)
-{
- x86_new_jmprel_data d;
- int num_info = (int)(data[1]&0xFF);
- x86_insn_info *info = (x86_insn_info *)data[0];
- unsigned long mod_data = data[1] >> 8;
- yasm_insn_operand *op;
- static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
-
- d.lindex = lindex;
-
- /* We know the target is in operand 0, but sanity check for Imm. */
- op = yasm_ops_first(operands);
- if (op->type != YASM_INSN__OPERAND_IMM)
- yasm_internal_error(N_("invalid operand conversion"));
- d.target = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(op->data.val),
- yasm_expr_sym(yasm_symrec_define_label("$", cur_section, prev_bc,
- 0, lindex)), lindex);
-
- /* See if the user explicitly specified short/near. */
- switch (jrinfo->operands[0] & OPTM_MASK) {
- case OPTM_Short:
- d.op_sel = JR_SHORT_FORCED;
- break;
- case OPTM_Near:
- d.op_sel = JR_NEAR_FORCED;
- break;
- default:
- d.op_sel = JR_NONE;
- }
-
- /* Set operand size */
- d.opersize = jrinfo->opersize;
-
- /* Check for address size setting in second operand, if present */
- if (jrinfo->num_operands > 1 &&
- (jrinfo->operands[1] & OPA_MASK) == OPA_AdSizeR)
- d.addrsize = (unsigned char)size_lookup[(jrinfo->operands[1] &
- OPS_MASK)>>OPS_SHIFT];
- else
- d.addrsize = 0;
-
- /* Check for address size override */
- if (jrinfo->modifiers & MOD_AdSizeR)
- d.addrsize = (unsigned char)(mod_data & 0xFF);
-
- /* Scan through other infos for this insn looking for short/near versions.
- * Needs to match opersize and number of operands, also be within CPU.
- */
- d.short_op_len = 0;
- d.near_op_len = 0;
- for (; num_info>0 && (d.short_op_len == 0 || d.near_op_len == 0);
- num_info--, info++) {
- unsigned long cpu = info->cpu | data[2];
-
- if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
- continue;
- if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
- continue;
- cpu &= ~(CPU_64 | CPU_Not64);
-
- if ((cpu_enabled & cpu) != cpu)
- continue;
-
- if (info->num_operands == 0)
- continue;
-
- if ((info->operands[0] & OPA_MASK) != OPA_JmpRel)
- continue;
-
- if (info->opersize != d.opersize)
- continue;
-
- switch (info->operands[0] & OPTM_MASK) {
- case OPTM_Short:
- d.short_op_len = info->opcode_len;
- d.short_op[0] = info->opcode[0];
- d.short_op[1] = info->opcode[1];
- d.short_op[2] = info->opcode[2];
- if (info->modifiers & MOD_Op0Add)
- d.short_op[0] += (unsigned char)(mod_data & 0xFF);
- break;
- case OPTM_Near:
- d.near_op_len = info->opcode_len;
- d.near_op[0] = info->opcode[0];
- d.near_op[1] = info->opcode[1];
- d.near_op[2] = info->opcode[2];
- if (info->modifiers & MOD_Op1Add)
- d.near_op[1] += (unsigned char)(mod_data & 0xFF);
- break;
- }
- }
-
- return yasm_x86__bc_new_jmprel(&d);
-}
-
-yasm_bytecode *
-yasm_x86__new_insn(const unsigned long data[4], int num_operands,
- yasm_insn_operandhead *operands, yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex)
-{
- x86_new_insn_data d;
- int num_info = (int)(data[1]&0xFF);
- x86_insn_info *info = (x86_insn_info *)data[0];
- unsigned long mod_data = data[1] >> 8;
- int found = 0;
- yasm_insn_operand *op;
- int i;
- static const unsigned int size_lookup[] = {0, 1, 2, 4, 8, 10, 16, 0};
-
- /* Just do a simple linear search through the info array for a match.
- * First match wins.
- */
- for (; num_info>0 && !found; num_info--, info++) {
- unsigned long cpu;
- unsigned int size;
- int mismatch = 0;
-
- /* Match CPU */
- cpu = info->cpu | data[2];
-
- if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
- continue;
- if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
- continue;
- cpu &= ~(CPU_64 | CPU_Not64);
-
- if ((cpu_enabled & cpu) != cpu)
- continue;
-
- /* Match # of operands */
- if (num_operands != info->num_operands)
- continue;
-
- if (!operands) {
- found = 1; /* no operands -> must have a match here. */
- break;
- }
-
- /* Match each operand type and size */
- for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
- !mismatch; op = yasm_ops_next(op), i++) {
- /* Check operand type */
- switch (info->operands[i] & OPT_MASK) {
- case OPT_Imm:
- if (op->type != YASM_INSN__OPERAND_IMM)
- mismatch = 1;
- break;
- case OPT_RM:
- if (op->type == YASM_INSN__OPERAND_MEMORY)
- break;
- /*@fallthrough@*/
- case OPT_Reg:
- if (op->type != YASM_INSN__OPERAND_REG)
- mismatch = 1;
- else {
- switch ((x86_expritem_reg_size)(op->data.reg & ~0xF)) {
- case X86_REG8:
- case X86_REG8X:
- case X86_REG16:
- case X86_REG32:
- case X86_REG64:
- case X86_FPUREG:
- break;
- default:
- mismatch = 1;
- break;
- }
- }
- break;
- case OPT_Mem:
- if (op->type != YASM_INSN__OPERAND_MEMORY)
- mismatch = 1;
- break;
- case OPT_SIMDRM:
- if (op->type == YASM_INSN__OPERAND_MEMORY)
- break;
- /*@fallthrough@*/
- case OPT_SIMDReg:
- if (op->type != YASM_INSN__OPERAND_REG)
- mismatch = 1;
- else {
- switch ((x86_expritem_reg_size)(op->data.reg & ~0xF)) {
- case X86_MMXREG:
- case X86_XMMREG:
- break;
- default:
- mismatch = 1;
- break;
- }
- }
- break;
- case OPT_SegReg:
- if (op->type != YASM_INSN__OPERAND_SEGREG)
- mismatch = 1;
- break;
- case OPT_CRReg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- (op->data.reg & ~0xF) != X86_CRREG)
- mismatch = 1;
- break;
- case OPT_DRReg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- (op->data.reg & ~0xF) != X86_DRREG)
- mismatch = 1;
- break;
- case OPT_TRReg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- (op->data.reg & ~0xF) != X86_TRREG)
- mismatch = 1;
- break;
- case OPT_ST0:
- if (op->type != YASM_INSN__OPERAND_REG ||
- op->data.reg != X86_FPUREG)
- mismatch = 1;
- break;
- case OPT_Areg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- ((info->operands[i] & OPS_MASK) == OPS_8 &&
- op->data.reg != (X86_REG8 | 0) &&
- op->data.reg != (X86_REG8X | 0)) ||
- ((info->operands[i] & OPS_MASK) == OPS_16 &&
- op->data.reg != (X86_REG16 | 0)) ||
- ((info->operands[i] & OPS_MASK) == OPS_32 &&
- op->data.reg != (X86_REG32 | 0)) ||
- ((info->operands[i] & OPS_MASK) == OPS_64 &&
- op->data.reg != (X86_REG64 | 0)))
- mismatch = 1;
- break;
- case OPT_Creg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- ((info->operands[i] & OPS_MASK) == OPS_8 &&
- op->data.reg != (X86_REG8 | 1) &&
- op->data.reg != (X86_REG8X | 1)) ||
- ((info->operands[i] & OPS_MASK) == OPS_16 &&
- op->data.reg != (X86_REG16 | 1)) ||
- ((info->operands[i] & OPS_MASK) == OPS_32 &&
- op->data.reg != (X86_REG32 | 1)) ||
- ((info->operands[i] & OPS_MASK) == OPS_64 &&
- op->data.reg != (X86_REG64 | 1)))
- mismatch = 1;
- break;
- case OPT_Dreg:
- if (op->type != YASM_INSN__OPERAND_REG ||
- ((info->operands[i] & OPS_MASK) == OPS_8 &&
- op->data.reg != (X86_REG8 | 2) &&
- op->data.reg != (X86_REG8X | 2)) ||
- ((info->operands[i] & OPS_MASK) == OPS_16 &&
- op->data.reg != (X86_REG16 | 2)) ||
- ((info->operands[i] & OPS_MASK) == OPS_32 &&
- op->data.reg != (X86_REG32 | 2)) ||
- ((info->operands[i] & OPS_MASK) == OPS_64 &&
- op->data.reg != (X86_REG64 | 2)))
- mismatch = 1;
- break;
- case OPT_CS:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 1)
- mismatch = 1;
- break;
- case OPT_DS:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 3)
- mismatch = 1;
- break;
- case OPT_ES:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 0)
- mismatch = 1;
- break;
- case OPT_FS:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 4)
- mismatch = 1;
- break;
- case OPT_GS:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 5)
- mismatch = 1;
- break;
- case OPT_SS:
- if (op->type != YASM_INSN__OPERAND_SEGREG ||
- (op->data.reg & 0xF) != 2)
- mismatch = 1;
- break;
- case OPT_CR4:
- if (op->type != YASM_INSN__OPERAND_REG ||
- op->data.reg != (X86_CRREG | 4))
- mismatch = 1;
- break;
- case OPT_MemOffs:
- if (op->type != YASM_INSN__OPERAND_MEMORY ||
- yasm_expr__contains(yasm_ea_get_disp(op->data.ea),
- YASM_EXPR_REG))
- mismatch = 1;
- break;
- default:
- yasm_internal_error(N_("invalid operand type"));
- }
-
- if (mismatch)
- break;
-
- /* Check operand size */
- size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT];
- if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
- /* Register size must exactly match */
- if (yasm_x86__get_reg_size(op->data.reg) != size)
- mismatch = 1;
- } else {
- if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
- /* Relaxed checking */
- if (size != 0 && op->size != size && op->size != 0)
- mismatch = 1;
- } else {
- /* Strict checking */
- if (op->size != size)
- mismatch = 1;
- }
- }
-
- if (mismatch)
- break;
-
- /* Check target modifier */
- switch (info->operands[i] & OPTM_MASK) {
- case OPTM_None:
- if (op->targetmod != 0)
- mismatch = 1;
- break;
- case OPTM_Near:
- if (op->targetmod != X86_NEAR)
- mismatch = 1;
- break;
- case OPTM_Short:
- if (op->targetmod != X86_SHORT)
- mismatch = 1;
- break;
- case OPTM_Far:
- if (op->targetmod != X86_FAR)
- mismatch = 1;
- break;
- case OPTM_To:
- if (op->targetmod != X86_TO)
- mismatch = 1;
- break;
- default:
- yasm_internal_error(N_("invalid target modifier type"));
- }
- }
-
- if (!mismatch) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- /* Didn't find a matching one */
- yasm__error(lindex, N_("invalid combination of opcode and operands"));
- return NULL;
- }
-
- /* Extended error/warning handling */
- switch (info->modifiers & MOD_Ext_MASK) {
- case MOD_ExtNone:
- /* No extended modifier, so just continue */
- break;
- case MOD_ExtErr:
- switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
- case 0:
- yasm__error(lindex, N_("mismatch in operand sizes"));
- break;
- case 1:
- yasm__error(lindex, N_("operand size not specified"));
- break;
- default:
- yasm_internal_error(N_("unrecognized x86 ext mod index"));
- }
- return NULL; /* It was an error */
- case MOD_ExtWarn:
- switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) {
- default:
- yasm_internal_error(N_("unrecognized x86 ext mod index"));
- }
- break;
- default:
- yasm_internal_error(N_("unrecognized x86 extended modifier"));
- }
-
- /* Shortcut to JmpRel */
- if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel)
- return x86_new_jmprel(data, num_operands, operands, info, cur_section,
- prev_bc, lindex);
-
- /* Copy what we can from info */
- d.lindex = lindex;
- d.ea = NULL;
- d.imm = NULL;
- d.opersize = info->opersize;
- d.op_len = info->opcode_len;
- d.op[0] = info->opcode[0];
- d.op[1] = info->opcode[1];
- d.op[2] = info->opcode[2];
- d.spare = info->spare;
- d.rex = (yasm_x86_LTX_mode_bits == 64 && info->opersize == 64) ? 0x48: 0;
- d.im_len = 0;
- d.im_sign = 0;
- d.shift_op = 0;
- d.signext_imm8_op = 0;
-
- /* Apply modifiers */
- if (info->modifiers & MOD_Op2Add) {
- d.op[2] += (unsigned char)(mod_data & 0xFF);
- mod_data >>= 8;
- }
- if (info->modifiers & MOD_Gap0)
- mod_data >>= 8;
- if (info->modifiers & MOD_Op1Add) {
- d.op[1] += (unsigned char)(mod_data & 0xFF);
- mod_data >>= 8;
- }
- if (info->modifiers & MOD_Gap1)
- mod_data >>= 8;
- if (info->modifiers & MOD_Op0Add) {
- d.op[0] += (unsigned char)(mod_data & 0xFF);
- mod_data >>= 8;
- }
- if (info->modifiers & MOD_SpAdd) {
- d.spare += (unsigned char)(mod_data & 0xFF);
- mod_data >>= 8;
- }
- if (info->modifiers & MOD_OpSizeR) {
- d.opersize = (unsigned char)(mod_data & 0xFF);
- mod_data >>= 8;
- }
- if (info->modifiers & MOD_Imm8) {
- d.imm = yasm_expr_new_ident(yasm_expr_int(
- yasm_intnum_new_int(mod_data & 0xFF)), lindex);
- d.im_len = 1;
- /*mod_data >>= 8;*/
- }
-
- /* Go through operands and assign */
- if (operands) {
- for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
- op = yasm_ops_next(op), i++) {
- switch (info->operands[i] & OPA_MASK) {
- case OPA_None:
- /* Throw away the operand contents */
- switch (op->type) {
- case YASM_INSN__OPERAND_REG:
- case YASM_INSN__OPERAND_SEGREG:
- break;
- case YASM_INSN__OPERAND_MEMORY:
- yasm_ea_delete(op->data.ea);
- break;
- case YASM_INSN__OPERAND_IMM:
- yasm_expr_delete(op->data.val);
- break;
- }
- break;
- case OPA_EA:
- switch (op->type) {
- case YASM_INSN__OPERAND_REG:
- d.ea =
- yasm_x86__ea_new_reg(op->data.reg, &d.rex,
- yasm_x86_LTX_mode_bits);
- break;
- case YASM_INSN__OPERAND_SEGREG:
- yasm_internal_error(
- N_("invalid operand conversion"));
- case YASM_INSN__OPERAND_MEMORY:
- d.ea = op->data.ea;
- if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
- /* Special-case for MOV MemOffs instruction */
- yasm_x86__ea_set_disponly(d.ea);
- break;
- case YASM_INSN__OPERAND_IMM:
- d.ea = yasm_x86__ea_new_imm(op->data.val,
- size_lookup[(info->operands[i] &
- OPS_MASK)>>OPS_SHIFT]);
- break;
- }
- break;
- case OPA_Imm:
- if (op->type == YASM_INSN__OPERAND_IMM) {
- d.imm = op->data.val;
- d.im_len = size_lookup[(info->operands[i] &
- OPS_MASK)>>OPS_SHIFT];
- } else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- case OPA_SImm:
- if (op->type == YASM_INSN__OPERAND_IMM) {
- d.imm = op->data.val;
- d.im_len = size_lookup[(info->operands[i] &
- OPS_MASK)>>OPS_SHIFT];
- d.im_sign = 1;
- } else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- case OPA_Spare:
- if (op->type == YASM_INSN__OPERAND_SEGREG)
- d.spare = (unsigned char)(op->data.reg&7);
- else if (op->type == YASM_INSN__OPERAND_REG) {
- if (yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
- op->data.reg, yasm_x86_LTX_mode_bits,
- X86_REX_R)) {
- yasm__error(lindex,
- N_("invalid combination of opcode and operands"));
- return NULL;
- }
- } else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- case OPA_Op0Add:
- if (op->type == YASM_INSN__OPERAND_REG) {
- unsigned char opadd;
- if (yasm_x86__set_rex_from_reg(&d.rex, &opadd,
- op->data.reg, yasm_x86_LTX_mode_bits,
- X86_REX_B)) {
- yasm__error(lindex,
- N_("invalid combination of opcode and operands"));
- return NULL;
- }
- d.op[0] += opadd;
- } else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- case OPA_Op1Add:
- /* Op1Add is only used for FPU, so no need to do REX */
- if (op->type == YASM_INSN__OPERAND_REG)
- d.op[1] += (unsigned char)(op->data.reg&7);
- else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- case OPA_SpareEA:
- if (op->type == YASM_INSN__OPERAND_REG) {
- d.ea = yasm_x86__ea_new_reg(op->data.reg, &d.rex,
- yasm_x86_LTX_mode_bits);
- if (!d.ea ||
- yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
- op->data.reg, yasm_x86_LTX_mode_bits,
- X86_REX_R)) {
- yasm__error(lindex,
- N_("invalid combination of opcode and operands"));
- if (d.ea)
- yasm_xfree(d.ea);
- return NULL;
- }
- } else
- yasm_internal_error(N_("invalid operand conversion"));
- break;
- default:
- yasm_internal_error(N_("unknown operand action"));
- }
-
- switch (info->operands[i] & OPAP_MASK) {
- case OPAP_None:
- break;
- case OPAP_ShiftOp:
- d.shift_op = 1;
- break;
- case OPAP_SImm8Avail:
- d.signext_imm8_op = 1;
- break;
- default:
- yasm_internal_error(
- N_("unknown operand postponed action"));
- }
- }
- }
-
- /* Create the bytecode and return it */
- return yasm_x86__bc_new_insn(&d);
-}
-
-
-#define YYCTYPE char
-#define YYCURSOR id
-#define YYLIMIT id
-#define YYMARKER marker
-#define YYFILL(n)
-
-/*!re2c
- any = [\000-\377];
- A = [aA];
- B = [bB];
- C = [cC];
- D = [dD];
- E = [eE];
- F = [fF];
- G = [gG];
- H = [hH];
- I = [iI];
- J = [jJ];
- K = [kK];
- L = [lL];
- M = [mM];
- N = [nN];
- O = [oO];
- P = [pP];
- Q = [qQ];
- R = [rR];
- S = [sS];
- T = [tT];
- U = [uU];
- V = [vV];
- W = [wW];
- X = [xX];
- Y = [yY];
- Z = [zZ];
-*/
-
-void
-yasm_x86__switch_cpu(const char *id, unsigned long lindex)
-{
- /*const char *marker;*/
-
- /*!re2c
- /* The standard CPU names /set/ cpu_enabled. */
- "8086" {
- cpu_enabled = CPU_Priv;
- return;
- }
- ("80" | I)? "186" {
- cpu_enabled = CPU_186|CPU_Priv;
- return;
- }
- ("80" | I)? "286" {
- cpu_enabled = CPU_186|CPU_286|CPU_Priv;
- return;
- }
- ("80" | I)? "386" {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- ("80" | I)? "486" {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_FPU|CPU_SMM|
- CPU_Prot|CPU_Priv;
- return;
- }
- (I? "586") | (P E N T I U M) | (P "5") {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_FPU|
- CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- (I? "686") | (P "6") | (P P R O) | (P E N T I U M P R O) {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_FPU|CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- (P "2") | (P E N T I U M "-"? ("2" | (I I))) {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_FPU|CPU_MMX|CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- (P "3") | (P E N T I U M "-"? ("3" | (I I I))) | (K A T M A I) {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_P3|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SMM|CPU_Prot|
- CPU_Priv;
- return;
- }
- (P "4") | (P E N T I U M "-"? ("4" | (I V))) | (W I L L I A M E T T E) {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_P3|CPU_P4|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|
- CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- (I A "-"? "64") | (I T A N I U M) {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_P3|CPU_P4|CPU_IA64|CPU_FPU|CPU_MMX|CPU_SSE|
- CPU_SSE2|CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- K "6" {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_K6|CPU_FPU|CPU_MMX|CPU_3DNow|CPU_SMM|CPU_Prot|
- CPU_Priv;
- return;
- }
- (A T H L O N) | (K "7") {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_K6|CPU_Athlon|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|
- CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
- ((S L E D G E)? (H A M M E R)) | (O P T E R O N) |
- (A T H L O N "-"? "64") {
- cpu_enabled = CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|
- CPU_K6|CPU_Athlon|CPU_Hammer|CPU_FPU|CPU_MMX|CPU_SSE|
- CPU_3DNow|CPU_SMM|CPU_Prot|CPU_Priv;
- return;
- }
-
- /* Features have "no" versions to disable them, and only set/reset the
- * specific feature being changed. All other bits are left alone.
- */
- F P U { cpu_enabled |= CPU_FPU; return; }
- N O F P U { cpu_enabled &= ~CPU_FPU; return; }
- M M X { cpu_enabled |= CPU_MMX; return; }
- N O M M X { cpu_enabled &= ~CPU_MMX; return; }
- S S E { cpu_enabled |= CPU_SSE; return; }
- N O S S E { cpu_enabled &= ~CPU_SSE; return; }
- S S E "2" { cpu_enabled |= CPU_SSE2; return; }
- N O S S E "2" { cpu_enabled &= ~CPU_SSE2; return; }
- "3" D N O W { cpu_enabled |= CPU_3DNow; return; }
- N O "3" D N O W { cpu_enabled &= ~CPU_3DNow; return; }
- C Y R I X { cpu_enabled |= CPU_Cyrix; return; }
- N O C Y R I X { cpu_enabled &= ~CPU_Cyrix; return; }
- A M D { cpu_enabled |= CPU_AMD; return; }
- N O A M D { cpu_enabled &= ~CPU_AMD; return; }
- S M M { cpu_enabled |= CPU_SMM; return; }
- N O S M M { cpu_enabled &= ~CPU_SMM; return; }
- P R O T { cpu_enabled |= CPU_Prot; return; }
- N O P R O T { cpu_enabled &= ~CPU_Prot; return; }
- U N D O C { cpu_enabled |= CPU_Undoc; return; }
- N O U N D O C { cpu_enabled &= ~CPU_Undoc; return; }
- O B S { cpu_enabled |= CPU_Obs; return; }
- N O O B S { cpu_enabled &= ~CPU_Obs; return; }
- P R I V { cpu_enabled |= CPU_Priv; return; }
- N O P R I V { cpu_enabled &= ~CPU_Priv; return; }
-
- /* catchalls */
- [\001-\377]+ {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("unrecognized CPU identifier `%s'"), id);
- return;
- }
- [\000] {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("unrecognized CPU identifier `%s'"), id);
- return;
- }
- */
-}
-
-yasm_arch_check_id_retval
-yasm_x86__check_identifier(unsigned long data[4], const char *id,
- unsigned long lindex)
-{
- const char *oid = id;
- /*const char *marker;*/
- /*!re2c
- /* target modifiers */
- N E A R {
- data[0] = X86_NEAR;
- return YASM_ARCH_CHECK_ID_TARGETMOD;
- }
- S H O R T {
- data[0] = X86_SHORT;
- return YASM_ARCH_CHECK_ID_TARGETMOD;
- }
- F A R {
- data[0] = X86_FAR;
- return YASM_ARCH_CHECK_ID_TARGETMOD;
- }
- T O {
- data[0] = X86_TO;
- return YASM_ARCH_CHECK_ID_TARGETMOD;
- }
-
- /* operand size overrides */
- O "16" {
- data[0] = X86_OPERSIZE;
- data[1] = 16;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- O "32" {
- data[0] = X86_OPERSIZE;
- data[1] = 32;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- O "64" {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a prefix in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_OPERSIZE;
- data[1] = 64;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- /* address size overrides */
- A "16" {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex,
- N_("Cannot override address size to 16 bits in 64-bit mode"));
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_ADDRSIZE;
- data[1] = 16;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- A "32" {
- data[0] = X86_ADDRSIZE;
- data[1] = 32;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- A "64" {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a prefix in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_ADDRSIZE;
- data[1] = 64;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
-
- /* instruction prefixes */
- L O C K {
- data[0] = X86_LOCKREP;
- data[1] = 0xF0;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- R E P N E {
- data[0] = X86_LOCKREP;
- data[1] = 0xF2;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- R E P N Z {
- data[0] = X86_LOCKREP;
- data[1] = 0xF2;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- R E P {
- data[0] = X86_LOCKREP;
- data[1] = 0xF3;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- R E P E {
- data[0] = X86_LOCKREP;
- data[1] = 0xF4;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
- R E P Z {
- data[0] = X86_LOCKREP;
- data[1] = 0xF4;
- return YASM_ARCH_CHECK_ID_PREFIX;
- }
-
- /* control, debug, and test registers */
- C R [02-48] {
- if (yasm_x86_LTX_mode_bits != 64 && oid[2] == '8') {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_CRREG | (oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- D R [0-7] {
- data[0] = X86_DRREG | (oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- T R [0-7] {
- data[0] = X86_TRREG | (oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- /* floating point, MMX, and SSE/SSE2 registers */
- S T [0-7] {
- data[0] = X86_FPUREG | (oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- M M [0-7] {
- data[0] = X86_MMXREG | (oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- X M M [0-9] {
- if (yasm_x86_LTX_mode_bits != 64 &&
- (oid[3] == '8' || oid[3] == '9')) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_XMMREG | (oid[3]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- X M M "1" [0-5] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | (10+oid[4]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- /* integer registers */
- R A X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 0;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R C X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 1;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R D X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 2;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R B X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 3;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R S P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 4;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R B P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 5;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R S I {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 6;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R D I {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | 7;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R [8-9] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | (oid[1]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- R "1" [0-5] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG64 | (10+oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- E A X { data[0] = X86_REG32 | 0; return YASM_ARCH_CHECK_ID_REG; }
- E C X { data[0] = X86_REG32 | 1; return YASM_ARCH_CHECK_ID_REG; }
- E D X { data[0] = X86_REG32 | 2; return YASM_ARCH_CHECK_ID_REG; }
- E B X { data[0] = X86_REG32 | 3; return YASM_ARCH_CHECK_ID_REG; }
- E S P { data[0] = X86_REG32 | 4; return YASM_ARCH_CHECK_ID_REG; }
- E B P { data[0] = X86_REG32 | 5; return YASM_ARCH_CHECK_ID_REG; }
- E S I { data[0] = X86_REG32 | 6; return YASM_ARCH_CHECK_ID_REG; }
- E D I { data[0] = X86_REG32 | 7; return YASM_ARCH_CHECK_ID_REG; }
- R [8-9] D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG32 | (oid[1]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- R "1" [0-5] D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG32 | (10+oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- A X { data[0] = X86_REG16 | 0; return YASM_ARCH_CHECK_ID_REG; }
- C X { data[0] = X86_REG16 | 1; return YASM_ARCH_CHECK_ID_REG; }
- D X { data[0] = X86_REG16 | 2; return YASM_ARCH_CHECK_ID_REG; }
- B X { data[0] = X86_REG16 | 3; return YASM_ARCH_CHECK_ID_REG; }
- S P { data[0] = X86_REG16 | 4; return YASM_ARCH_CHECK_ID_REG; }
- B P { data[0] = X86_REG16 | 5; return YASM_ARCH_CHECK_ID_REG; }
- S I { data[0] = X86_REG16 | 6; return YASM_ARCH_CHECK_ID_REG; }
- D I { data[0] = X86_REG16 | 7; return YASM_ARCH_CHECK_ID_REG; }
- R [8-9] W {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG16 | (oid[1]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- R "1" [0-5] W {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG16 | (10+oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- A L { data[0] = X86_REG8 | 0; return YASM_ARCH_CHECK_ID_REG; }
- C L { data[0] = X86_REG8 | 1; return YASM_ARCH_CHECK_ID_REG; }
- D L { data[0] = X86_REG8 | 2; return YASM_ARCH_CHECK_ID_REG; }
- B L { data[0] = X86_REG8 | 3; return YASM_ARCH_CHECK_ID_REG; }
- A H { data[0] = X86_REG8 | 4; return YASM_ARCH_CHECK_ID_REG; }
- C H { data[0] = X86_REG8 | 5; return YASM_ARCH_CHECK_ID_REG; }
- D H { data[0] = X86_REG8 | 6; return YASM_ARCH_CHECK_ID_REG; }
- B H { data[0] = X86_REG8 | 7; return YASM_ARCH_CHECK_ID_REG; }
- S P L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8X | 4;
- return YASM_ARCH_CHECK_ID_REG;
- }
- B P L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8X | 5;
- return YASM_ARCH_CHECK_ID_REG;
- }
- S I L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8X | 6;
- return YASM_ARCH_CHECK_ID_REG;
- }
- D I L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8X | 7;
- return YASM_ARCH_CHECK_ID_REG;
- }
- R [8-9] B {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8 | (oid[1]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
- R "1" [0-5] B {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_REG8 | (10+oid[2]-'0');
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- /* segment registers */
- E S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' segment register ignored in 64-bit mode"), oid);
- data[0] = 0x2600;
- return YASM_ARCH_CHECK_ID_SEGREG;
- }
- C S { data[0] = 0x2e01; return YASM_ARCH_CHECK_ID_SEGREG; }
- S S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' segment register ignored in 64-bit mode"), oid);
- data[0] = 0x3602;
- return YASM_ARCH_CHECK_ID_SEGREG;
- }
- D S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' segment register ignored in 64-bit mode"), oid);
- data[0] = 0x3e03;
- return YASM_ARCH_CHECK_ID_SEGREG;
- }
- F S { data[0] = 0x6404; return YASM_ARCH_CHECK_ID_SEGREG; }
- G S { data[0] = 0x6505; return YASM_ARCH_CHECK_ID_SEGREG; }
-
- /* RIP for 64-bit mode IP-relative offsets */
- R I P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is a register in 64-bit mode"), oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- data[0] = X86_RIP;
- return YASM_ARCH_CHECK_ID_REG;
- }
-
- /* instructions */
-
- /* Move */
- M O V { RET_INSN(mov, 0, CPU_Any); }
- /* Move with sign/zero extend */
- M O V S X { RET_INSN(movszx, 0xBE, CPU_386); }
- M O V S X D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(movsxd, 0, CPU_Hammer|CPU_64);
- }
- M O V Z X { RET_INSN(movszx, 0xB6, CPU_386); }
- /* Push instructions */
- P U S H { RET_INSN(push, 0, CPU_Any); }
- P U S H A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x0060, CPU_186);
- }
- P U S H A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x2060, CPU_386);
- }
- P U S H A W {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x1060, CPU_186);
- }
- /* Pop instructions */
- P O P { RET_INSN(pop, 0, CPU_Any); }
- P O P A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x0061, CPU_186);
- }
- P O P A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x2061, CPU_386);
- }
- P O P A W {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x1061, CPU_186);
- }
- /* Exchange */
- X C H G { RET_INSN(xchg, 0, CPU_Any); }
- /* In/out from ports */
- I N { RET_INSN(in, 0, CPU_Any); }
- O U T { RET_INSN(out, 0, CPU_Any); }
- /* Load effective address */
- L E A { RET_INSN(lea, 0, CPU_Any); }
- /* Load segment registers from memory */
- L D S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(ldes, 0xC5, CPU_Any);
- }
- L E S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(ldes, 0xC4, CPU_Any);
- }
- L F S { RET_INSN(lfgss, 0xB4, CPU_386); }
- L G S { RET_INSN(lfgss, 0xB5, CPU_386); }
- L S S { RET_INSN(lfgss, 0xB6, CPU_386); }
- /* Flags register instructions */
- C L C { RET_INSN(onebyte, 0x00F8, CPU_Any); }
- C L D { RET_INSN(onebyte, 0x00FC, CPU_Any); }
- C L I { RET_INSN(onebyte, 0x00FA, CPU_Any); }
- C L T S { RET_INSN(twobyte, 0x0F06, CPU_286|CPU_Priv); }
- C M C { RET_INSN(onebyte, 0x00F5, CPU_Any); }
- L A H F {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x009F, CPU_Any);
- }
- S A H F {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x009E, CPU_Any);
- }
- P U S H F { RET_INSN(onebyte, 0x009C, CPU_Any); }
- P U S H F D { RET_INSN(onebyte, 0x209C, CPU_386); }
- P U S H F W { RET_INSN(onebyte, 0x109C, CPU_Any); }
- P U S H F Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x409C, CPU_Hammer|CPU_64);
- }
- P O P F { RET_INSN(onebyte, 0x009D, CPU_Any); }
- P O P F D { RET_INSN(onebyte, 0x209D, CPU_386); }
- P O P F W { RET_INSN(onebyte, 0x109D, CPU_Any); }
- P O P F Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x409D, CPU_Hammer|CPU_64);
- }
- S T C { RET_INSN(onebyte, 0x00F9, CPU_Any); }
- S T D { RET_INSN(onebyte, 0x00FD, CPU_Any); }
- S T I { RET_INSN(onebyte, 0x00FB, CPU_Any); }
- /* Arithmetic */
- A D D { RET_INSN(arith, 0x0000, CPU_Any); }
- I N C { RET_INSN(incdec, 0x0040, CPU_Any); }
- S U B { RET_INSN(arith, 0x0528, CPU_Any); }
- D E C { RET_INSN(incdec, 0x0148, CPU_Any); }
- S B B { RET_INSN(arith, 0x0318, CPU_Any); }
- C M P { RET_INSN(arith, 0x0738, CPU_Any); }
- T E S T { RET_INSN(test, 0, CPU_Any); }
- A N D { RET_INSN(arith, 0x0420, CPU_Any); }
- O R { RET_INSN(arith, 0x0108, CPU_Any); }
- X O R { RET_INSN(arith, 0x0630, CPU_Any); }
- A D C { RET_INSN(arith, 0x0210, CPU_Any); }
- N E G { RET_INSN(f6, 0x03, CPU_Any); }
- N O T { RET_INSN(f6, 0x02, CPU_Any); }
- A A A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x0037, CPU_Any);
- }
- A A S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x003F, CPU_Any);
- }
- D A A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x0027, CPU_Any);
- }
- D A S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x002F, CPU_Any);
- }
- A A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(aadm, 0x01, CPU_Any);
- }
- A A M {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(aadm, 0x00, CPU_Any);
- }
- /* Conversion instructions */
- C B W { RET_INSN(onebyte, 0x1098, CPU_Any); }
- C W D E { RET_INSN(onebyte, 0x2098, CPU_386); }
- C D Q E {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x4098, CPU_Hammer|CPU_64);
- }
- C W D { RET_INSN(onebyte, 0x1099, CPU_Any); }
- C D Q { RET_INSN(onebyte, 0x2099, CPU_386); }
- C D O {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x4099, CPU_Hammer|CPU_64);
- }
- /* Multiplication and division */
- M U L { RET_INSN(f6, 0x04, CPU_Any); }
- I M U L { RET_INSN(imul, 0, CPU_Any); }
- D I V { RET_INSN(f6, 0x06, CPU_Any); }
- I D I V { RET_INSN(f6, 0x07, CPU_Any); }
- /* Shifts */
- R O L { RET_INSN(shift, 0x00, CPU_Any); }
- R O R { RET_INSN(shift, 0x01, CPU_Any); }
- R C L { RET_INSN(shift, 0x02, CPU_Any); }
- R C R { RET_INSN(shift, 0x03, CPU_Any); }
- S A L { RET_INSN(shift, 0x04, CPU_Any); }
- S H L { RET_INSN(shift, 0x04, CPU_Any); }
- S H R { RET_INSN(shift, 0x05, CPU_Any); }
- S A R { RET_INSN(shift, 0x07, CPU_Any); }
- S H L D { RET_INSN(shlrd, 0xA4, CPU_386); }
- S H R D { RET_INSN(shlrd, 0xAC, CPU_386); }
- /* Control transfer instructions (unconditional) */
- C A L L { RET_INSN(call, 0, CPU_Any); }
- J M P { RET_INSN(jmp, 0, CPU_Any); }
- R E T { RET_INSN(retnf, 0xC2, CPU_Any); }
- R E T N { RET_INSN(retnf, 0xC2, CPU_Any); }
- R E T F { RET_INSN(retnf, 0xCA, CPU_Any); }
- E N T E R { RET_INSN(enter, 0, CPU_186); }
- L E A V E { RET_INSN(onebyte, 0x00C9, CPU_186); }
- /* Conditional jumps */
- J O { RET_INSN(jcc, 0x00, CPU_Any); }
- J N O { RET_INSN(jcc, 0x01, CPU_Any); }
- J B { RET_INSN(jcc, 0x02, CPU_Any); }
- J C { RET_INSN(jcc, 0x02, CPU_Any); }
- J N A E { RET_INSN(jcc, 0x02, CPU_Any); }
- J N B { RET_INSN(jcc, 0x03, CPU_Any); }
- J N C { RET_INSN(jcc, 0x03, CPU_Any); }
- J A E { RET_INSN(jcc, 0x03, CPU_Any); }
- J E { RET_INSN(jcc, 0x04, CPU_Any); }
- J Z { RET_INSN(jcc, 0x04, CPU_Any); }
- J N E { RET_INSN(jcc, 0x05, CPU_Any); }
- J N Z { RET_INSN(jcc, 0x05, CPU_Any); }
- J B E { RET_INSN(jcc, 0x06, CPU_Any); }
- J N A { RET_INSN(jcc, 0x06, CPU_Any); }
- J N B E { RET_INSN(jcc, 0x07, CPU_Any); }
- J A { RET_INSN(jcc, 0x07, CPU_Any); }
- J S { RET_INSN(jcc, 0x08, CPU_Any); }
- J N S { RET_INSN(jcc, 0x09, CPU_Any); }
- J P { RET_INSN(jcc, 0x0A, CPU_Any); }
- J P E { RET_INSN(jcc, 0x0A, CPU_Any); }
- J N P { RET_INSN(jcc, 0x0B, CPU_Any); }
- J P O { RET_INSN(jcc, 0x0B, CPU_Any); }
- J L { RET_INSN(jcc, 0x0C, CPU_Any); }
- J N G E { RET_INSN(jcc, 0x0C, CPU_Any); }
- J N L { RET_INSN(jcc, 0x0D, CPU_Any); }
- J G E { RET_INSN(jcc, 0x0D, CPU_Any); }
- J L E { RET_INSN(jcc, 0x0E, CPU_Any); }
- J N G { RET_INSN(jcc, 0x0E, CPU_Any); }
- J N L E { RET_INSN(jcc, 0x0F, CPU_Any); }
- J G { RET_INSN(jcc, 0x0F, CPU_Any); }
- J C X Z { RET_INSN(jcxz, 16, CPU_Any); }
- J E C X Z { RET_INSN(jcxz, 32, CPU_386); }
- J R C X Z {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(jcxz, 64, CPU_Hammer|CPU_64);
- }
- /* Loop instructions */
- L O O P { RET_INSN(loop, 0x02, CPU_Any); }
- L O O P Z { RET_INSN(loop, 0x01, CPU_Any); }
- L O O P E { RET_INSN(loop, 0x01, CPU_Any); }
- L O O P N Z { RET_INSN(loop, 0x00, CPU_Any); }
- L O O P N E { RET_INSN(loop, 0x00, CPU_Any); }
- /* Set byte on flag instructions */
- S E T O { RET_INSN(setcc, 0x00, CPU_386); }
- S E T N O { RET_INSN(setcc, 0x01, CPU_386); }
- S E T B { RET_INSN(setcc, 0x02, CPU_386); }
- S E T C { RET_INSN(setcc, 0x02, CPU_386); }
- S E T N A E { RET_INSN(setcc, 0x02, CPU_386); }
- S E T N B { RET_INSN(setcc, 0x03, CPU_386); }
- S E T N C { RET_INSN(setcc, 0x03, CPU_386); }
- S E T A E { RET_INSN(setcc, 0x03, CPU_386); }
- S E T E { RET_INSN(setcc, 0x04, CPU_386); }
- S E T Z { RET_INSN(setcc, 0x04, CPU_386); }
- S E T N E { RET_INSN(setcc, 0x05, CPU_386); }
- S E T N Z { RET_INSN(setcc, 0x05, CPU_386); }
- S E T B E { RET_INSN(setcc, 0x06, CPU_386); }
- S E T N A { RET_INSN(setcc, 0x06, CPU_386); }
- S E T N B E { RET_INSN(setcc, 0x07, CPU_386); }
- S E T A { RET_INSN(setcc, 0x07, CPU_386); }
- S E T S { RET_INSN(setcc, 0x08, CPU_386); }
- S E T N S { RET_INSN(setcc, 0x09, CPU_386); }
- S E T P { RET_INSN(setcc, 0x0A, CPU_386); }
- S E T P E { RET_INSN(setcc, 0x0A, CPU_386); }
- S E T N P { RET_INSN(setcc, 0x0B, CPU_386); }
- S E T P O { RET_INSN(setcc, 0x0B, CPU_386); }
- S E T L { RET_INSN(setcc, 0x0C, CPU_386); }
- S E T N G E { RET_INSN(setcc, 0x0C, CPU_386); }
- S E T N L { RET_INSN(setcc, 0x0D, CPU_386); }
- S E T G E { RET_INSN(setcc, 0x0D, CPU_386); }
- S E T L E { RET_INSN(setcc, 0x0E, CPU_386); }
- S E T N G { RET_INSN(setcc, 0x0E, CPU_386); }
- S E T N L E { RET_INSN(setcc, 0x0F, CPU_386); }
- S E T G { RET_INSN(setcc, 0x0F, CPU_386); }
- /* String instructions. */
- C M P S B { RET_INSN(onebyte, 0x00A6, CPU_Any); }
- C M P S W { RET_INSN(onebyte, 0x10A7, CPU_Any); }
- C M P S D { RET_INSN(cmpsd, 0, CPU_Any); }
- C M P S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40A7, CPU_Hammer|CPU_64);
- }
- I N S B { RET_INSN(onebyte, 0x006C, CPU_Any); }
- I N S W { RET_INSN(onebyte, 0x106D, CPU_Any); }
- I N S D { RET_INSN(onebyte, 0x206D, CPU_386); }
- O U T S B { RET_INSN(onebyte, 0x006E, CPU_Any); }
- O U T S W { RET_INSN(onebyte, 0x106F, CPU_Any); }
- O U T S D { RET_INSN(onebyte, 0x206F, CPU_386); }
- L O D S B { RET_INSN(onebyte, 0x00AC, CPU_Any); }
- L O D S W { RET_INSN(onebyte, 0x10AD, CPU_Any); }
- L O D S D { RET_INSN(onebyte, 0x20AD, CPU_386); }
- L O D S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40AD, CPU_Hammer|CPU_64);
- }
- M O V S B { RET_INSN(onebyte, 0x00A4, CPU_Any); }
- M O V S W { RET_INSN(onebyte, 0x10A5, CPU_Any); }
- M O V S D { RET_INSN(movsd, 0, CPU_Any); }
- M O V S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40A5, CPU_Any);
- }
- S C A S B { RET_INSN(onebyte, 0x00AE, CPU_Any); }
- S C A S W { RET_INSN(onebyte, 0x10AF, CPU_Any); }
- S C A S D { RET_INSN(onebyte, 0x20AF, CPU_386); }
- S C A S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40AF, CPU_Hammer|CPU_64);
- }
- S T O S B { RET_INSN(onebyte, 0x00AA, CPU_Any); }
- S T O S W { RET_INSN(onebyte, 0x10AB, CPU_Any); }
- S T O S D { RET_INSN(onebyte, 0x20AB, CPU_386); }
- S T O S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40AB, CPU_Hammer|CPU_64);
- }
- X L A T B? { RET_INSN(onebyte, 0x00D7, CPU_Any); }
- /* Bit manipulation */
- B S F { RET_INSN(bsfr, 0xBC, CPU_386); }
- B S R { RET_INSN(bsfr, 0xBD, CPU_386); }
- B T { RET_INSN(bittest, 0x04A3, CPU_386); }
- B T C { RET_INSN(bittest, 0x07BB, CPU_386); }
- B T R { RET_INSN(bittest, 0x06B3, CPU_386); }
- B T S { RET_INSN(bittest, 0x05AB, CPU_386); }
- /* Interrupts and operating system instructions */
- I N T { RET_INSN(int, 0, CPU_Any); }
- I N T "3" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
- I N T "03" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
- I N T O {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x00CE, CPU_Any);
- }
- I R E T { RET_INSN(onebyte, 0x00CF, CPU_Any); }
- I R E T W { RET_INSN(onebyte, 0x10CF, CPU_Any); }
- I R E T D { RET_INSN(onebyte, 0x20CF, CPU_386); }
- I R E T Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(onebyte, 0x40CF, CPU_Hammer|CPU_64);
- }
- R S M { RET_INSN(twobyte, 0x0FAA, CPU_586|CPU_SMM); }
- B O U N D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(bound, 0, CPU_186);
- }
- H L T { RET_INSN(onebyte, 0x00F4, CPU_Priv); }
- N O P { RET_INSN(onebyte, 0x0090, CPU_Any); }
- /* Protection control */
- A R P L {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(arpl, 0, CPU_286|CPU_Prot);
- }
- L A R { RET_INSN(bsfr, 0x02, CPU_286|CPU_Prot); }
- L G D T { RET_INSN(twobytemem, 0x020F01, CPU_286|CPU_Priv); }
- L I D T { RET_INSN(twobytemem, 0x030F01, CPU_286|CPU_Priv); }
- L L D T { RET_INSN(prot286, 0x0200, CPU_286|CPU_Prot|CPU_Priv); }
- L M S W { RET_INSN(prot286, 0x0601, CPU_286|CPU_Priv); }
- L S L { RET_INSN(bsfr, 0x03, CPU_286|CPU_Prot); }
- L T R { RET_INSN(prot286, 0x0300, CPU_286|CPU_Prot|CPU_Priv); }
- S G D T { RET_INSN(twobytemem, 0x000F01, CPU_286|CPU_Priv); }
- S I D T { RET_INSN(twobytemem, 0x010F01, CPU_286|CPU_Priv); }
- S L D T { RET_INSN(sldtmsw, 0x0000, CPU_286); }
- S M S W { RET_INSN(sldtmsw, 0x0401, CPU_286); }
- S T R { RET_INSN(str, 0, CPU_286|CPU_Prot); }
- V E R R { RET_INSN(prot286, 0x0400, CPU_286|CPU_Prot); }
- V E R W { RET_INSN(prot286, 0x0500, CPU_286|CPU_Prot); }
- /* Floating point instructions */
- F L D { RET_INSN(fldstp, 0x0500C0, CPU_FPU); }
- F I L D { RET_INSN(fildstp, 0x0500, CPU_FPU); }
- F B L D { RET_INSN(fbldstp, 0x04, CPU_FPU); }
- F S T { RET_INSN(fst, 0, CPU_FPU); }
- F I S T { RET_INSN(fiarith, 0x02DB, CPU_FPU); }
- F S T P { RET_INSN(fldstp, 0x0703D8, CPU_FPU); }
- F I S T P { RET_INSN(fildstp, 0x0703, CPU_FPU); }
- F B S T P { RET_INSN(fbldstp, 0x06, CPU_FPU); }
- F X C H { RET_INSN(fxch, 0, CPU_FPU); }
- F C O M { RET_INSN(fcom, 0x02D0, CPU_FPU); }
- F I C O M { RET_INSN(fiarith, 0x02DA, CPU_FPU); }
- F C O M P { RET_INSN(fcom, 0x03D8, CPU_FPU); }
- F I C O M P { RET_INSN(fiarith, 0x03DA, CPU_FPU); }
- F C O M P P { RET_INSN(twobyte, 0xDED9, CPU_FPU); }
- F U C O M { RET_INSN(fcom2, 0xDDE0, CPU_286|CPU_FPU); }
- F U C O M P { RET_INSN(fcom2, 0xDDE8, CPU_286|CPU_FPU); }
- F U C O M P P { RET_INSN(twobyte, 0xDAE9, CPU_286|CPU_FPU); }
- F T S T { RET_INSN(twobyte, 0xD9E4, CPU_FPU); }
- F X A M { RET_INSN(twobyte, 0xD9E5, CPU_FPU); }
- F L D "1" { RET_INSN(twobyte, 0xD9E8, CPU_FPU); }
- F L D L "2" T { RET_INSN(twobyte, 0xD9E9, CPU_FPU); }
- F L D L "2" E { RET_INSN(twobyte, 0xD9EA, CPU_FPU); }
- F L D P I { RET_INSN(twobyte, 0xD9EB, CPU_FPU); }
- F L D L G "2" { RET_INSN(twobyte, 0xD9EC, CPU_FPU); }
- F L D L N "2" { RET_INSN(twobyte, 0xD9ED, CPU_FPU); }
- F L D Z { RET_INSN(twobyte, 0xD9EE, CPU_FPU); }
- F A D D { RET_INSN(farith, 0x00C0C0, CPU_FPU); }
- F A D D P { RET_INSN(farithp, 0xC0, CPU_FPU); }
- F I A D D { RET_INSN(fiarith, 0x00DA, CPU_FPU); }
- F S U B { RET_INSN(farith, 0x04E0E8, CPU_FPU); }
- F I S U B { RET_INSN(fiarith, 0x04DA, CPU_FPU); }
- F S U B P { RET_INSN(farithp, 0xE8, CPU_FPU); }
- F S U B R { RET_INSN(farith, 0x05E8E0, CPU_FPU); }
- F I S U B R { RET_INSN(fiarith, 0x05DA, CPU_FPU); }
- F S U B R P { RET_INSN(farithp, 0xE0, CPU_FPU); }
- F M U L { RET_INSN(farith, 0x01C8C8, CPU_FPU); }
- F I M U L { RET_INSN(fiarith, 0x01DA, CPU_FPU); }
- F M U L P { RET_INSN(farithp, 0xC8, CPU_FPU); }
- F D I V { RET_INSN(farith, 0x06F0F8, CPU_FPU); }
- F I D I V { RET_INSN(fiarith, 0x06DA, CPU_FPU); }
- F D I V P { RET_INSN(farithp, 0xF8, CPU_FPU); }
- F D I V R { RET_INSN(farith, 0x07F8F0, CPU_FPU); }
- F I D I V R { RET_INSN(fiarith, 0x07DA, CPU_FPU); }
- F D I V R P { RET_INSN(farithp, 0xF0, CPU_FPU); }
- F "2" X M "1" { RET_INSN(twobyte, 0xD9F0, CPU_FPU); }
- F Y L "2" X { RET_INSN(twobyte, 0xD9F1, CPU_FPU); }
- F P T A N { RET_INSN(twobyte, 0xD9F2, CPU_FPU); }
- F P A T A N { RET_INSN(twobyte, 0xD9F3, CPU_FPU); }
- F X T R A C T { RET_INSN(twobyte, 0xD9F4, CPU_FPU); }
- F P R E M "1" { RET_INSN(twobyte, 0xD9F5, CPU_286|CPU_FPU); }
- F D E C S T P { RET_INSN(twobyte, 0xD9F6, CPU_FPU); }
- F I N C S T P { RET_INSN(twobyte, 0xD9F7, CPU_FPU); }
- F P R E M { RET_INSN(twobyte, 0xD9F8, CPU_FPU); }
- F Y L "2" X P "1" { RET_INSN(twobyte, 0xD9F9, CPU_FPU); }
- F S Q R T { RET_INSN(twobyte, 0xD9FA, CPU_FPU); }
- F S I N C O S { RET_INSN(twobyte, 0xD9FB, CPU_286|CPU_FPU); }
- F R N D I N T { RET_INSN(twobyte, 0xD9FC, CPU_FPU); }
- F S C A L E { RET_INSN(twobyte, 0xD9FD, CPU_FPU); }
- F S I N { RET_INSN(twobyte, 0xD9FE, CPU_286|CPU_FPU); }
- F C O S { RET_INSN(twobyte, 0xD9FF, CPU_286|CPU_FPU); }
- F C H S { RET_INSN(twobyte, 0xD9E0, CPU_FPU); }
- F A B S { RET_INSN(twobyte, 0xD9E1, CPU_FPU); }
- F N I N I T { RET_INSN(twobyte, 0xDBE3, CPU_FPU); }
- F I N I T { RET_INSN(threebyte, 0x98DBE3, CPU_FPU); }
- F L D C W { RET_INSN(fldnstcw, 0x05, CPU_FPU); }
- F N S T C W { RET_INSN(fldnstcw, 0x07, CPU_FPU); }
- F S T C W { RET_INSN(fstcw, 0, CPU_FPU); }
- F N S T S W { RET_INSN(fnstsw, 0, CPU_FPU); }
- F S T S W { RET_INSN(fstsw, 0, CPU_FPU); }
- F N C L E X { RET_INSN(twobyte, 0xDBE2, CPU_FPU); }
- F C L E X { RET_INSN(threebyte, 0x98DBE2, CPU_FPU); }
- F N S T E N V { RET_INSN(onebytemem, 0x06D9, CPU_FPU); }
- F S T E N V { RET_INSN(twobytemem, 0x069BD9, CPU_FPU); }
- F L D E N V { RET_INSN(onebytemem, 0x04D9, CPU_FPU); }
- F N S A V E { RET_INSN(onebytemem, 0x06DD, CPU_FPU); }
- F S A V E { RET_INSN(twobytemem, 0x069BDD, CPU_FPU); }
- F R S T O R { RET_INSN(onebytemem, 0x04DD, CPU_FPU); }
- F F R E E { RET_INSN(ffree, 0xDD, CPU_FPU); }
- F F R E E P { RET_INSN(ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); }
- F N O P { RET_INSN(twobyte, 0xD9D0, CPU_FPU); }
- F W A I T { RET_INSN(onebyte, 0x009B, CPU_FPU); }
- /* Prefixes (should the others be here too? should wait be a prefix? */
- W A I T { RET_INSN(onebyte, 0x009B, CPU_Any); }
- /* 486 extensions */
- B S W A P { RET_INSN(bswap, 0, CPU_486); }
- X A D D { RET_INSN(cmpxchgxadd, 0xC0, CPU_486); }
- C M P X C H G { RET_INSN(cmpxchgxadd, 0xB0, CPU_486); }
- C M P X C H G "486" { RET_INSN(cmpxchgxadd, 0xA6, CPU_486|CPU_Undoc); }
- I N V D { RET_INSN(twobyte, 0x0F08, CPU_486|CPU_Priv); }
- W B I N V D { RET_INSN(twobyte, 0x0F09, CPU_486|CPU_Priv); }
- I N V L P G { RET_INSN(twobytemem, 0x070F01, CPU_486|CPU_Priv); }
- /* 586+ and late 486 extensions */
- C P U I D { RET_INSN(twobyte, 0x0FA2, CPU_486); }
- /* Pentium extensions */
- W R M S R { RET_INSN(twobyte, 0x0F30, CPU_586|CPU_Priv); }
- R D T S C { RET_INSN(twobyte, 0x0F31, CPU_586); }
- R D M S R { RET_INSN(twobyte, 0x0F32, CPU_586|CPU_Priv); }
- C M P X C H G "8" B { RET_INSN(cmpxchg8b, 0, CPU_586); }
- /* Pentium II/Pentium Pro extensions */
- S Y S E N T E R {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(twobyte, 0x0F34, CPU_686);
- }
- S Y S E X I T {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(twobyte, 0x0F35, CPU_686|CPU_Priv);
- }
- F X S A V E { RET_INSN(twobytemem, 0x000FAE, CPU_686|CPU_FPU); }
- F X R S T O R { RET_INSN(twobytemem, 0x010FAE, CPU_686|CPU_FPU); }
- R D P M C { RET_INSN(twobyte, 0x0F33, CPU_686); }
- U D "2" { RET_INSN(twobyte, 0x0F0B, CPU_286); }
- U D "1" { RET_INSN(twobyte, 0x0FB9, CPU_286|CPU_Undoc); }
- C M O V O { RET_INSN(cmovcc, 0x00, CPU_686); }
- C M O V N O { RET_INSN(cmovcc, 0x01, CPU_686); }
- C M O V B { RET_INSN(cmovcc, 0x02, CPU_686); }
- C M O V C { RET_INSN(cmovcc, 0x02, CPU_686); }
- C M O V N A E { RET_INSN(cmovcc, 0x02, CPU_686); }
- C M O V N B { RET_INSN(cmovcc, 0x03, CPU_686); }
- C M O V N C { RET_INSN(cmovcc, 0x03, CPU_686); }
- C M O V A E { RET_INSN(cmovcc, 0x03, CPU_686); }
- C M O V E { RET_INSN(cmovcc, 0x04, CPU_686); }
- C M O V Z { RET_INSN(cmovcc, 0x04, CPU_686); }
- C M O V N E { RET_INSN(cmovcc, 0x05, CPU_686); }
- C M O V N Z { RET_INSN(cmovcc, 0x05, CPU_686); }
- C M O V B E { RET_INSN(cmovcc, 0x06, CPU_686); }
- C M O V N A { RET_INSN(cmovcc, 0x06, CPU_686); }
- C M O V N B E { RET_INSN(cmovcc, 0x07, CPU_686); }
- C M O V A { RET_INSN(cmovcc, 0x07, CPU_686); }
- C M O V S { RET_INSN(cmovcc, 0x08, CPU_686); }
- C M O V N S { RET_INSN(cmovcc, 0x09, CPU_686); }
- C M O V P { RET_INSN(cmovcc, 0x0A, CPU_686); }
- C M O V P E { RET_INSN(cmovcc, 0x0A, CPU_686); }
- C M O V N P { RET_INSN(cmovcc, 0x0B, CPU_686); }
- C M O V P O { RET_INSN(cmovcc, 0x0B, CPU_686); }
- C M O V L { RET_INSN(cmovcc, 0x0C, CPU_686); }
- C M O V N G E { RET_INSN(cmovcc, 0x0C, CPU_686); }
- C M O V N L { RET_INSN(cmovcc, 0x0D, CPU_686); }
- C M O V G E { RET_INSN(cmovcc, 0x0D, CPU_686); }
- C M O V L E { RET_INSN(cmovcc, 0x0E, CPU_686); }
- C M O V N G { RET_INSN(cmovcc, 0x0E, CPU_686); }
- C M O V N L E { RET_INSN(cmovcc, 0x0F, CPU_686); }
- C M O V G { RET_INSN(cmovcc, 0x0F, CPU_686); }
- F C M O V B { RET_INSN(fcmovcc, 0xDAC0, CPU_686|CPU_FPU); }
- F C M O V E { RET_INSN(fcmovcc, 0xDAC8, CPU_686|CPU_FPU); }
- F C M O V B E { RET_INSN(fcmovcc, 0xDAD0, CPU_686|CPU_FPU); }
- F C M O V U { RET_INSN(fcmovcc, 0xDAD8, CPU_686|CPU_FPU); }
- F C M O V N B { RET_INSN(fcmovcc, 0xDBC0, CPU_686|CPU_FPU); }
- F C M O V N E { RET_INSN(fcmovcc, 0xDBC8, CPU_686|CPU_FPU); }
- F C M O V N B E { RET_INSN(fcmovcc, 0xDBD0, CPU_686|CPU_FPU); }
- F C M O V U { RET_INSN(fcmovcc, 0xDBD8, CPU_686|CPU_FPU); }
- F C O M I { RET_INSN(fcom2, 0xDBF0, CPU_686|CPU_FPU); }
- F U C O M I { RET_INSN(fcom2, 0xDBE8, CPU_686|CPU_FPU); }
- F C O M I P { RET_INSN(fcom2, 0xDFF0, CPU_686|CPU_FPU); }
- F U C O M I P { RET_INSN(fcom2, 0xDFE8, CPU_686|CPU_FPU); }
- /* Pentium4 extensions */
- M O V N T I { RET_INSN(movnti, 0, CPU_P4); }
- C L F L U S H { RET_INSN(clflush, 0, CPU_P3); }
- L F E N C E { RET_INSN(threebyte, 0x0FAEE8, CPU_P3); }
- M F E N C E { RET_INSN(threebyte, 0x0FAEF0, CPU_P3); }
- P A U S E { RET_INSN(twobyte, 0xF390, CPU_P4); }
- /* MMX/SSE2 instructions */
- E M M S { RET_INSN(twobyte, 0x0F77, CPU_MMX); }
- M O V D { RET_INSN(movd, 0, CPU_MMX); }
- M O V Q { RET_INSN(movq, 0, CPU_MMX); }
- P A C K S S D W { RET_INSN(mmxsse2, 0x6B, CPU_MMX); }
- P A C K S S W B { RET_INSN(mmxsse2, 0x63, CPU_MMX); }
- P A C K U S W B { RET_INSN(mmxsse2, 0x67, CPU_MMX); }
- P A D D B { RET_INSN(mmxsse2, 0xFC, CPU_MMX); }
- P A D D W { RET_INSN(mmxsse2, 0xFD, CPU_MMX); }
- P A D D D { RET_INSN(mmxsse2, 0xFE, CPU_MMX); }
- P A D D Q { RET_INSN(mmxsse2, 0xD4, CPU_MMX); }
- P A D D S B { RET_INSN(mmxsse2, 0xEC, CPU_MMX); }
- P A D D S W { RET_INSN(mmxsse2, 0xED, CPU_MMX); }
- P A D D U S B { RET_INSN(mmxsse2, 0xDC, CPU_MMX); }
- P A D D U S W { RET_INSN(mmxsse2, 0xDD, CPU_MMX); }
- P A N D { RET_INSN(mmxsse2, 0xDB, CPU_MMX); }
- P A N D N { RET_INSN(mmxsse2, 0xDF, CPU_MMX); }
- P A C M P E Q B { RET_INSN(mmxsse2, 0x74, CPU_MMX); }
- P A C M P E Q W { RET_INSN(mmxsse2, 0x75, CPU_MMX); }
- P A C M P E Q D { RET_INSN(mmxsse2, 0x76, CPU_MMX); }
- P A C M P G T B { RET_INSN(mmxsse2, 0x64, CPU_MMX); }
- P A C M P G T W { RET_INSN(mmxsse2, 0x65, CPU_MMX); }
- P A C M P G T D { RET_INSN(mmxsse2, 0x66, CPU_MMX); }
- P M A D D W D { RET_INSN(mmxsse2, 0xF5, CPU_MMX); }
- P M U L H W { RET_INSN(mmxsse2, 0xE5, CPU_MMX); }
- P M U L L W { RET_INSN(mmxsse2, 0xD5, CPU_MMX); }
- P O R { RET_INSN(mmxsse2, 0xEB, CPU_MMX); }
- P S L L W { RET_INSN(pshift, 0x0671F1, CPU_MMX); }
- P S L L D { RET_INSN(pshift, 0x0672F2, CPU_MMX); }
- P S L L Q { RET_INSN(pshift, 0x0673F3, CPU_MMX); }
- P S R A W { RET_INSN(pshift, 0x0471E1, CPU_MMX); }
- P S R A D { RET_INSN(pshift, 0x0472E2, CPU_MMX); }
- P S R L W { RET_INSN(pshift, 0x0271D1, CPU_MMX); }
- P S R L D { RET_INSN(pshift, 0x0272D2, CPU_MMX); }
- P S R L Q { RET_INSN(pshift, 0x0273D3, CPU_MMX); }
- P S U B B { RET_INSN(mmxsse2, 0xF8, CPU_MMX); }
- P S U B W { RET_INSN(mmxsse2, 0xF9, CPU_MMX); }
- P S U B D { RET_INSN(mmxsse2, 0xFA, CPU_MMX); }
- P S U B Q { RET_INSN(mmxsse2, 0xFB, CPU_MMX); }
- P S U B S B { RET_INSN(mmxsse2, 0xE8, CPU_MMX); }
- P S U B S W { RET_INSN(mmxsse2, 0xE9, CPU_MMX); }
- P S U B U S B { RET_INSN(mmxsse2, 0xD8, CPU_MMX); }
- P S U B U S W { RET_INSN(mmxsse2, 0xD9, CPU_MMX); }
- P U N P C K H B W { RET_INSN(mmxsse2, 0x68, CPU_MMX); }
- P U N P C K H W D { RET_INSN(mmxsse2, 0x69, CPU_MMX); }
- P U N P C K H D Q { RET_INSN(mmxsse2, 0x6A, CPU_MMX); }
- P U N P C K L B W { RET_INSN(mmxsse2, 0x60, CPU_MMX); }
- P U N P C K L W D { RET_INSN(mmxsse2, 0x61, CPU_MMX); }
- P U N P C K L D Q { RET_INSN(mmxsse2, 0x62, CPU_MMX); }
- P X O R { RET_INSN(mmxsse2, 0xEF, CPU_MMX); }
- /* PIII (Katmai) new instructions / SIMD instructions */
- A D D P S { RET_INSN(sseps, 0x58, CPU_SSE); }
- A D D S S { RET_INSN(ssess, 0xF358, CPU_SSE); }
- A N D N P S { RET_INSN(sseps, 0x55, CPU_SSE); }
- A N D P S { RET_INSN(sseps, 0x54, CPU_SSE); }
- C M P E Q P S { RET_INSN(ssecmpps, 0x00, CPU_SSE); }
- C M P E Q S S { RET_INSN(ssecmpss, 0x00F3, CPU_SSE); }
- C M P L E P S { RET_INSN(ssecmpps, 0x02, CPU_SSE); }
- C M P L E S S { RET_INSN(ssecmpss, 0x02F3, CPU_SSE); }
- C M P L T P S { RET_INSN(ssecmpps, 0x01, CPU_SSE); }
- C M P L T S S { RET_INSN(ssecmpss, 0x01F3, CPU_SSE); }
- C M P N E Q P S { RET_INSN(ssecmpps, 0x04, CPU_SSE); }
- C M P N E Q S S { RET_INSN(ssecmpss, 0x04F3, CPU_SSE); }
- C M P N L E P S { RET_INSN(ssecmpps, 0x06, CPU_SSE); }
- C M P N L E S S { RET_INSN(ssecmpss, 0x06F3, CPU_SSE); }
- C M P N L T P S { RET_INSN(ssecmpps, 0x05, CPU_SSE); }
- C M P N L T S S { RET_INSN(ssecmpss, 0x05F3, CPU_SSE); }
- C M P O R D P S { RET_INSN(ssecmpps, 0x07, CPU_SSE); }
- C M P O R D S S { RET_INSN(ssecmpss, 0x07F3, CPU_SSE); }
- C M P U N O R D P S { RET_INSN(ssecmpps, 0x03, CPU_SSE); }
- C M P U N O R D S S { RET_INSN(ssecmpss, 0x03F3, CPU_SSE); }
- C M P P S { RET_INSN(ssepsimm, 0xC2, CPU_SSE); }
- C M P S S { RET_INSN(ssessimm, 0xF3C2, CPU_SSE); }
- C O M I S S { RET_INSN(sseps, 0x2F, CPU_SSE); }
- C V T P I "2" P S { RET_INSN(sseps, 0x2A, CPU_SSE); }
- C V T P S "2" P I { RET_INSN(sseps, 0x2D, CPU_SSE); }
- C V T S I "2" S S { RET_INSN(ssess, 0xF32A, CPU_SSE); }
- C V T S S "2" S I { RET_INSN(ssess, 0xF32D, CPU_SSE); }
- C V T T P S "2" P I { RET_INSN(sseps, 0x2C, CPU_SSE); }
- C V T T S S "2" S I { RET_INSN(ssess, 0xF32C, CPU_SSE); }
- D I V P S { RET_INSN(sseps, 0x5E, CPU_SSE); }
- D I V S S { RET_INSN(ssess, 0xF35E, CPU_SSE); }
- L D M X C S R { RET_INSN(ldstmxcsr, 0x02, CPU_SSE); }
- M A S K M O V Q { RET_INSN(maskmovq, 0, CPU_P3|CPU_MMX); }
- M A X P S { RET_INSN(sseps, 0x5F, CPU_SSE); }
- M A X S S { RET_INSN(ssess, 0xF35F, CPU_SSE); }
- M I N P S { RET_INSN(sseps, 0x5D, CPU_SSE); }
- M I N S S { RET_INSN(ssess, 0xF35D, CPU_SSE); }
- M O V A P S { RET_INSN(movaups, 0x28, CPU_SSE); }
- M O V H L P S { RET_INSN(movhllhps, 0x12, CPU_SSE); }
- M O V H P S { RET_INSN(movhlps, 0x16, CPU_SSE); }
- M O V L H P S { RET_INSN(movhllhps, 0x16, CPU_SSE); }
- M O V L P S { RET_INSN(movhlps, 0x12, CPU_SSE); }
- M O V M S K P S { RET_INSN(movmskps, 0, CPU_SSE); }
- M O V N T P S { RET_INSN(movntps, 0, CPU_SSE); }
- M O V N T Q { RET_INSN(movntq, 0, CPU_SSE); }
- M O V S S { RET_INSN(movss, 0, CPU_SSE); }
- M O V U P S { RET_INSN(movaups, 0x10, CPU_SSE); }
- M U L P S { RET_INSN(sseps, 0x59, CPU_SSE); }
- M U L S S { RET_INSN(ssess, 0xF359, CPU_SSE); }
- O R P S { RET_INSN(sseps, 0x56, CPU_SSE); }
- P A V G B { RET_INSN(mmxsse2, 0xE0, CPU_P3|CPU_MMX); }
- P A V G W { RET_INSN(mmxsse2, 0xE3, CPU_P3|CPU_MMX); }
- P E X T R W { RET_INSN(pextrw, 0, CPU_P3|CPU_MMX); }
- P I N S R W { RET_INSN(pinsrw, 0, CPU_P3|CPU_MMX); }
- P M A X S W { RET_INSN(mmxsse2, 0xEE, CPU_P3|CPU_MMX); }
- P M A X U B { RET_INSN(mmxsse2, 0xDE, CPU_P3|CPU_MMX); }
- P M I N S W { RET_INSN(mmxsse2, 0xEA, CPU_P3|CPU_MMX); }
- P M I N U B { RET_INSN(mmxsse2, 0xDA, CPU_P3|CPU_MMX); }
- P M O V M S K B { RET_INSN(pmovmskb, 0, CPU_SSE); }
- P M U L H U W { RET_INSN(mmxsse2, 0xE4, CPU_P3|CPU_MMX); }
- P R E F E T C H N T A { RET_INSN(twobytemem, 0x000F18, CPU_P3); }
- P R E F E T C H T "0" { RET_INSN(twobytemem, 0x010F18, CPU_P3); }
- P R E F E T C H T "1" { RET_INSN(twobytemem, 0x020F18, CPU_P3); }
- P R E F E T C H T "2" { RET_INSN(twobytemem, 0x030F18, CPU_P3); }
- P S A D B W { RET_INSN(mmxsse2, 0xF6, CPU_P3|CPU_MMX); }
- P S H U F W { RET_INSN(pshufw, 0, CPU_P3|CPU_MMX); }
- R C P P S { RET_INSN(sseps, 0x53, CPU_SSE); }
- R C P S S { RET_INSN(ssess, 0xF353, CPU_SSE); }
- R S Q R T P S { RET_INSN(sseps, 0x52, CPU_SSE); }
- R S Q R T S S { RET_INSN(ssess, 0xF352, CPU_SSE); }
- S F E N C E { RET_INSN(threebyte, 0x0FAEF8, CPU_P3); }
- S H U F P S { RET_INSN(ssepsimm, 0xC6, CPU_SSE); }
- S Q R T P S { RET_INSN(sseps, 0x51, CPU_SSE); }
- S Q R T S S { RET_INSN(ssess, 0xF351, CPU_SSE); }
- S T M X C S R { RET_INSN(ldstmxcsr, 0x03, CPU_SSE); }
- S U B P S { RET_INSN(sseps, 0x5C, CPU_SSE); }
- S U B S S { RET_INSN(ssess, 0xF35C, CPU_SSE); }
- U C O M I S S { RET_INSN(ssess, 0xF32E, CPU_SSE); }
- U N P C K H P S { RET_INSN(sseps, 0x15, CPU_SSE); }
- U N P C K L P S { RET_INSN(sseps, 0x14, CPU_SSE); }
- X O R P S { RET_INSN(sseps, 0x57, CPU_SSE); }
- /* SSE2 instructions */
- A D D P D { RET_INSN(ssess, 0x6658, CPU_SSE2); }
- A D D S D { RET_INSN(ssess, 0xF258, CPU_SSE2); }
- A N D N P D { RET_INSN(ssess, 0x6655, CPU_SSE2); }
- A N D P D { RET_INSN(ssess, 0x6654, CPU_SSE2); }
- C M P E Q P D { RET_INSN(ssecmpss, 0x0066, CPU_SSE2); }
- C M P E Q S D { RET_INSN(ssecmpss, 0x00F2, CPU_SSE2); }
- C M P L E P D { RET_INSN(ssecmpss, 0x0266, CPU_SSE2); }
- C M P L E S D { RET_INSN(ssecmpss, 0x02F2, CPU_SSE2); }
- C M P L T P D { RET_INSN(ssecmpss, 0x0166, CPU_SSE2); }
- C M P L T S D { RET_INSN(ssecmpss, 0x01F2, CPU_SSE2); }
- C M P N E Q P D { RET_INSN(ssecmpss, 0x0466, CPU_SSE2); }
- C M P N E Q S D { RET_INSN(ssecmpss, 0x04F2, CPU_SSE2); }
- C M P N L E P D { RET_INSN(ssecmpss, 0x0666, CPU_SSE2); }
- C M P N L E S D { RET_INSN(ssecmpss, 0x06F2, CPU_SSE2); }
- C M P N L T P D { RET_INSN(ssecmpss, 0x0566, CPU_SSE2); }
- C M P N L T S D { RET_INSN(ssecmpss, 0x05F2, CPU_SSE2); }
- C M P O R D P D { RET_INSN(ssecmpss, 0x0766, CPU_SSE2); }
- C M P O R D S D { RET_INSN(ssecmpss, 0x07F2, CPU_SSE2); }
- C M P U N O R D P D { RET_INSN(ssecmpss, 0x0366, CPU_SSE2); }
- C M P U N O R D S D { RET_INSN(ssecmpss, 0x03F2, CPU_SSE2); }
- C M P P D { RET_INSN(ssessimm, 0x66C2, CPU_SSE2); }
- /* C M P S D is in string instructions above */
- C O M I S D { RET_INSN(ssess, 0x662F, CPU_SSE2); }
- C V T P I "2" P D { RET_INSN(ssess, 0x662A, CPU_SSE2); }
- C V T S I "2" S D { RET_INSN(ssess, 0xF22A, CPU_SSE2); }
- D I V P D { RET_INSN(ssess, 0x665E, CPU_SSE2); }
- D I V S D { RET_INSN(ssess, 0xF25E, CPU_SSE2); }
- M A X P D { RET_INSN(ssess, 0x665F, CPU_SSE2); }
- M A X S D { RET_INSN(ssess, 0xF25F, CPU_SSE2); }
- M I N P D { RET_INSN(ssess, 0x665D, CPU_SSE2); }
- M I N S D { RET_INSN(ssess, 0xF25D, CPU_SSE2); }
- M O V A P D { RET_INSN(movaupd, 0x28, CPU_SSE2); }
- M O V H P D { RET_INSN(movhlpd, 0x16, CPU_SSE2); }
- M O V L P D { RET_INSN(movhlpd, 0x12, CPU_SSE2); }
- M O V M S K P D { RET_INSN(movmskpd, 0, CPU_SSE2); }
- M O V N T P D { RET_INSN(movntpddq, 0x2B, CPU_SSE2); }
- M O V N T D Q { RET_INSN(movntpddq, 0xE7, CPU_SSE2); }
- /* M O V S D is in string instructions above */
- M O V U P D { RET_INSN(movaupd, 0x10, CPU_SSE2); }
- M U L P D { RET_INSN(ssess, 0x6659, CPU_SSE2); }
- M U L S D { RET_INSN(ssess, 0xF259, CPU_SSE2); }
- O R P D { RET_INSN(ssess, 0x6656, CPU_SSE2); }
- S H U F P D { RET_INSN(ssessimm, 0x66C6, CPU_SSE2); }
- S Q R T P D { RET_INSN(ssess, 0x6651, CPU_SSE2); }
- S Q R T S D { RET_INSN(ssess, 0xF251, CPU_SSE2); }
- S U B P D { RET_INSN(ssess, 0x665C, CPU_SSE2); }
- S U B S D { RET_INSN(ssess, 0xF25C, CPU_SSE2); }
- U C O M I S D { RET_INSN(ssess, 0xF22E, CPU_SSE2); }
- U N P C K H P D { RET_INSN(ssess, 0x6615, CPU_SSE2); }
- U N P C K L P D { RET_INSN(ssess, 0x6614, CPU_SSE2); }
- X O R P D { RET_INSN(ssess, 0x6657, CPU_SSE2); }
- C V T D Q "2" P D { RET_INSN(ssess, 0xF3E6, CPU_SSE2); }
- C V T P D "2" D Q { RET_INSN(ssess, 0xF2E6, CPU_SSE2); }
- C V T D Q "2" P S { RET_INSN(sseps, 0x5B, CPU_SSE2); }
- C V T P D "2" P I { RET_INSN(ssess, 0x662D, CPU_SSE2); }
- C V T P D "2" P S { RET_INSN(ssess, 0x665A, CPU_SSE2); }
- C V T P S "2" P D { RET_INSN(sseps, 0x5A, CPU_SSE2); }
- C V T P S "2" D Q { RET_INSN(ssess, 0x665B, CPU_SSE2); }
- C V T S D "2" S I { RET_INSN(ssess, 0xF22D, CPU_SSE2); }
- C V T S D "2" S S { RET_INSN(ssess, 0xF25A, CPU_SSE2); }
- C V T S S "2" S D { RET_INSN(ssess, 0xF35A, CPU_SSE2); }
- C V T T P D "2" P I { RET_INSN(ssess, 0x662C, CPU_SSE2); }
- C V T T S D "2" S I { RET_INSN(ssess, 0xF22C, CPU_SSE2); }
- C V T T P D "2" D Q { RET_INSN(ssess, 0x66E6, CPU_SSE2); }
- C V T T P S "2" D Q { RET_INSN(ssess, 0xF35B, CPU_SSE2); }
- M A S K M O V D Q U { RET_INSN(maskmovdqu, 0, CPU_SSE2); }
- M O V D Q A { RET_INSN(movdqau, 0x66, CPU_SSE2); }
- M O V D Q U { RET_INSN(movdqau, 0xF3, CPU_SSE2); }
- M O V D Q "2" Q { RET_INSN(movdq2q, 0, CPU_SSE2); }
- M O V Q "2" D Q { RET_INSN(movq2dq, 0, CPU_SSE2); }
- P M U L U D Q { RET_INSN(mmxsse2, 0xF4, CPU_SSE2); }
- P S H U F D { RET_INSN(ssessimm, 0x6670, CPU_SSE2); }
- P S H U F H W { RET_INSN(ssessimm, 0xF370, CPU_SSE2); }
- P S H U F L W { RET_INSN(ssessimm, 0xF270, CPU_SSE2); }
- P S L L D Q { RET_INSN(pslrldq, 0x07, CPU_SSE2); }
- P S R L D Q { RET_INSN(pslrldq, 0x03, CPU_SSE2); }
- P U N P C K H Q D Q { RET_INSN(ssess, 0x666D, CPU_SSE2); }
- P U N P C K L Q D Q { RET_INSN(ssess, 0x666C, CPU_SSE2); }
- /* AMD 3DNow! instructions */
- P R E F E T C H { RET_INSN(twobytemem, 0x000F0D, CPU_3DNow); }
- P R E F E T C H W { RET_INSN(twobytemem, 0x010F0D, CPU_3DNow); }
- F E M M S { RET_INSN(twobyte, 0x0F0E, CPU_3DNow); }
- P A V G U S B { RET_INSN(now3d, 0xBF, CPU_3DNow); }
- P F "2" I D { RET_INSN(now3d, 0x1D, CPU_3DNow); }
- P F "2" I W { RET_INSN(now3d, 0x1C, CPU_Athlon|CPU_3DNow); }
- P F A C C { RET_INSN(now3d, 0xAE, CPU_3DNow); }
- P F A D D { RET_INSN(now3d, 0x9E, CPU_3DNow); }
- P F C M P E Q { RET_INSN(now3d, 0xB0, CPU_3DNow); }
- P F C M P G E { RET_INSN(now3d, 0x90, CPU_3DNow); }
- P F C M P G T { RET_INSN(now3d, 0xA0, CPU_3DNow); }
- P F M A X { RET_INSN(now3d, 0xA4, CPU_3DNow); }
- P F M I N { RET_INSN(now3d, 0x94, CPU_3DNow); }
- P F M U L { RET_INSN(now3d, 0xB4, CPU_3DNow); }
- P F N A C C { RET_INSN(now3d, 0x8A, CPU_Athlon|CPU_3DNow); }
- P F P N A C C { RET_INSN(now3d, 0x8E, CPU_Athlon|CPU_3DNow); }
- P F R C P { RET_INSN(now3d, 0x96, CPU_3DNow); }
- P F R C P I T "1" { RET_INSN(now3d, 0xA6, CPU_3DNow); }
- P F R C P I T "2" { RET_INSN(now3d, 0xB6, CPU_3DNow); }
- P F R S Q I T "1" { RET_INSN(now3d, 0xA7, CPU_3DNow); }
- P F R S Q R T { RET_INSN(now3d, 0x97, CPU_3DNow); }
- P F S U B { RET_INSN(now3d, 0x9A, CPU_3DNow); }
- P F S U B R { RET_INSN(now3d, 0xAA, CPU_3DNow); }
- P I "2" F D { RET_INSN(now3d, 0x0D, CPU_3DNow); }
- P I "2" F W { RET_INSN(now3d, 0x0C, CPU_Athlon|CPU_3DNow); }
- P M U L H R W A { RET_INSN(now3d, 0xB7, CPU_3DNow); }
- P S W A P D { RET_INSN(now3d, 0xBB, CPU_Athlon|CPU_3DNow); }
- /* AMD extensions */
- S Y S C A L L { RET_INSN(twobyte, 0x0F05, CPU_686|CPU_AMD); }
- S Y S R E T { RET_INSN(twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); }
- /* AMD x86-64 extensions */
- S W A P G S {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("`%s' is an instruction in 64-bit mode"),
- oid);
- return YASM_ARCH_CHECK_ID_NONE;
- }
- RET_INSN(threebyte, 0x0F01F8, CPU_Hammer|CPU_64);
- }
- /* Cyrix MMX instructions */
- P A D D S I W { RET_INSN(cyrixmmx, 0x51, CPU_Cyrix|CPU_MMX); }
- P A V E B { RET_INSN(cyrixmmx, 0x50, CPU_Cyrix|CPU_MMX); }
- P D I S T I B { RET_INSN(cyrixmmx, 0x54, CPU_Cyrix|CPU_MMX); }
- P M A C H R I W { RET_INSN(pmachriw, 0, CPU_Cyrix|CPU_MMX); }
- P M A G W { RET_INSN(cyrixmmx, 0x52, CPU_Cyrix|CPU_MMX); }
- P M U L H R I W { RET_INSN(cyrixmmx, 0x5D, CPU_Cyrix|CPU_MMX); }
- P M U L H R W C { RET_INSN(cyrixmmx, 0x59, CPU_Cyrix|CPU_MMX); }
- P M V G E Z B { RET_INSN(cyrixmmx, 0x5C, CPU_Cyrix|CPU_MMX); }
- P M V L Z B { RET_INSN(cyrixmmx, 0x5B, CPU_Cyrix|CPU_MMX); }
- P M V N Z B { RET_INSN(cyrixmmx, 0x5A, CPU_Cyrix|CPU_MMX); }
- P M V Z B { RET_INSN(cyrixmmx, 0x58, CPU_Cyrix|CPU_MMX); }
- P S U B S I W { RET_INSN(cyrixmmx, 0x55, CPU_Cyrix|CPU_MMX); }
- /* Cyrix extensions */
- R D S H R { RET_INSN(twobyte, 0x0F36, CPU_686|CPU_Cyrix|CPU_SMM); }
- R S D C { RET_INSN(rsdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
- R S L D T { RET_INSN(cyrixsmm, 0x7B, CPU_486|CPU_Cyrix|CPU_SMM); }
- R S T S { RET_INSN(cyrixsmm, 0x7D, CPU_486|CPU_Cyrix|CPU_SMM); }
- S V D C { RET_INSN(svdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); }
- S V L D T { RET_INSN(cyrixsmm, 0x7A, CPU_486|CPU_Cyrix|CPU_SMM); }
- S V T S { RET_INSN(cyrixsmm, 0x7C, CPU_486|CPU_Cyrix|CPU_SMM); }
- S M I N T { RET_INSN(twobyte, 0x0F38, CPU_686|CPU_Cyrix); }
- S M I N T O L D { RET_INSN(twobyte, 0x0F7E, CPU_486|CPU_Cyrix|CPU_Obs); }
- W R S H R { RET_INSN(twobyte, 0x0F37, CPU_686|CPU_Cyrix|CPU_SMM); }
- /* Obsolete/undocumented instructions */
- F S E T P M { RET_INSN(twobyte, 0xDBE4, CPU_286|CPU_FPU|CPU_Obs); }
- I B T S { RET_INSN(ibts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
- L O A D A L L { RET_INSN(twobyte, 0x0F07, CPU_386|CPU_Undoc); }
- L O A D A L L "286" { RET_INSN(twobyte, 0x0F05, CPU_286|CPU_Undoc); }
- S A L C {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
- RET_INSN(not64, 0, CPU_Not64);
- }
- RET_INSN(onebyte, 0x00D6, CPU_Undoc);
- }
- S M I { RET_INSN(onebyte, 0x00F1, CPU_386|CPU_Undoc); }
- U M O V { RET_INSN(umov, 0, CPU_386|CPU_Undoc); }
- X B T S { RET_INSN(xbts, 0, CPU_386|CPU_Undoc|CPU_Obs); }
-
-
- /* catchalls */
- [\001-\377]+ {
- return YASM_ARCH_CHECK_ID_NONE;
- }
- [\000] {
- return YASM_ARCH_CHECK_ID_NONE;
- }
- */
-}
+++ /dev/null
-/* $IdPath$
- * Bytecode internal structures header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_BC_INT_H
-#define YASM_BC_INT_H
-
-struct yasm_effaddr {
- /*@only@*/ /*@null@*/ yasm_expr *disp; /* address displacement */
- unsigned char len; /* length of disp (in bytes), 0 if unknown,
- * 0xff if unknown and required to be >0.
- */
- unsigned char nosplit; /* 1 if reg*2 should not be split into
- reg+reg. (0 if not) */
-};
-
-struct yasm_immval {
- /*@only@*/ /*@null@*/ yasm_expr *val;
-
- unsigned char len; /* final length (in bytes), 0 if unknown */
- unsigned char sign; /* 1 if final imm is treated as signed */
-};
-
-struct yasm_bytecode {
- /*@reldef@*/ STAILQ_ENTRY(yasm_bytecode) link;
-
- yasm_bytecode_type type;
-
- /* number of times bytecode is repeated, NULL=1. */
- /*@only@*/ /*@null@*/ yasm_expr *multiple;
-
- unsigned long len; /* total length of entire bytecode (including
- multiple copies), 0 if unknown */
-
- /* where it came from */
- unsigned long line;
-
- /* other assembler state info */
- unsigned long offset; /* 0 if unknown */
-
- /* storage for optimizer flags */
- unsigned long opt_flags;
-};
-
-#define yasm_bcs__next(x) STAILQ_NEXT(x, link)
-
-#endif
+++ /dev/null
-#include "util.h"
-RCSID("$IdPath$");
-
-/*****************************************************************************/
-/* MODULE NAME: BitVector.c MODULE TYPE: (adt) */
-/*****************************************************************************/
-/* MODULE IMPORTS: */
-/*****************************************************************************/
-#include <ctype.h> /* MODULE TYPE: (sys) */
-#ifdef STDC_HEADERS
-#include <limits.h> /* MODULE TYPE: (sys) */
-#include <string.h> /* MODULE TYPE: (sys) */
-#endif
-/*****************************************************************************/
-/* MODULE INTERFACE: */
-/*****************************************************************************/
-#include "bitvect.h"
-
-/* ToolBox.h */
-#define and && /* logical (boolean) operators: lower case */
-#define or ||
-#define not !
-
-#define AND & /* binary (bitwise) operators: UPPER CASE */
-#define OR |
-#define XOR ^
-#define NOT ~
-#define SHL <<
-#define SHR >>
-
-#ifdef ENABLE_MODULO
-#define mod % /* arithmetic operators */
-#endif
-
-#define blockdef(name,size) unsigned char name[size]
-#define blocktypedef(name,size) typedef unsigned char name[size]
-
-/*****************************************************************************/
-/* MODULE RESOURCES: */
-/*****************************************************************************/
-
-#define bits_(BitVector) *(BitVector-3)
-#define size_(BitVector) *(BitVector-2)
-#define mask_(BitVector) *(BitVector-1)
-
-#define ERRCODE_TYPE "sizeof(word) > sizeof(size_t)"
-#define ERRCODE_BITS "bits(word) != sizeof(word)*8"
-#define ERRCODE_WORD "bits(word) < 16"
-#define ERRCODE_LONG "bits(word) > bits(long)"
-#define ERRCODE_POWR "bits(word) != 2^x"
-#define ERRCODE_LOGA "bits(word) != 2^ld(bits(word))"
-#define ERRCODE_NULL "unable to allocate memory"
-#define ERRCODE_INDX "index out of range"
-#define ERRCODE_ORDR "minimum > maximum index"
-#define ERRCODE_SIZE "bit vector size mismatch"
-#define ERRCODE_PARS "input string syntax error"
-#define ERRCODE_OVFL "numeric overflow error"
-#define ERRCODE_SAME "result vector(s) must be distinct"
-#define ERRCODE_EXPO "exponent must be positive"
-#define ERRCODE_ZERO "division by zero error"
-#define ERRCODE_OOPS "unexpected internal error - please contact author"
-
-/*****************************************************************************/
-/* MODULE IMPLEMENTATION: */
-/*****************************************************************************/
-
- /**********************************************/
- /* global implementation-intrinsic constants: */
- /**********************************************/
-
-#define BIT_VECTOR_HIDDEN_WORDS 3
-
- /*****************************************************************/
- /* global machine-dependent constants (set by "BitVector_Boot"): */
- /*****************************************************************/
-
-static N_word BITS; /* = # of bits in machine word (must be power of 2) */
-static N_word MODMASK; /* = BITS - 1 (mask for calculating modulo BITS) */
-static N_word LOGBITS; /* = ld(BITS) (logarithmus dualis) */
-static N_word FACTOR; /* = ld(BITS / 8) (ld of # of bytes) */
-
-static N_word LSB = 1; /* = mask for least significant bit */
-static N_word MSB; /* = mask for most significant bit */
-
-static N_word LONGBITS; /* = # of bits in unsigned long */
-
-static N_word LOG10; /* = logarithm to base 10 of BITS - 1 */
-static N_word EXP10; /* = largest possible power of 10 in signed int */
-
- /********************************************************************/
- /* global bit mask table for fast access (set by "BitVector_Boot"): */
- /********************************************************************/
-
-static wordptr BITMASKTAB;
-
- /*****************************/
- /* global macro definitions: */
- /*****************************/
-
-#define BIT_VECTOR_ZERO_WORDS(target,count) \
- while (count-- > 0) *target++ = 0;
-
-#define BIT_VECTOR_FILL_WORDS(target,fill,count) \
- while (count-- > 0) *target++ = fill;
-
-#define BIT_VECTOR_FLIP_WORDS(target,flip,count) \
- while (count-- > 0) *target++ ^= flip;
-
-#define BIT_VECTOR_COPY_WORDS(target,source,count) \
- while (count-- > 0) *target++ = *source++;
-
-#define BIT_VECTOR_BACK_WORDS(target,source,count) \
- { target += count; source += count; while (count-- > 0) *--target = *--source; }
-
-#define BIT_VECTOR_CLR_BIT(address,index) \
- *(address+(index>>LOGBITS)) &= NOT BITMASKTAB[index AND MODMASK];
-
-#define BIT_VECTOR_SET_BIT(address,index) \
- *(address+(index>>LOGBITS)) |= BITMASKTAB[index AND MODMASK];
-
-#define BIT_VECTOR_TST_BIT(address,index) \
- ((*(address+(index>>LOGBITS)) AND BITMASKTAB[index AND MODMASK]) != 0)
-
-#define BIT_VECTOR_FLP_BIT(address,index,mask) \
- (mask = BITMASKTAB[index AND MODMASK]), \
- (((*(addr+(index>>LOGBITS)) ^= mask) AND mask) != 0)
-
-#define BIT_VECTOR_DIGITIZE(type,value,digit) \
- value = (type) ((digit = value) / 10); \
- digit -= value * 10; \
- digit += (type) '0';
-
- /*********************************************************/
- /* private low-level functions (potentially dangerous!): */
- /*********************************************************/
-
-static N_word power10(N_word x)
-{
- N_word y = 1;
-
- while (x-- > 0) y *= 10;
- return(y);
-}
-
-static void BIT_VECTOR_zro_words(wordptr addr, N_word count)
-{
- BIT_VECTOR_ZERO_WORDS(addr,count)
-}
-
-static void BIT_VECTOR_cpy_words(wordptr target, wordptr source, N_word count)
-{
- BIT_VECTOR_COPY_WORDS(target,source,count)
-}
-
-static void BIT_VECTOR_mov_words(wordptr target, wordptr source, N_word count)
-{
- if (target != source)
- {
- if (target < source) BIT_VECTOR_COPY_WORDS(target,source,count)
- else BIT_VECTOR_BACK_WORDS(target,source,count)
- }
-}
-
-static void BIT_VECTOR_ins_words(wordptr addr, N_word total, N_word count,
- boolean clear)
-{
- N_word length;
-
- if ((total > 0) and (count > 0))
- {
- if (count > total) count = total;
- length = total - count;
- if (length > 0) BIT_VECTOR_mov_words(addr+count,addr,length);
- if (clear) BIT_VECTOR_zro_words(addr,count);
- }
-}
-
-static void BIT_VECTOR_del_words(wordptr addr, N_word total, N_word count,
- boolean clear)
-{
- N_word length;
-
- if ((total > 0) and (count > 0))
- {
- if (count > total) count = total;
- length = total - count;
- if (length > 0) BIT_VECTOR_mov_words(addr,addr+count,length);
- if (clear) BIT_VECTOR_zro_words(addr+length,count);
- }
-}
-
-static void BIT_VECTOR_reverse(charptr string, N_word length)
-{
- charptr last;
- N_char temp;
-
- if (length > 1)
- {
- last = string + length - 1;
- while (string < last)
- {
- temp = *string;
- *string = *last;
- *last = temp;
- string++;
- last--;
- }
- }
-}
-
-static N_word BIT_VECTOR_int2str(charptr string, N_word value)
-{
- N_word length;
- N_word digit;
- charptr work;
-
- work = string;
- if (value > 0)
- {
- length = 0;
- while (value > 0)
- {
- BIT_VECTOR_DIGITIZE(N_word,value,digit)
- *work++ = (N_char) digit;
- length++;
- }
- BIT_VECTOR_reverse(string,length);
- }
- else
- {
- length = 1;
- *work++ = (N_char) '0';
- }
- return(length);
-}
-
-static N_word BIT_VECTOR_str2int(charptr string, N_word *value)
-{
- N_word length;
- N_word digit;
-
- *value = 0;
- length = 0;
- digit = (N_word) *string++;
- /* separate because isdigit() is likely a macro! */
- while (isdigit((int)digit) != 0)
- {
- length++;
- digit -= (N_word) '0';
- if (*value) *value *= 10;
- *value += digit;
- digit = (N_word) *string++;
- }
- return(length);
-}
-
- /********************************************/
- /* routine to convert error code to string: */
- /********************************************/
-
-const char * BitVector_Error(ErrCode error)
-{
- switch (error)
- {
- case ErrCode_Ok: return( NULL ); break;
- case ErrCode_Type: return( ERRCODE_TYPE ); break;
- case ErrCode_Bits: return( ERRCODE_BITS ); break;
- case ErrCode_Word: return( ERRCODE_WORD ); break;
- case ErrCode_Long: return( ERRCODE_LONG ); break;
- case ErrCode_Powr: return( ERRCODE_POWR ); break;
- case ErrCode_Loga: return( ERRCODE_LOGA ); break;
- case ErrCode_Null: return( ERRCODE_NULL ); break;
- case ErrCode_Indx: return( ERRCODE_INDX ); break;
- case ErrCode_Ordr: return( ERRCODE_ORDR ); break;
- case ErrCode_Size: return( ERRCODE_SIZE ); break;
- case ErrCode_Pars: return( ERRCODE_PARS ); break;
- case ErrCode_Ovfl: return( ERRCODE_OVFL ); break;
- case ErrCode_Same: return( ERRCODE_SAME ); break;
- case ErrCode_Expo: return( ERRCODE_EXPO ); break;
- case ErrCode_Zero: return( ERRCODE_ZERO ); break;
- default: return( ERRCODE_OOPS ); break;
- }
-}
-
- /*****************************************/
- /* automatic self-configuration routine: */
- /*****************************************/
-
- /*******************************************************/
- /* */
- /* MUST be called once prior to any other function */
- /* to initialize the machine dependent constants */
- /* of this package! (But call only ONCE, or you */
- /* will suffer memory leaks!) */
- /* */
- /*******************************************************/
-
-ErrCode BitVector_Boot(void)
-{
- N_long longsample = 1L;
- N_word sample = LSB;
- N_word lsb;
-
- if (sizeof(N_word) > sizeof(size_t)) return(ErrCode_Type);
-
- BITS = 1;
- while (sample <<= 1) BITS++; /* determine # of bits in a machine word */
-
- if (BITS != (sizeof(N_word) << 3)) return(ErrCode_Bits);
-
- if (BITS < 16) return(ErrCode_Word);
-
- LONGBITS = 1;
- while (longsample <<= 1) LONGBITS++; /* = # of bits in an unsigned long */
-
- if (BITS > LONGBITS) return(ErrCode_Long);
-
- LOGBITS = 0;
- sample = BITS;
- lsb = (sample AND LSB);
- while ((sample >>= 1) and (not lsb))
- {
- LOGBITS++;
- lsb = (sample AND LSB);
- }
-
- if (sample) return(ErrCode_Powr); /* # of bits is not a power of 2! */
-
- if (BITS != (LSB << LOGBITS)) return(ErrCode_Loga);
-
- MODMASK = BITS - 1;
- FACTOR = LOGBITS - 3; /* ld(BITS / 8) = ld(BITS) - ld(8) = ld(BITS) - 3 */
- MSB = (LSB << MODMASK);
-
- BITMASKTAB = (wordptr) yasm_xmalloc((size_t) (BITS << FACTOR));
-
- if (BITMASKTAB == NULL) return(ErrCode_Null);
-
- for ( sample = 0; sample < BITS; sample++ )
- {
- BITMASKTAB[sample] = (LSB << sample);
- }
-
- LOG10 = (N_word) (MODMASK * 0.30103); /* = (BITS - 1) * ( ln 2 / ln 10 ) */
- EXP10 = power10(LOG10);
-
- return(ErrCode_Ok);
-}
-
-void BitVector_Shutdown(void)
-{
- if (BITMASKTAB) yasm_xfree(BITMASKTAB);
-}
-
-N_word BitVector_Size(N_int bits) /* bit vector size (# of words) */
-{
- N_word size;
-
- size = bits >> LOGBITS;
- if (bits AND MODMASK) size++;
- return(size);
-}
-
-N_word BitVector_Mask(N_int bits) /* bit vector mask (unused bits) */
-{
- N_word mask;
-
- mask = bits AND MODMASK;
- if (mask) mask = (N_word) ~(~0L << mask); else mask = (N_word) ~0L;
- return(mask);
-}
-
-const char * BitVector_Version(void)
-{
- return("6.0");
-}
-
-N_int BitVector_Word_Bits(void)
-{
- return(BITS);
-}
-
-N_int BitVector_Long_Bits(void)
-{
- return(LONGBITS);
-}
-
-/********************************************************************/
-/* */
-/* WARNING: Do not "free()" constant character strings, i.e., */
-/* don't call "BitVector_Dispose()" for strings returned */
-/* by "BitVector_Error()" or "BitVector_Version()"! */
-/* */
-/* ONLY call this function for strings allocated with "malloc()", */
-/* i.e., the strings returned by the functions "BitVector_to_*()" */
-/* and "BitVector_Block_Read()"! */
-/* */
-/********************************************************************/
-
-void BitVector_Dispose(charptr string) /* free string */
-{
- if (string != NULL) yasm_xfree((voidptr) string);
-}
-
-void BitVector_Destroy(wordptr addr) /* free bitvec */
-{
- if (addr != NULL)
- {
- addr -= BIT_VECTOR_HIDDEN_WORDS;
- yasm_xfree((voidptr) addr);
- }
-}
-
-void BitVector_Destroy_List(listptr list, N_int count) /* free list */
-{
- listptr slot;
-
- if (list != NULL)
- {
- slot = list;
- while (count-- > 0)
- {
- BitVector_Destroy(*slot++);
- }
- free((voidptr) list);
- }
-}
-
-wordptr BitVector_Create(N_int bits, boolean clear) /* malloc */
-{
- N_word size;
- N_word mask;
- N_word bytes;
- wordptr addr;
- wordptr zero;
-
- size = BitVector_Size(bits);
- mask = BitVector_Mask(bits);
- bytes = (size + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
- addr = (wordptr) yasm_xmalloc((size_t) bytes);
- if (addr != NULL)
- {
- *addr++ = bits;
- *addr++ = size;
- *addr++ = mask;
- if (clear)
- {
- zero = addr;
- BIT_VECTOR_ZERO_WORDS(zero,size)
- }
- }
- return(addr);
-}
-
-listptr BitVector_Create_List(N_int bits, boolean clear, N_int count)
-{
- listptr list = NULL;
- listptr slot;
- wordptr addr;
- N_int i;
-
- if (count > 0)
- {
- list = (listptr) malloc(sizeof(wordptr) * count);
- if (list != NULL)
- {
- slot = list;
- for ( i = 0; i < count; i++ )
- {
- addr = BitVector_Create(bits,clear);
- if (addr == NULL)
- {
- BitVector_Destroy_List(list,i);
- return(NULL);
- }
- *slot++ = addr;
- }
- }
- }
- return(list);
-}
-
-wordptr BitVector_Resize(wordptr oldaddr, N_int bits) /* realloc */
-{
- N_word bytes;
- N_word oldsize;
- N_word oldmask;
- N_word newsize;
- N_word newmask;
- wordptr newaddr;
- wordptr source;
- wordptr target;
-
- oldsize = size_(oldaddr);
- oldmask = mask_(oldaddr);
- newsize = BitVector_Size(bits);
- newmask = BitVector_Mask(bits);
- if (oldsize > 0) *(oldaddr+oldsize-1) &= oldmask;
- if (newsize <= oldsize)
- {
- newaddr = oldaddr;
- bits_(newaddr) = bits;
- size_(newaddr) = newsize;
- mask_(newaddr) = newmask;
- if (newsize > 0) *(newaddr+newsize-1) &= newmask;
- }
- else
- {
- bytes = (newsize + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
- newaddr = (wordptr) yasm_xmalloc((size_t) bytes);
- if (newaddr != NULL)
- {
- *newaddr++ = bits;
- *newaddr++ = newsize;
- *newaddr++ = newmask;
- target = newaddr;
- source = oldaddr;
- newsize -= oldsize;
- BIT_VECTOR_COPY_WORDS(target,source,oldsize)
- BIT_VECTOR_ZERO_WORDS(target,newsize)
- }
- BitVector_Destroy(oldaddr);
- }
- return(newaddr);
-}
-
-wordptr BitVector_Shadow(wordptr addr) /* makes new, same size but empty */
-{
- return( BitVector_Create(bits_(addr),true) );
-}
-
-wordptr BitVector_Clone(wordptr addr) /* makes exact duplicate */
-{
- N_word bits;
- wordptr twin;
-
- bits = bits_(addr);
- twin = BitVector_Create(bits,false);
- if ((twin != NULL) and (bits > 0))
- BIT_VECTOR_cpy_words(twin,addr,size_(addr));
- return(twin);
-}
-
-wordptr BitVector_Concat(wordptr X, wordptr Y) /* returns concatenation */
-{
- /* BEWARE that X = most significant part, Y = least significant part! */
-
- N_word bitsX;
- N_word bitsY;
- N_word bitsZ;
- wordptr Z;
-
- bitsX = bits_(X);
- bitsY = bits_(Y);
- bitsZ = bitsX + bitsY;
- Z = BitVector_Create(bitsZ,false);
- if ((Z != NULL) and (bitsZ > 0))
- {
- BIT_VECTOR_cpy_words(Z,Y,size_(Y));
- BitVector_Interval_Copy(Z,X,bitsY,0,bitsX);
- *(Z+size_(Z)-1) &= mask_(Z);
- }
- return(Z);
-}
-
-void BitVector_Copy(wordptr X, wordptr Y) /* X = Y */
-{
- N_word sizeX = size_(X);
- N_word sizeY = size_(Y);
- N_word maskX = mask_(X);
- N_word maskY = mask_(Y);
- N_word fill = 0;
- wordptr lastX;
- wordptr lastY;
-
- if ((X != Y) and (sizeX > 0))
- {
- lastX = X + sizeX - 1;
- if (sizeY > 0)
- {
- lastY = Y + sizeY - 1;
- *lastY &= maskY;
- while ((sizeX > 0) and (sizeY > 0))
- {
- *X++ = *Y++;
- sizeX--;
- sizeY--;
- }
- if ( (*lastY AND (maskY AND NOT (maskY >> 1))) != 0 )
- {
- fill = (N_word) ~0L;
- *(X-1) |= NOT maskY;
- }
- }
- while (sizeX-- > 0) *X++ = fill;
- *lastX &= maskX;
- }
-}
-
-void BitVector_Empty(wordptr addr) /* X = {} clr all */
-{
- N_word size = size_(addr);
-
- BIT_VECTOR_ZERO_WORDS(addr,size)
-}
-
-void BitVector_Fill(wordptr addr) /* X = ~{} set all */
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word fill = (N_word) ~0L;
-
- if (size > 0)
- {
- BIT_VECTOR_FILL_WORDS(addr,fill,size)
- *(--addr) &= mask;
- }
-}
-
-void BitVector_Flip(wordptr addr) /* X = ~X flip all */
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word flip = (N_word) ~0L;
-
- if (size > 0)
- {
- BIT_VECTOR_FLIP_WORDS(addr,flip,size)
- *(--addr) &= mask;
- }
-}
-
-void BitVector_Primes(wordptr addr)
-{
- N_word bits = bits_(addr);
- N_word size = size_(addr);
- wordptr work;
- N_word temp;
- N_word i,j;
-
- if (size > 0)
- {
- temp = 0xAAAA;
- i = BITS >> 4;
- while (--i > 0)
- {
- temp <<= 16;
- temp |= 0xAAAA;
- }
- i = size;
- work = addr;
- *work++ = temp XOR 0x0006;
- while (--i > 0) *work++ = temp;
- for ( i = 3; (j = i * i) < bits; i += 2 )
- {
- for ( ; j < bits; j += i ) BIT_VECTOR_CLR_BIT(addr,j)
- }
- *(addr+size-1) &= mask_(addr);
- }
-}
-
-void BitVector_Reverse(wordptr X, wordptr Y)
-{
- N_word bits = bits_(X);
- N_word mask;
- N_word bit;
- N_word value;
-
- if (bits > 0)
- {
- if (X == Y) BitVector_Interval_Reverse(X,0,bits-1);
- else if (bits == bits_(Y))
- {
-/* mask = mask_(Y); */
-/* mask &= NOT (mask >> 1); */
- mask = BITMASKTAB[(bits-1) AND MODMASK];
- Y += size_(Y) - 1;
- value = 0;
- bit = LSB;
- while (bits-- > 0)
- {
- if ((*Y AND mask) != 0)
- {
- value |= bit;
- }
- if (not (mask >>= 1))
- {
- Y--;
- mask = MSB;
- }
- if (not (bit <<= 1))
- {
- *X++ = value;
- value = 0;
- bit = LSB;
- }
- }
- if (bit > LSB) *X = value;
- }
- }
-}
-
-void BitVector_Interval_Empty(wordptr addr, N_int lower, N_int upper)
-{ /* X = X \ [lower..upper] */
- N_word bits = bits_(addr);
- N_word size = size_(addr);
- wordptr loaddr;
- wordptr hiaddr;
- N_word lobase;
- N_word hibase;
- N_word lomask;
- N_word himask;
- N_word diff;
-
- if ((size > 0) and (lower < bits) and (upper < bits) and (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (N_word) (~0L << (lower AND MODMASK));
- himask = (N_word) ~((~0L << (upper AND MODMASK)) << 1);
-
- if (diff == 0)
- {
- *loaddr &= NOT (lomask AND himask);
- }
- else
- {
- *loaddr++ &= NOT lomask;
- while (--diff > 0)
- {
- *loaddr++ = 0;
- }
- *hiaddr &= NOT himask;
- }
- }
-}
-
-void BitVector_Interval_Fill(wordptr addr, N_int lower, N_int upper)
-{ /* X = X + [lower..upper] */
- N_word bits = bits_(addr);
- N_word size = size_(addr);
- N_word fill = (N_word) ~0L;
- wordptr loaddr;
- wordptr hiaddr;
- N_word lobase;
- N_word hibase;
- N_word lomask;
- N_word himask;
- N_word diff;
-
- if ((size > 0) and (lower < bits) and (upper < bits) and (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (N_word) (~0L << (lower AND MODMASK));
- himask = (N_word) ~((~0L << (upper AND MODMASK)) << 1);
-
- if (diff == 0)
- {
- *loaddr |= (lomask AND himask);
- }
- else
- {
- *loaddr++ |= lomask;
- while (--diff > 0)
- {
- *loaddr++ = fill;
- }
- *hiaddr |= himask;
- }
- *(addr+size-1) &= mask_(addr);
- }
-}
-
-void BitVector_Interval_Flip(wordptr addr, N_int lower, N_int upper)
-{ /* X = X ^ [lower..upper] */
- N_word bits = bits_(addr);
- N_word size = size_(addr);
- N_word flip = (N_word) ~0L;
- wordptr loaddr;
- wordptr hiaddr;
- N_word lobase;
- N_word hibase;
- N_word lomask;
- N_word himask;
- N_word diff;
-
- if ((size > 0) and (lower < bits) and (upper < bits) and (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (N_word) (~0L << (lower AND MODMASK));
- himask = (N_word) ~((~0L << (upper AND MODMASK)) << 1);
-
- if (diff == 0)
- {
- *loaddr ^= (lomask AND himask);
- }
- else
- {
- *loaddr++ ^= lomask;
- while (--diff > 0)
- {
- *loaddr++ ^= flip;
- }
- *hiaddr ^= himask;
- }
- *(addr+size-1) &= mask_(addr);
- }
-}
-
-void BitVector_Interval_Reverse(wordptr addr, N_int lower, N_int upper)
-{
- N_word bits = bits_(addr);
- wordptr loaddr;
- wordptr hiaddr;
- N_word lomask;
- N_word himask;
-
- if ((bits > 0) and (lower < bits) and (upper < bits) and (lower < upper))
- {
- loaddr = addr + (lower >> LOGBITS);
- hiaddr = addr + (upper >> LOGBITS);
- lomask = BITMASKTAB[lower AND MODMASK];
- himask = BITMASKTAB[upper AND MODMASK];
- for ( bits = upper - lower + 1; bits > 1; bits -= 2 )
- {
- if (((*loaddr AND lomask) != 0) XOR ((*hiaddr AND himask) != 0))
- {
- *loaddr ^= lomask; /* swap bits only if they differ! */
- *hiaddr ^= himask;
- }
- if (not (lomask <<= 1))
- {
- lomask = LSB;
- loaddr++;
- }
- if (not (himask >>= 1))
- {
- himask = MSB;
- hiaddr--;
- }
- }
- }
-}
-
-boolean BitVector_interval_scan_inc(wordptr addr, N_int start,
- N_intptr min, N_intptr max)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word offset;
- N_word bitmask;
- N_word value;
- boolean empty;
-
- if ((size == 0) or (start >= bits_(addr))) return(FALSE);
-
- *min = start;
- *max = start;
-
- offset = start >> LOGBITS;
-
- *(addr+size-1) &= mask;
-
- addr += offset;
- size -= offset;
-
- bitmask = BITMASKTAB[start AND MODMASK];
- mask = NOT (bitmask OR (bitmask - 1));
-
- value = *addr++;
- if ((value AND bitmask) == 0)
- {
- value &= mask;
- if (value == 0)
- {
- offset++;
- empty = TRUE;
- while (empty and (--size > 0))
- {
- if ((value = *addr++)) empty = false; else offset++;
- }
- if (empty) return(FALSE);
- }
- start = offset << LOGBITS;
- bitmask = LSB;
- mask = value;
- while (not (mask AND LSB))
- {
- bitmask <<= 1;
- mask >>= 1;
- start++;
- }
- mask = NOT (bitmask OR (bitmask - 1));
- *min = start;
- *max = start;
- }
- value = NOT value;
- value &= mask;
- if (value == 0)
- {
- offset++;
- empty = TRUE;
- while (empty and (--size > 0))
- {
- if ((value = NOT *addr++)) empty = false; else offset++;
- }
- if (empty) value = LSB;
- }
- start = offset << LOGBITS;
- while (not (value AND LSB))
- {
- value >>= 1;
- start++;
- }
- *max = --start;
- return(TRUE);
-}
-
-boolean BitVector_interval_scan_dec(wordptr addr, N_int start,
- N_intptr min, N_intptr max)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word offset;
- N_word bitmask;
- N_word value;
- boolean empty;
-
- if ((size == 0) or (start >= bits_(addr))) return(FALSE);
-
- *min = start;
- *max = start;
-
- offset = start >> LOGBITS;
-
- if (offset >= size) return(FALSE);
-
- *(addr+size-1) &= mask;
-
- addr += offset;
- size = ++offset;
-
- bitmask = BITMASKTAB[start AND MODMASK];
- mask = (bitmask - 1);
-
- value = *addr--;
- if ((value AND bitmask) == 0)
- {
- value &= mask;
- if (value == 0)
- {
- offset--;
- empty = TRUE;
- while (empty and (--size > 0))
- {
- if ((value = *addr--)) empty = false; else offset--;
- }
- if (empty) return(FALSE);
- }
- start = offset << LOGBITS;
- bitmask = MSB;
- mask = value;
- while (not (mask AND MSB))
- {
- bitmask >>= 1;
- mask <<= 1;
- start--;
- }
- mask = (bitmask - 1);
- *max = --start;
- *min = start;
- }
- value = NOT value;
- value &= mask;
- if (value == 0)
- {
- offset--;
- empty = TRUE;
- while (empty and (--size > 0))
- {
- if ((value = NOT *addr--)) empty = false; else offset--;
- }
- if (empty) value = MSB;
- }
- start = offset << LOGBITS;
- while (not (value AND MSB))
- {
- value <<= 1;
- start--;
- }
- *min = start;
- return(TRUE);
-}
-
-void BitVector_Interval_Copy(wordptr X, wordptr Y, N_int Xoffset,
- N_int Yoffset, N_int length)
-{
- N_word bitsX = bits_(X);
- N_word bitsY = bits_(Y);
- N_word source = 0; /* silence compiler warning */
- N_word target = 0; /* silence compiler warning */
- N_word s_lo_base;
- N_word s_hi_base;
- N_word s_lo_bit;
- N_word s_hi_bit;
- N_word s_base;
- N_word s_lower = 0; /* silence compiler warning */
- N_word s_upper = 0; /* silence compiler warning */
- N_word s_bits;
- N_word s_min;
- N_word s_max;
- N_word t_lo_base;
- N_word t_hi_base;
- N_word t_lo_bit;
- N_word t_hi_bit;
- N_word t_base;
- N_word t_lower = 0; /* silence compiler warning */
- N_word t_upper = 0; /* silence compiler warning */
- N_word t_bits;
- N_word t_min;
- N_word mask;
- N_word bits;
- N_word select;
- boolean ascending;
- boolean notfirst;
- wordptr Z = X;
-
- if ((length > 0) and (Xoffset < bitsX) and (Yoffset < bitsY))
- {
- if ((Xoffset + length) > bitsX) length = bitsX - Xoffset;
- if ((Yoffset + length) > bitsY) length = bitsY - Yoffset;
-
- ascending = (Xoffset <= Yoffset);
-
- s_lo_base = Yoffset >> LOGBITS;
- s_lo_bit = Yoffset AND MODMASK;
- Yoffset += --length;
- s_hi_base = Yoffset >> LOGBITS;
- s_hi_bit = Yoffset AND MODMASK;
-
- t_lo_base = Xoffset >> LOGBITS;
- t_lo_bit = Xoffset AND MODMASK;
- Xoffset += length;
- t_hi_base = Xoffset >> LOGBITS;
- t_hi_bit = Xoffset AND MODMASK;
-
- if (ascending)
- {
- s_base = s_lo_base;
- t_base = t_lo_base;
- }
- else
- {
- s_base = s_hi_base;
- t_base = t_hi_base;
- }
- s_bits = 0;
- t_bits = 0;
- Y += s_base;
- X += t_base;
- notfirst = FALSE;
- while (TRUE)
- {
- if (t_bits == 0)
- {
- if (notfirst)
- {
- *X = target;
- if (ascending)
- {
- if (t_base == t_hi_base) break;
- t_base++;
- X++;
- }
- else
- {
- if (t_base == t_lo_base) break;
- t_base--;
- X--;
- }
- }
- select = ((t_base == t_hi_base) << 1) OR (t_base == t_lo_base);
- switch (select)
- {
- case 0:
- t_lower = 0;
- t_upper = BITS - 1;
- t_bits = BITS;
- target = 0;
- break;
- case 1:
- t_lower = t_lo_bit;
- t_upper = BITS - 1;
- t_bits = BITS - t_lo_bit;
- mask = (N_word) (~0L << t_lower);
- target = *X AND NOT mask;
- break;
- case 2:
- t_lower = 0;
- t_upper = t_hi_bit;
- t_bits = t_hi_bit + 1;
- mask = (N_word) ((~0L << t_upper) << 1);
- target = *X AND mask;
- break;
- case 3:
- t_lower = t_lo_bit;
- t_upper = t_hi_bit;
- t_bits = t_hi_bit - t_lo_bit + 1;
- mask = (N_word) (~0L << t_lower);
- mask &= (N_word) ~((~0L << t_upper) << 1);
- target = *X AND NOT mask;
- break;
- }
- }
- if (s_bits == 0)
- {
- if (notfirst)
- {
- if (ascending)
- {
- if (s_base == s_hi_base) break;
- s_base++;
- Y++;
- }
- else
- {
- if (s_base == s_lo_base) break;
- s_base--;
- Y--;
- }
- }
- source = *Y;
- select = ((s_base == s_hi_base) << 1) OR (s_base == s_lo_base);
- switch (select)
- {
- case 0:
- s_lower = 0;
- s_upper = BITS - 1;
- s_bits = BITS;
- break;
- case 1:
- s_lower = s_lo_bit;
- s_upper = BITS - 1;
- s_bits = BITS - s_lo_bit;
- break;
- case 2:
- s_lower = 0;
- s_upper = s_hi_bit;
- s_bits = s_hi_bit + 1;
- break;
- case 3:
- s_lower = s_lo_bit;
- s_upper = s_hi_bit;
- s_bits = s_hi_bit - s_lo_bit + 1;
- break;
- }
- }
- notfirst = TRUE;
- if (s_bits > t_bits)
- {
- bits = t_bits - 1;
- if (ascending)
- {
- s_min = s_lower;
- s_max = s_lower + bits;
- }
- else
- {
- s_max = s_upper;
- s_min = s_upper - bits;
- }
- t_min = t_lower;
- }
- else
- {
- bits = s_bits - 1;
- if (ascending) t_min = t_lower;
- else t_min = t_upper - bits;
- s_min = s_lower;
- s_max = s_upper;
- }
- bits++;
- mask = (N_word) (~0L << s_min);
- mask &= (N_word) ~((~0L << s_max) << 1);
- if (s_min == t_min) target |= (source AND mask);
- else
- {
- if (s_min < t_min) target |= (source AND mask) << (t_min-s_min);
- else target |= (source AND mask) >> (s_min-t_min);
- }
- if (ascending)
- {
- s_lower += bits;
- t_lower += bits;
- }
- else
- {
- s_upper -= bits;
- t_upper -= bits;
- }
- s_bits -= bits;
- t_bits -= bits;
- }
- *(Z+size_(Z)-1) &= mask_(Z);
- }
-}
-
-
-wordptr BitVector_Interval_Substitute(wordptr X, wordptr Y,
- N_int Xoffset, N_int Xlength,
- N_int Yoffset, N_int Ylength)
-{
- N_word Xbits = bits_(X);
- N_word Ybits = bits_(Y);
- N_word limit;
- N_word diff;
-
- if ((Xoffset <= Xbits) and (Yoffset <= Ybits))
- {
- limit = Xoffset + Xlength;
- if (limit > Xbits)
- {
- limit = Xbits;
- Xlength = Xbits - Xoffset;
- }
- if ((Yoffset + Ylength) > Ybits)
- {
- Ylength = Ybits - Yoffset;
- }
- if (Xlength == Ylength)
- {
- if ((Ylength > 0) and ((X != Y) or (Xoffset != Yoffset)))
- {
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- }
- else /* Xlength != Ylength */
- {
- if (Xlength > Ylength)
- {
- diff = Xlength - Ylength;
- if (Ylength > 0) BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- if (limit < Xbits) BitVector_Delete(X,Xoffset+Ylength,diff,FALSE);
- if ((X = BitVector_Resize(X,Xbits-diff)) == NULL) return(NULL);
- }
- else /* Ylength > Xlength ==> Ylength > 0 */
- {
- diff = Ylength - Xlength;
- if (X != Y)
- {
- if ((X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
- if (limit < Xbits) BitVector_Insert(X,limit,diff,FALSE);
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- else /* in-place */
- {
- if ((Y = X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
- if (limit >= Xbits)
- {
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- else /* limit < Xbits */
- {
- BitVector_Insert(X,limit,diff,FALSE);
- if ((Yoffset+Ylength) <= limit)
- {
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- else /* overlaps or lies above critical area */
- {
- if (limit <= Yoffset)
- {
- Yoffset += diff;
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- else /* Yoffset < limit */
- {
- Xlength = limit - Yoffset;
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Xlength);
- Yoffset = Xoffset + Ylength; /* = limit + diff */
- Xoffset += Xlength;
- Ylength -= Xlength;
- BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
- }
- }
- }
- }
- }
- }
- }
- return(X);
-}
-
-boolean BitVector_is_empty(wordptr addr) /* X == {} ? */
-{
- N_word size = size_(addr);
- boolean r = TRUE;
-
- if (size > 0)
- {
- *(addr+size-1) &= mask_(addr);
- while (r and (size-- > 0)) r = ( *addr++ == 0 );
- }
- return(r);
-}
-
-boolean BitVector_is_full(wordptr addr) /* X == ~{} ? */
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- boolean r = FALSE;
- wordptr last;
-
- if (size > 0)
- {
- r = TRUE;
- last = addr + size - 1;
- *last |= NOT mask;
- while (r and (size-- > 0)) r = ( NOT *addr++ == 0 );
- *last &= mask;
- }
- return(r);
-}
-
-boolean BitVector_equal(wordptr X, wordptr Y) /* X == Y ? */
-{
- N_word size = size_(X);
- N_word mask = mask_(X);
- boolean r = FALSE;
-
- if (bits_(X) == bits_(Y))
- {
- r = TRUE;
- if (size > 0)
- {
- *(X+size-1) &= mask;
- *(Y+size-1) &= mask;
- while (r and (size-- > 0)) r = (*X++ == *Y++);
- }
- }
- return(r);
-}
-
-Z_int BitVector_Lexicompare(wordptr X, wordptr Y) /* X <,=,> Y ? */
-{ /* unsigned */
- N_word bitsX = bits_(X);
- N_word bitsY = bits_(Y);
- N_word size = size_(X);
- boolean r = TRUE;
-
- if (bitsX == bitsY)
- {
- if (size > 0)
- {
- X += size;
- Y += size;
- while (r and (size-- > 0)) r = (*(--X) == *(--Y));
- }
- if (r) return((Z_int) 0);
- else
- {
- if (*X < *Y) return((Z_int) -1); else return((Z_int) 1);
- }
- }
- else
- {
- if (bitsX < bitsY) return((Z_int) -1); else return((Z_int) 1);
- }
-}
-
-Z_int BitVector_Compare(wordptr X, wordptr Y) /* X <,=,> Y ? */
-{ /* signed */
- N_word bitsX = bits_(X);
- N_word bitsY = bits_(Y);
- N_word size = size_(X);
- N_word mask = mask_(X);
- N_word sign;
- boolean r = TRUE;
-
- if (bitsX == bitsY)
- {
- if (size > 0)
- {
- X += size;
- Y += size;
- mask &= NOT (mask >> 1);
- if ((sign = (*(X-1) AND mask)) != (*(Y-1) AND mask))
- {
- if (sign) return((Z_int) -1); else return((Z_int) 1);
- }
- while (r and (size-- > 0)) r = (*(--X) == *(--Y));
- }
- if (r) return((Z_int) 0);
- else
- {
- if (*X < *Y) return((Z_int) -1); else return((Z_int) 1);
- }
- }
- else
- {
- if (bitsX < bitsY) return((Z_int) -1); else return((Z_int) 1);
- }
-}
-
-charptr BitVector_to_Hex(wordptr addr)
-{
- N_word bits = bits_(addr);
- N_word size = size_(addr);
- N_word value;
- N_word count;
- N_word digit;
- N_word length;
- charptr string;
-
- length = bits >> 2;
- if (bits AND 0x0003) length++;
- string = (charptr) yasm_xmalloc((size_t) (length+1));
- if (string == NULL) return(NULL);
- string += length;
- *string = (N_char) '\0';
- if (size > 0)
- {
- *(addr+size-1) &= mask_(addr);
- while ((size-- > 0) and (length > 0))
- {
- value = *addr++;
- count = BITS >> 2;
- while ((count-- > 0) and (length > 0))
- {
- digit = value AND 0x000F;
- if (digit > 9) digit += (N_word) 'A' - 10;
- else digit += (N_word) '0';
- *(--string) = (N_char) digit; length--;
- if ((count > 0) and (length > 0)) value >>= 4;
- }
- }
- }
- return(string);
-}
-
-ErrCode BitVector_from_Hex(wordptr addr, charptr string)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- boolean ok = TRUE;
- N_word length;
- N_word value;
- N_word count;
- int digit;
-
- if (size > 0)
- {
- length = strlen((char *) string);
- string += length;
- while (size-- > 0)
- {
- value = 0;
- for ( count = 0; (ok and (length > 0) and (count < BITS)); count += 4 )
- {
- digit = (int) *(--string); length--;
- /* separate because toupper() is likely a macro! */
- digit = toupper(digit);
- if ((ok = (isxdigit(digit) != 0)))
- {
- if (digit >= (int) 'A') digit -= (int) 'A' - 10;
- else digit -= (int) '0';
- value |= (((N_word) digit) << count);
- }
- }
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
- if (ok) return(ErrCode_Ok);
- else return(ErrCode_Pars);
-}
-
-ErrCode BitVector_from_Oct(wordptr addr, charptr string)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- boolean ok = TRUE;
- N_word length;
- N_word value;
- N_word value_fill = 0;
- N_word count;
- Z_word count_fill = 0;
- int digit = 0;
-
- if (size > 0)
- {
- length = strlen((char *) string);
- string += length;
- while (size-- > 0)
- {
- value = value_fill;
- for ( count = count_fill; (ok and (length > 0) and (count < BITS)); count += 3 )
- {
- digit = (int) *(--string); length--;
- if ((ok = (isdigit(digit) && digit != '8' && digit != '9')) != 0)
- {
- digit -= (int) '0';
- value |= (((N_word) digit) << count);
- }
- }
- count_fill = (Z_word)count-(Z_word)BITS;
- if (count_fill > 0)
- value_fill = (((N_word) digit) >> (3-count_fill));
- else
- value_fill = 0;
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
- if (ok) return(ErrCode_Ok);
- else return(ErrCode_Pars);
-}
-
-charptr BitVector_to_Bin(wordptr addr)
-{
- N_word size = size_(addr);
- N_word value;
- N_word count;
- N_word digit;
- N_word length;
- charptr string;
-
- length = bits_(addr);
- string = (charptr) yasm_xmalloc((size_t) (length+1));
- if (string == NULL) return(NULL);
- string += length;
- *string = (N_char) '\0';
- if (size > 0)
- {
- *(addr+size-1) &= mask_(addr);
- while (size-- > 0)
- {
- value = *addr++;
- count = BITS;
- if (count > length) count = length;
- while (count-- > 0)
- {
- digit = value AND 0x0001;
- digit += (N_word) '0';
- *(--string) = (N_char) digit; length--;
- if (count > 0) value >>= 1;
- }
- }
- }
- return(string);
-}
-
-ErrCode BitVector_from_Bin(wordptr addr, charptr string)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- boolean ok = TRUE;
- N_word length;
- N_word value;
- N_word count;
- int digit;
-
- if (size > 0)
- {
- length = strlen((char *) string);
- string += length;
- while (size-- > 0)
- {
- value = 0;
- for ( count = 0; (ok and (length > 0) and (count < BITS)); count++ )
- {
- digit = (int) *(--string); length--;
- switch (digit)
- {
- case (int) '0':
- break;
- case (int) '1':
- value |= BITMASKTAB[count];
- break;
- default:
- ok = FALSE;
- break;
- }
- }
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
- if (ok) return(ErrCode_Ok);
- else return(ErrCode_Pars);
-}
-
-charptr BitVector_to_Dec(wordptr addr)
-{
- N_word bits = bits_(addr);
- N_word length;
- N_word digits;
- N_word count;
- N_word q;
- N_word r;
- boolean loop;
- charptr result;
- charptr string;
- wordptr quot;
- wordptr rest;
- wordptr temp;
- wordptr base;
- Z_int sign;
-
- length = (N_word) (bits / 3.3); /* digits = bits * ln(2) / ln(10) */
- length += 2; /* compensate for truncating & provide space for minus sign */
- result = (charptr) yasm_xmalloc((size_t) (length+1)); /* remember the '\0'! */
- if (result == NULL) return(NULL);
- string = result;
- sign = BitVector_Sign(addr);
- if ((bits < 4) or (sign == 0))
- {
- if (bits > 0) digits = *addr; else digits = (N_word) 0;
- if (sign < 0) digits = ((N_word)(-((Z_word)digits))) AND mask_(addr);
- *string++ = (N_char) digits + (N_char) '0';
- digits = 1;
- }
- else
- {
- quot = BitVector_Create(bits,FALSE);
- if (quot == NULL)
- {
- BitVector_Dispose(result);
- return(NULL);
- }
- rest = BitVector_Create(bits,FALSE);
- if (rest == NULL)
- {
- BitVector_Dispose(result);
- BitVector_Destroy(quot);
- return(NULL);
- }
- temp = BitVector_Create(bits,FALSE);
- if (temp == NULL)
- {
- BitVector_Dispose(result);
- BitVector_Destroy(quot);
- BitVector_Destroy(rest);
- return(NULL);
- }
- base = BitVector_Create(bits,TRUE);
- if (base == NULL)
- {
- BitVector_Dispose(result);
- BitVector_Destroy(quot);
- BitVector_Destroy(rest);
- BitVector_Destroy(temp);
- return(NULL);
- }
- if (sign < 0) BitVector_Negate(quot,addr);
- else BitVector_Copy(quot,addr);
- digits = 0;
- *base = EXP10;
- loop = (bits >= BITS);
- do
- {
- if (loop)
- {
- BitVector_Copy(temp,quot);
- if (BitVector_Div_Pos(quot,temp,base,rest))
- {
- BitVector_Dispose(result); /* emergency exit */
- BitVector_Destroy(quot);
- BitVector_Destroy(rest); /* should never occur */
- BitVector_Destroy(temp); /* under normal operation */
- BitVector_Destroy(base);
- return(NULL);
- }
- loop = not BitVector_is_empty(quot);
- q = *rest;
- }
- else q = *quot;
- count = LOG10;
- while (((loop and (count-- > 0)) or ((not loop) and (q != 0))) and
- (digits < length))
- {
- if (q != 0)
- {
- BIT_VECTOR_DIGITIZE(N_word,q,r)
- }
- else r = (N_word) '0';
- *string++ = (N_char) r;
- digits++;
- }
- }
- while (loop and (digits < length));
- BitVector_Destroy(quot);
- BitVector_Destroy(rest);
- BitVector_Destroy(temp);
- BitVector_Destroy(base);
- }
- if ((sign < 0) and (digits < length))
- {
- *string++ = (N_char) '-';
- digits++;
- }
- *string = (N_char) '\0';
- BIT_VECTOR_reverse(result,digits);
- return(result);
-}
-
-static wordptr from_Dec_term = NULL;
-static wordptr from_Dec_base = NULL;
-static wordptr from_Dec_prod = NULL;
-static wordptr from_Dec_rank = NULL;
-static wordptr from_Dec_temp = NULL;
-
-ErrCode BitVector_from_Dec_static_Boot(N_word bits)
-{
- if (bits > 0)
- {
- BitVector_from_Dec_static_Shutdown();
- from_Dec_term = BitVector_Create(BITS,FALSE);
- if (from_Dec_term == NULL)
- {
- return(ErrCode_Null);
- }
- from_Dec_base = BitVector_Create(BITS,FALSE);
- if (from_Dec_base == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- return(ErrCode_Null);
- }
- from_Dec_prod = BitVector_Create(bits,FALSE);
- if (from_Dec_prod == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- return(ErrCode_Null);
- }
- from_Dec_rank = BitVector_Create(bits,FALSE);
- if (from_Dec_rank == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- BitVector_Destroy(from_Dec_prod);
- return(ErrCode_Null);
- }
- from_Dec_temp = BitVector_Create(bits,FALSE);
- if (from_Dec_temp == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- BitVector_Destroy(from_Dec_prod);
- BitVector_Destroy(from_Dec_rank);
- return(ErrCode_Null);
- }
- }
- return(ErrCode_Ok);
-}
-
-void BitVector_from_Dec_static_Shutdown(void)
-{
- if (from_Dec_term != NULL)
- BitVector_Destroy(from_Dec_term);
- if (from_Dec_base != NULL)
- BitVector_Destroy(from_Dec_base);
- if (from_Dec_prod != NULL)
- BitVector_Destroy(from_Dec_prod);
- if (from_Dec_rank != NULL)
- BitVector_Destroy(from_Dec_rank);
- if (from_Dec_temp != NULL)
- BitVector_Destroy(from_Dec_temp);
-}
-
-ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(addr);
- N_word mask = mask_(addr);
- boolean init = (bits > BITS);
- boolean minus;
- boolean shift;
- boolean carry;
- wordptr term = from_Dec_term;
- wordptr base = from_Dec_base;
- wordptr prod = from_Dec_prod;
- wordptr rank = from_Dec_rank;
- wordptr temp = from_Dec_temp;
- N_word accu;
- N_word powr;
- N_word count;
- N_word length;
- int digit;
-
- if (bits > 0)
- {
- length = strlen((char *) string);
- if (length == 0) return(ErrCode_Pars);
- digit = (int) *string;
- if ((minus = (digit == (int) '-')) or
- (digit == (int) '+'))
- {
- string++;
- if (--length == 0) return(ErrCode_Pars);
- }
- string += length;
- if (init)
- {
- BitVector_Empty(prod);
- BitVector_Empty(rank);
- }
- BitVector_Empty(addr);
- *base = EXP10;
- shift = FALSE;
- while ((not error) and (length > 0))
- {
- accu = 0;
- powr = 1;
- count = LOG10;
- while ((not error) and (length > 0) and (count-- > 0))
- {
- digit = (int) *(--string); length--;
- /* separate because isdigit() is likely a macro! */
- if (isdigit(digit) != 0)
- {
- accu += ((N_word) digit - (N_word) '0') * powr;
- powr *= 10;
- }
- else error = ErrCode_Pars;
- }
- if (not error)
- {
- if (shift)
- {
- *term = accu;
- BitVector_Copy(temp,rank);
- error = BitVector_Mul_Pos(prod,temp,term,FALSE);
- }
- else
- {
- *prod = accu;
- if ((not init) and ((accu AND NOT mask) != 0)) error = ErrCode_Ovfl;
- }
- if (not error)
- {
- carry = FALSE;
- BitVector_compute(addr,addr,prod,FALSE,&carry);
- /* ignores sign change (= overflow) but not */
- /* numbers too large (= carry) for resulting bit vector */
- if (carry) error = ErrCode_Ovfl;
- else
- {
- if (length > 0)
- {
- if (shift)
- {
- BitVector_Copy(temp,rank);
- error = BitVector_Mul_Pos(rank,temp,base,FALSE);
- }
- else
- {
- *rank = *base;
- shift = TRUE;
- }
- }
- }
- }
- }
- }
- if (not error and minus)
- {
- BitVector_Negate(addr,addr);
- if ((*(addr + size_(addr) - 1) AND mask AND NOT (mask >> 1)) == 0)
- error = ErrCode_Ovfl;
- }
- }
- return(error);
-}
-
-ErrCode BitVector_from_Dec(wordptr addr, charptr string)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(addr);
- N_word mask = mask_(addr);
- boolean init = (bits > BITS);
- boolean minus;
- boolean shift;
- boolean carry;
- wordptr term;
- wordptr base;
- wordptr prod;
- wordptr rank;
- wordptr temp;
- N_word accu;
- N_word powr;
- N_word count;
- N_word length;
- int digit;
-
- if (bits > 0)
- {
- length = strlen((char *) string);
- if (length == 0) return(ErrCode_Pars);
- digit = (int) *string;
- if ((minus = (digit == (int) '-')) or
- (digit == (int) '+'))
- {
- string++;
- if (--length == 0) return(ErrCode_Pars);
- }
- string += length;
- term = BitVector_Create(BITS,FALSE);
- if (term == NULL)
- {
- return(ErrCode_Null);
- }
- base = BitVector_Create(BITS,FALSE);
- if (base == NULL)
- {
- BitVector_Destroy(term);
- return(ErrCode_Null);
- }
- prod = BitVector_Create(bits,init);
- if (prod == NULL)
- {
- BitVector_Destroy(term);
- BitVector_Destroy(base);
- return(ErrCode_Null);
- }
- rank = BitVector_Create(bits,init);
- if (rank == NULL)
- {
- BitVector_Destroy(term);
- BitVector_Destroy(base);
- BitVector_Destroy(prod);
- return(ErrCode_Null);
- }
- temp = BitVector_Create(bits,FALSE);
- if (temp == NULL)
- {
- BitVector_Destroy(term);
- BitVector_Destroy(base);
- BitVector_Destroy(prod);
- BitVector_Destroy(rank);
- return(ErrCode_Null);
- }
- BitVector_Empty(addr);
- *base = EXP10;
- shift = FALSE;
- while ((not error) and (length > 0))
- {
- accu = 0;
- powr = 1;
- count = LOG10;
- while ((not error) and (length > 0) and (count-- > 0))
- {
- digit = (int) *(--string); length--;
- /* separate because isdigit() is likely a macro! */
- if (isdigit(digit) != 0)
- {
- accu += ((N_word) digit - (N_word) '0') * powr;
- powr *= 10;
- }
- else error = ErrCode_Pars;
- }
- if (not error)
- {
- if (shift)
- {
- *term = accu;
- BitVector_Copy(temp,rank);
- error = BitVector_Mul_Pos(prod,temp,term,FALSE);
- }
- else
- {
- *prod = accu;
- if ((not init) and ((accu AND NOT mask) != 0)) error = ErrCode_Ovfl;
- }
- if (not error)
- {
- carry = FALSE;
- BitVector_compute(addr,addr,prod,FALSE,&carry);
- /* ignores sign change (= overflow) but not */
- /* numbers too large (= carry) for resulting bit vector */
- if (carry) error = ErrCode_Ovfl;
- else
- {
- if (length > 0)
- {
- if (shift)
- {
- BitVector_Copy(temp,rank);
- error = BitVector_Mul_Pos(rank,temp,base,FALSE);
- }
- else
- {
- *rank = *base;
- shift = TRUE;
- }
- }
- }
- }
- }
- }
- BitVector_Destroy(term);
- BitVector_Destroy(base);
- BitVector_Destroy(prod);
- BitVector_Destroy(rank);
- BitVector_Destroy(temp);
- if (not error and minus)
- {
- BitVector_Negate(addr,addr);
- if ((*(addr + size_(addr) - 1) AND mask AND NOT (mask >> 1)) == 0)
- error = ErrCode_Ovfl;
- }
- }
- return(error);
-}
-
-charptr BitVector_to_Enum(wordptr addr)
-{
- N_word bits = bits_(addr);
- N_word sample;
- N_word length;
- N_word digits;
- N_word factor;
- N_word power;
- N_word start;
- N_word min;
- N_word max;
- charptr string;
- charptr target;
- boolean comma;
-
- if (bits > 0)
- {
- sample = bits - 1; /* greatest possible index */
- length = 2; /* account for index 0 and terminating '\0' */
- digits = 1; /* account for intervening dashes and commas */
- factor = 1;
- power = 10;
- while (sample >= (power-1))
- {
- length += ++digits * factor * 6; /* 9,90,900,9000,... (9*2/3 = 6) */
- factor = power;
- power *= 10;
- }
- if (sample > --factor)
- {
- sample -= factor;
- factor = (N_word) ( sample / 3 );
- factor = (factor << 1) + (sample - (factor * 3));
- length += ++digits * factor;
- }
- }
- else length = 1;
- string = (charptr) yasm_xmalloc((size_t) length);
- if (string == NULL) return(NULL);
- start = 0;
- comma = FALSE;
- target = string;
- while ((start < bits) and BitVector_interval_scan_inc(addr,start,&min,&max))
- {
- start = max + 2;
- if (comma) *target++ = (N_char) ',';
- if (min == max)
- {
- target += BIT_VECTOR_int2str(target,min);
- }
- else
- {
- if (min+1 == max)
- {
- target += BIT_VECTOR_int2str(target,min);
- *target++ = (N_char) ',';
- target += BIT_VECTOR_int2str(target,max);
- }
- else
- {
- target += BIT_VECTOR_int2str(target,min);
- *target++ = (N_char) '-';
- target += BIT_VECTOR_int2str(target,max);
- }
- }
- comma = TRUE;
- }
- *target = (N_char) '\0';
- return(string);
-}
-
-ErrCode BitVector_from_Enum(wordptr addr, charptr string)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(addr);
- N_word state = 1;
- N_word token;
- N_word indx;
- N_word start = 0; /* silence compiler warning */
-
- if (bits > 0)
- {
- BitVector_Empty(addr);
- while ((not error) and (state != 0))
- {
- token = (N_word) *string;
- /* separate because isdigit() is likely a macro! */
- if (isdigit((int)token) != 0)
- {
- string += BIT_VECTOR_str2int(string,&indx);
- if (indx < bits) token = (N_word) '0';
- else error = ErrCode_Indx;
- }
- else string++;
- if (not error)
- switch (state)
- {
- case 1:
- switch (token)
- {
- case (N_word) '0':
- state = 2;
- break;
- case (N_word) '\0':
- state = 0;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 2:
- switch (token)
- {
- case (N_word) '-':
- start = indx;
- state = 3;
- break;
- case (N_word) ',':
- BIT_VECTOR_SET_BIT(addr,indx)
- state = 5;
- break;
- case (N_word) '\0':
- BIT_VECTOR_SET_BIT(addr,indx)
- state = 0;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 3:
- switch (token)
- {
- case (N_word) '0':
- if (start < indx)
- BitVector_Interval_Fill(addr,start,indx);
- else if (start == indx)
- BIT_VECTOR_SET_BIT(addr,indx)
- else error = ErrCode_Ordr;
- state = 4;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 4:
- switch (token)
- {
- case (N_word) ',':
- state = 5;
- break;
- case (N_word) '\0':
- state = 0;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 5:
- switch (token)
- {
- case (N_word) '0':
- state = 2;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- }
- }
- }
- return(error);
-}
-
-void BitVector_Bit_Off(wordptr addr, N_int indx) /* X = X \ {x} */
-{
- if (indx < bits_(addr)) BIT_VECTOR_CLR_BIT(addr,indx)
-}
-
-void BitVector_Bit_On(wordptr addr, N_int indx) /* X = X + {x} */
-{
- if (indx < bits_(addr)) BIT_VECTOR_SET_BIT(addr,indx)
-}
-
-boolean BitVector_bit_flip(wordptr addr, N_int indx) /* X=(X+{x})\(X*{x}) */
-{
- N_word mask;
-
- if (indx < bits_(addr)) return( BIT_VECTOR_FLP_BIT(addr,indx,mask) );
- else return( FALSE );
-}
-
-boolean BitVector_bit_test(wordptr addr, N_int indx) /* {x} in X ? */
-{
- if (indx < bits_(addr)) return( BIT_VECTOR_TST_BIT(addr,indx) );
- else return( FALSE );
-}
-
-void BitVector_Bit_Copy(wordptr addr, N_int indx, boolean bit)
-{
- if (indx < bits_(addr))
- {
- if (bit) BIT_VECTOR_SET_BIT(addr,indx)
- else BIT_VECTOR_CLR_BIT(addr,indx)
- }
-}
-
-void BitVector_LSB(wordptr addr, boolean bit)
-{
- if (bits_(addr) > 0)
- {
- if (bit) *addr |= LSB;
- else *addr &= NOT LSB;
- }
-}
-
-void BitVector_MSB(wordptr addr, boolean bit)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
-
- if (size-- > 0)
- {
- if (bit) *(addr+size) |= mask AND NOT (mask >> 1);
- else *(addr+size) &= NOT mask OR (mask >> 1);
- }
-}
-
-boolean BitVector_lsb_(wordptr addr)
-{
- if (size_(addr) > 0) return( (*addr AND LSB) != 0 );
- else return( FALSE );
-}
-
-boolean BitVector_msb_(wordptr addr)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
-
- if (size-- > 0)
- return( (*(addr+size) AND (mask AND NOT (mask >> 1))) != 0 );
- else
- return( FALSE );
-}
-
-boolean BitVector_rotate_left(wordptr addr)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word msb;
- boolean carry_in;
- boolean carry_out = FALSE;
-
- if (size > 0)
- {
- msb = mask AND NOT (mask >> 1);
- carry_in = ((*(addr+size-1) AND msb) != 0);
- while (size-- > 1)
- {
- carry_out = ((*addr AND MSB) != 0);
- *addr <<= 1;
- if (carry_in) *addr |= LSB;
- carry_in = carry_out;
- addr++;
- }
- carry_out = ((*addr AND msb) != 0);
- *addr <<= 1;
- if (carry_in) *addr |= LSB;
- *addr &= mask;
- }
- return(carry_out);
-}
-
-boolean BitVector_rotate_right(wordptr addr)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word msb;
- boolean carry_in;
- boolean carry_out = FALSE;
-
- if (size > 0)
- {
- msb = mask AND NOT (mask >> 1);
- carry_in = ((*addr AND LSB) != 0);
- addr += size-1;
- *addr &= mask;
- carry_out = ((*addr AND LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= msb;
- carry_in = carry_out;
- addr--;
- size--;
- while (size-- > 0)
- {
- carry_out = ((*addr AND LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= MSB;
- carry_in = carry_out;
- addr--;
- }
- }
- return(carry_out);
-}
-
-boolean BitVector_shift_left(wordptr addr, boolean carry_in)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word msb;
- boolean carry_out = carry_in;
-
- if (size > 0)
- {
- msb = mask AND NOT (mask >> 1);
- while (size-- > 1)
- {
- carry_out = ((*addr AND MSB) != 0);
- *addr <<= 1;
- if (carry_in) *addr |= LSB;
- carry_in = carry_out;
- addr++;
- }
- carry_out = ((*addr AND msb) != 0);
- *addr <<= 1;
- if (carry_in) *addr |= LSB;
- *addr &= mask;
- }
- return(carry_out);
-}
-
-boolean BitVector_shift_right(wordptr addr, boolean carry_in)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word msb;
- boolean carry_out = carry_in;
-
- if (size > 0)
- {
- msb = mask AND NOT (mask >> 1);
- addr += size-1;
- *addr &= mask;
- carry_out = ((*addr AND LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= msb;
- carry_in = carry_out;
- addr--;
- size--;
- while (size-- > 0)
- {
- carry_out = ((*addr AND LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= MSB;
- carry_in = carry_out;
- addr--;
- }
- }
- return(carry_out);
-}
-
-void BitVector_Move_Left(wordptr addr, N_int bits)
-{
- N_word count;
- N_word words;
-
- if (bits > 0)
- {
- count = bits AND MODMASK;
- words = bits >> LOGBITS;
- if (bits >= bits_(addr)) BitVector_Empty(addr);
- else
- {
- while (count-- > 0) BitVector_shift_left(addr,0);
- BitVector_Word_Insert(addr,0,words,TRUE);
- }
- }
-}
-
-void BitVector_Move_Right(wordptr addr, N_int bits)
-{
- N_word count;
- N_word words;
-
- if (bits > 0)
- {
- count = bits AND MODMASK;
- words = bits >> LOGBITS;
- if (bits >= bits_(addr)) BitVector_Empty(addr);
- else
- {
- while (count-- > 0) BitVector_shift_right(addr,0);
- BitVector_Word_Delete(addr,0,words,TRUE);
- }
- }
-}
-
-void BitVector_Insert(wordptr addr, N_int offset, N_int count, boolean clear)
-{
- N_word bits = bits_(addr);
- N_word last;
-
- if ((count > 0) and (offset < bits))
- {
- last = offset + count;
- if (last < bits)
- {
- BitVector_Interval_Copy(addr,addr,last,offset,(bits-last));
- }
- else last = bits;
- if (clear) BitVector_Interval_Empty(addr,offset,(last-1));
- }
-}
-
-void BitVector_Delete(wordptr addr, N_int offset, N_int count, boolean clear)
-{
- N_word bits = bits_(addr);
- N_word last;
-
- if ((count > 0) and (offset < bits))
- {
- last = offset + count;
- if (last < bits)
- {
- BitVector_Interval_Copy(addr,addr,offset,last,(bits-last));
- }
- else count = bits - offset;
- if (clear) BitVector_Interval_Empty(addr,(bits-count),(bits-1));
- }
-}
-
-boolean BitVector_increment(wordptr addr) /* X++ */
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- wordptr last = addr + size - 1;
- boolean carry = TRUE;
-
- if (size > 0)
- {
- *last |= NOT mask;
- while (carry and (size-- > 0))
- {
- carry = (++(*addr++) == 0);
- }
- *last &= mask;
- }
- return(carry);
-}
-
-boolean BitVector_decrement(wordptr addr) /* X-- */
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- wordptr last = addr + size - 1;
- boolean carry = TRUE;
-
- if (size > 0)
- {
- *last &= mask;
- while (carry and (size-- > 0))
- {
- carry = (*addr == 0);
- --(*addr++);
- }
- *last &= mask;
- }
- return(carry);
-}
-
-boolean BitVector_compute(wordptr X, wordptr Y, wordptr Z, boolean minus, boolean *carry)
-{
- N_word size = size_(X);
- N_word mask = mask_(X);
- N_word vv = 0;
- N_word cc;
- N_word mm;
- N_word yy;
- N_word zz;
- N_word lo;
- N_word hi;
-
- if (size > 0)
- {
- if (minus) cc = (*carry == 0);
- else cc = (*carry != 0);
- /* deal with (size-1) least significant full words first: */
- while (--size > 0)
- {
- yy = *Y++;
- if (minus) zz = (N_word) NOT ( Z ? *Z++ : 0 );
- else zz = (N_word) ( Z ? *Z++ : 0 );
- lo = (yy AND LSB) + (zz AND LSB) + cc;
- hi = (yy >> 1) + (zz >> 1) + (lo >> 1);
- cc = ((hi AND MSB) != 0);
- *X++ = (hi << 1) OR (lo AND LSB);
- }
- /* deal with most significant word (may be used only partially): */
- yy = *Y AND mask;
- if (minus) zz = (N_word) NOT ( Z ? *Z : 0 );
- else zz = (N_word) ( Z ? *Z : 0 );
- zz &= mask;
- if (mask == LSB) /* special case, only one bit used */
- {
- vv = cc;
- lo = yy + zz + cc;
- cc = (lo >> 1);
- vv ^= cc;
- *X = lo AND LSB;
- }
- else
- {
- if (NOT mask) /* not all bits are used, but more than one */
- {
- mm = (mask >> 1);
- vv = (yy AND mm) + (zz AND mm) + cc;
- mm = mask AND NOT mm;
- lo = yy + zz + cc;
- cc = (lo >> 1);
- vv ^= cc;
- vv &= mm;
- cc &= mm;
- *X = lo AND mask;
- }
- else /* other special case, all bits are used */
- {
- mm = NOT MSB;
- lo = (yy AND mm) + (zz AND mm) + cc;
- vv = lo AND MSB;
- hi = ((yy AND MSB) >> 1) + ((zz AND MSB) >> 1) + (vv >> 1);
- cc = hi AND MSB;
- vv ^= cc;
- *X = (hi << 1) OR (lo AND mm);
- }
- }
- if (minus) *carry = (cc == 0);
- else *carry = (cc != 0);
- }
- return(vv != 0);
-}
-
-boolean BitVector_add(wordptr X, wordptr Y, wordptr Z, boolean *carry)
-{
- return(BitVector_compute(X,Y,Z,FALSE,carry));
-}
-
-boolean BitVector_sub(wordptr X, wordptr Y, wordptr Z, boolean *carry)
-{
- return(BitVector_compute(X,Y,Z,TRUE,carry));
-}
-
-boolean BitVector_inc(wordptr X, wordptr Y)
-{
- boolean carry = TRUE;
-
- return(BitVector_compute(X,Y,NULL,FALSE,&carry));
-}
-
-boolean BitVector_dec(wordptr X, wordptr Y)
-{
- boolean carry = TRUE;
-
- return(BitVector_compute(X,Y,NULL,TRUE,&carry));
-}
-
-void BitVector_Negate(wordptr X, wordptr Y)
-{
- N_word size = size_(X);
- N_word mask = mask_(X);
- boolean carry = TRUE;
-
- if (size > 0)
- {
- while (size-- > 0)
- {
- *X = NOT *Y++;
- if (carry)
- {
- carry = (++(*X) == 0);
- }
- X++;
- }
- *(--X) &= mask;
- }
-}
-
-void BitVector_Absolute(wordptr X, wordptr Y)
-{
- N_word size = size_(Y);
- N_word mask = mask_(Y);
-
- if (size > 0)
- {
- if (*(Y+size-1) AND (mask AND NOT (mask >> 1))) BitVector_Negate(X,Y);
- else BitVector_Copy(X,Y);
- }
-}
-
-Z_int BitVector_Sign(wordptr addr)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- wordptr last = addr + size - 1;
- boolean r = TRUE;
-
- if (size > 0)
- {
- *last &= mask;
- while (r and (size-- > 0)) r = ( *addr++ == 0 );
- }
- if (r) return((Z_int) 0);
- else
- {
- if (*last AND (mask AND NOT (mask >> 1))) return((Z_int) -1);
- else return((Z_int) 1);
- }
-}
-
-ErrCode BitVector_Mul_Pos(wordptr X, wordptr Y, wordptr Z, boolean strict)
-{
- N_word mask;
- N_word limit;
- N_word count;
- Z_long last;
- wordptr sign;
- boolean carry;
- boolean overflow;
- boolean ok = TRUE;
-
- /*
- Requirements:
- - X, Y and Z must be distinct
- - X and Y must have equal sizes (whereas Z may be any size!)
- - Z should always contain the SMALLER of the two factors Y and Z
- Constraints:
- - The contents of Y (and of X, of course) are destroyed
- (only Z is preserved!)
- */
-
- if ((X == Y) or (X == Z) or (Y == Z)) return(ErrCode_Same);
- if (bits_(X) != bits_(Y)) return(ErrCode_Size);
- BitVector_Empty(X);
- if (BitVector_is_empty(Y)) return(ErrCode_Ok); /* exit also taken if bits_(Y)==0 */
- if ((last = Set_Max(Z)) < 0L) return(ErrCode_Ok);
- limit = (N_word) last;
- sign = Y + size_(Y) - 1;
- mask = mask_(Y);
- *sign &= mask;
- mask &= NOT (mask >> 1);
- for ( count = 0; (ok and (count <= limit)); count++ )
- {
- if ( BIT_VECTOR_TST_BIT(Z,count) )
- {
- carry = false;
- overflow = BitVector_compute(X,X,Y,false,&carry);
- if (strict) ok = not (carry or overflow);
- else ok = not carry;
- }
- if (ok and (count < limit))
- {
- carry = BitVector_shift_left(Y,0);
- if (strict)
- {
- overflow = ((*sign AND mask) != 0);
- ok = not (carry or overflow);
- }
- else ok = not carry;
- }
- }
- if (ok) return(ErrCode_Ok); else return(ErrCode_Ovfl);
-}
-
-ErrCode BitVector_Multiply(wordptr X, wordptr Y, wordptr Z)
-{
- ErrCode error = ErrCode_Ok;
- N_word bit_x = bits_(X);
- N_word bit_y = bits_(Y);
- N_word bit_z = bits_(Z);
- N_word size;
- N_word mask;
- N_word msb;
- wordptr ptr_y;
- wordptr ptr_z;
- boolean sgn_x;
- boolean sgn_y;
- boolean sgn_z;
- boolean zero;
- wordptr A;
- wordptr B;
-
- /*
- Requirements:
- - Y and Z must have equal sizes
- - X must have at least the same size as Y and Z but may be larger (!)
- Features:
- - The contents of Y and Z are preserved
- - X may be identical with Y or Z (or both!)
- (in-place multiplication is possible!)
- */
-
- if ((bit_y != bit_z) or (bit_x < bit_y)) return(ErrCode_Size);
- if (BitVector_is_empty(Y) or BitVector_is_empty(Z))
- {
- BitVector_Empty(X);
- }
- else
- {
- A = BitVector_Create(bit_y,FALSE);
- if (A == NULL) return(ErrCode_Null);
- B = BitVector_Create(bit_z,FALSE);
- if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
- size = size_(Y);
- mask = mask_(Y);
- msb = (mask AND NOT (mask >> 1));
- sgn_y = (((*(Y+size-1) &= mask) AND msb) != 0);
- sgn_z = (((*(Z+size-1) &= mask) AND msb) != 0);
- sgn_x = sgn_y XOR sgn_z;
- if (sgn_y) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
- if (sgn_z) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
- ptr_y = A + size;
- ptr_z = B + size;
- zero = TRUE;
- while (zero and (size-- > 0))
- {
- zero &= (*(--ptr_y) == 0);
- zero &= (*(--ptr_z) == 0);
- }
- if (*ptr_y > *ptr_z)
- {
- if (bit_x > bit_y)
- {
- A = BitVector_Resize(A,bit_x);
- if (A == NULL) { BitVector_Destroy(B); return(ErrCode_Null); }
- }
- error = BitVector_Mul_Pos(X,A,B,TRUE);
- }
- else
- {
- if (bit_x > bit_z)
- {
- B = BitVector_Resize(B,bit_x);
- if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
- }
- error = BitVector_Mul_Pos(X,B,A,TRUE);
- }
- if ((not error) and sgn_x) BitVector_Negate(X,X);
- BitVector_Destroy(A);
- BitVector_Destroy(B);
- }
- return(error);
-}
-
-ErrCode BitVector_Div_Pos(wordptr Q, wordptr X, wordptr Y, wordptr R)
-{
- N_word bits = bits_(Q);
- N_word mask;
- wordptr addr;
- Z_long last;
- boolean flag;
- boolean copy = FALSE; /* flags whether valid rest is in R (0) or X (1) */
-
- /*
- Requirements:
- - All bit vectors must have equal sizes
- - Q, X, Y and R must all be distinct bit vectors
- - Y must be non-zero (of course!)
- Constraints:
- - The contents of X (and Q and R, of course) are destroyed
- (only Y is preserved!)
- */
-
- if ((bits != bits_(X)) or (bits != bits_(Y)) or (bits != bits_(R)))
- return(ErrCode_Size);
- if ((Q == X) or (Q == Y) or (Q == R) or (X == Y) or (X == R) or (Y == R))
- return(ErrCode_Same);
- if (BitVector_is_empty(Y))
- return(ErrCode_Zero);
-
- BitVector_Empty(R);
- BitVector_Copy(Q,X);
- if ((last = Set_Max(Q)) < 0L) return(ErrCode_Ok);
- bits = (N_word) ++last;
- while (bits-- > 0)
- {
- addr = Q + (bits >> LOGBITS);
- mask = BITMASKTAB[bits AND MODMASK];
- flag = ((*addr AND mask) != 0);
- if (copy)
- {
- BitVector_shift_left(X,flag);
- flag = FALSE;
- BitVector_compute(R,X,Y,TRUE,&flag);
- }
- else
- {
- BitVector_shift_left(R,flag);
- flag = FALSE;
- BitVector_compute(X,R,Y,TRUE,&flag);
- }
- if (flag) *addr &= NOT mask;
- else
- {
- *addr |= mask;
- copy = not copy;
- }
- }
- if (copy) BitVector_Copy(R,X);
- return(ErrCode_Ok);
-}
-
-ErrCode BitVector_Divide(wordptr Q, wordptr X, wordptr Y, wordptr R)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(Q);
- N_word size = size_(Q);
- N_word mask = mask_(Q);
- N_word msb = (mask AND NOT (mask >> 1));
- boolean sgn_q;
- boolean sgn_x;
- boolean sgn_y;
- wordptr A;
- wordptr B;
-
- /*
- Requirements:
- - All bit vectors must have equal sizes
- - Q and R must be two distinct bit vectors
- - Y must be non-zero (of course!)
- Features:
- - The contents of X and Y are preserved
- - Q may be identical with X or Y (or both)
- (in-place division is possible!)
- - R may be identical with X or Y (or both)
- (but not identical with Q!)
- */
-
- if ((bits != bits_(X)) or (bits != bits_(Y)) or (bits != bits_(R)))
- return(ErrCode_Size);
- if (Q == R)
- return(ErrCode_Same);
- if (BitVector_is_empty(Y))
- return(ErrCode_Zero);
-
- if (BitVector_is_empty(X))
- {
- BitVector_Empty(Q);
- BitVector_Empty(R);
- }
- else
- {
- A = BitVector_Create(bits,FALSE);
- if (A == NULL) return(ErrCode_Null);
- B = BitVector_Create(bits,FALSE);
- if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
- size--;
- sgn_x = (((*(X+size) &= mask) AND msb) != 0);
- sgn_y = (((*(Y+size) &= mask) AND msb) != 0);
- sgn_q = sgn_x XOR sgn_y;
- if (sgn_x) BitVector_Negate(A,X); else BitVector_Copy(A,X);
- if (sgn_y) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
- if (not (error = BitVector_Div_Pos(Q,A,B,R)))
- {
- if (sgn_q) BitVector_Negate(Q,Q);
- if (sgn_x) BitVector_Negate(R,R);
- }
- BitVector_Destroy(A);
- BitVector_Destroy(B);
- }
- return(error);
-}
-
-ErrCode BitVector_GCD(wordptr X, wordptr Y, wordptr Z)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(X);
- N_word size = size_(X);
- N_word mask = mask_(X);
- N_word msb = (mask AND NOT (mask >> 1));
- boolean sgn_a;
- boolean sgn_b;
- boolean sgn_r;
- wordptr Q;
- wordptr R;
- wordptr A;
- wordptr B;
- wordptr T;
-
- /*
- Requirements:
- - All bit vectors must have equal sizes
- Features:
- - The contents of Y and Z are preserved
- - X may be identical with Y or Z (or both)
- (in-place is possible!)
- - GCD(0,z) == GCD(z,0) == z
- - negative values are handled correctly
- */
-
- if ((bits != bits_(Y)) or (bits != bits_(Z))) return(ErrCode_Size);
- if (BitVector_is_empty(Y))
- {
- if (X != Z) BitVector_Copy(X,Z);
- return(ErrCode_Ok);
- }
- if (BitVector_is_empty(Z))
- {
- if (X != Y) BitVector_Copy(X,Y);
- return(ErrCode_Ok);
- }
- Q = BitVector_Create(bits,false);
- if (Q == NULL)
- {
- return(ErrCode_Null);
- }
- R = BitVector_Create(bits,FALSE);
- if (R == NULL)
- {
- BitVector_Destroy(Q);
- return(ErrCode_Null);
- }
- A = BitVector_Create(bits,FALSE);
- if (A == NULL)
- {
- BitVector_Destroy(Q);
- BitVector_Destroy(R);
- return(ErrCode_Null);
- }
- B = BitVector_Create(bits,FALSE);
- if (B == NULL)
- {
- BitVector_Destroy(Q);
- BitVector_Destroy(R);
- BitVector_Destroy(A);
- return(ErrCode_Null);
- }
- size--;
- sgn_a = (((*(Y+size) &= mask) AND msb) != 0);
- sgn_b = (((*(Z+size) &= mask) AND msb) != 0);
- if (sgn_a) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
- if (sgn_b) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
- while (not error)
- {
- if (not (error = BitVector_Div_Pos(Q,A,B,R)))
- {
- if (BitVector_is_empty(R)) break;
- T = A; sgn_r = sgn_a;
- A = B; sgn_a = sgn_b;
- B = R; sgn_b = sgn_r;
- R = T;
- }
- }
- if (not error)
- {
- if (sgn_b) BitVector_Negate(X,B); else BitVector_Copy(X,B);
- }
- BitVector_Destroy(Q);
- BitVector_Destroy(R);
- BitVector_Destroy(A);
- BitVector_Destroy(B);
- return(error);
-}
-
-ErrCode BitVector_GCD2(wordptr U, wordptr V, wordptr W, wordptr X, wordptr Y)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(U);
- N_word size = size_(U);
- N_word mask = mask_(U);
- N_word msb = (mask AND NOT (mask >> 1));
- boolean minus;
- boolean carry;
- boolean sgn_q;
- boolean sgn_r;
- boolean sgn_a;
- boolean sgn_b;
- boolean sgn_x;
- boolean sgn_y;
- listptr L;
- wordptr Q;
- wordptr R;
- wordptr A;
- wordptr B;
- wordptr T;
- wordptr X1;
- wordptr X2;
- wordptr X3;
- wordptr Y1;
- wordptr Y2;
- wordptr Y3;
- wordptr Z;
-
- /*
- Requirements:
- - All bit vectors must have equal sizes
- - U, V, and W must all be distinct bit vectors
- Features:
- - The contents of X and Y are preserved
- - U, V and W may be identical with X or Y (or both,
- provided that U, V and W are mutually distinct)
- (i.e., in-place is possible!)
- - GCD(0,z) == GCD(z,0) == z
- - negative values are handled correctly
- */
-
- if ((bits != bits_(V)) or
- (bits != bits_(W)) or
- (bits != bits_(X)) or
- (bits != bits_(Y)))
- {
- return(ErrCode_Size);
- }
- if ((U == V) or (U == W) or (V == W))
- {
- return(ErrCode_Same);
- }
- if (BitVector_is_empty(X))
- {
- if (U != Y) BitVector_Copy(U,Y);
- BitVector_Empty(V);
- BitVector_Empty(W);
- *W = 1;
- return(ErrCode_Ok);
- }
- if (BitVector_is_empty(Y))
- {
- if (U != X) BitVector_Copy(U,X);
- BitVector_Empty(V);
- BitVector_Empty(W);
- *V = 1;
- return(ErrCode_Ok);
- }
- if ((L = BitVector_Create_List(bits,false,11)) == NULL)
- {
- return(ErrCode_Null);
- }
- Q = L[0];
- R = L[1];
- A = L[2];
- B = L[3];
- X1 = L[4];
- X2 = L[5];
- X3 = L[6];
- Y1 = L[7];
- Y2 = L[8];
- Y3 = L[9];
- Z = L[10];
- size--;
- sgn_a = (((*(X+size) &= mask) AND msb) != 0);
- sgn_b = (((*(Y+size) &= mask) AND msb) != 0);
- if (sgn_a) BitVector_Negate(A,X); else BitVector_Copy(A,X);
- if (sgn_b) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
- BitVector_Empty(X1);
- BitVector_Empty(X2);
- *X1 = 1;
- BitVector_Empty(Y1);
- BitVector_Empty(Y2);
- *Y2 = 1;
- sgn_x = false;
- sgn_y = false;
- while (not error)
- {
- if ((error = BitVector_Div_Pos(Q,A,B,R)))
- {
- break;
- }
- if (BitVector_is_empty(R))
- {
- break;
- }
- sgn_q = sgn_a XOR sgn_b;
-
- if (sgn_x) BitVector_Negate(Z,X2); else BitVector_Copy(Z,X2);
- if ((error = BitVector_Mul_Pos(X3,Z,Q,true)))
- {
- break;
- }
- minus = not (sgn_x XOR sgn_q);
- carry = 0;
- if (BitVector_compute(X3,X1,X3,minus,&carry))
- {
- error = ErrCode_Ovfl;
- break;
- }
- sgn_x = (((*(X3+size) &= mask) AND msb) != 0);
-
- if (sgn_y) BitVector_Negate(Z,Y2); else BitVector_Copy(Z,Y2);
- if ((error = BitVector_Mul_Pos(Y3,Z,Q,true)))
- {
- break;
- }
- minus = not (sgn_y XOR sgn_q);
- carry = 0;
- if (BitVector_compute(Y3,Y1,Y3,minus,&carry))
- {
- error = ErrCode_Ovfl;
- break;
- }
- sgn_y = (((*(Y3+size) &= mask) AND msb) != 0);
-
- T = A; sgn_r = sgn_a;
- A = B; sgn_a = sgn_b;
- B = R; sgn_b = sgn_r;
- R = T;
-
- T = X1;
- X1 = X2;
- X2 = X3;
- X3 = T;
-
- T = Y1;
- Y1 = Y2;
- Y2 = Y3;
- Y3 = T;
- }
- if (not error)
- {
- if (sgn_b) BitVector_Negate(U,B); else BitVector_Copy(U,B);
- BitVector_Copy(V,X2);
- BitVector_Copy(W,Y2);
- }
- BitVector_Destroy_List(L,11);
- return(error);
-}
-
-ErrCode BitVector_Power(wordptr X, wordptr Y, wordptr Z)
-{
- ErrCode error = ErrCode_Ok;
- N_word bits = bits_(X);
- boolean first = TRUE;
- Z_long last;
- N_word limit;
- N_word count;
- wordptr T;
-
- /*
- Requirements:
- - X must have at least the same size as Y but may be larger (!)
- - X may not be identical with Z
- - Z must be positive
- Features:
- - The contents of Y and Z are preserved
- */
-
- if (X == Z) return(ErrCode_Same);
- if (bits < bits_(Y)) return(ErrCode_Size);
- if (BitVector_msb_(Z)) return(ErrCode_Expo);
- if ((last = Set_Max(Z)) < 0L)
- {
- if (bits < 2) return(ErrCode_Ovfl);
- BitVector_Empty(X);
- *X |= LSB;
- return(ErrCode_Ok); /* anything ^ 0 == 1 */
- }
- if (BitVector_is_empty(Y))
- {
- if (X != Y) BitVector_Empty(X);
- return(ErrCode_Ok); /* 0 ^ anything not zero == 0 */
- }
- T = BitVector_Create(bits,FALSE);
- if (T == NULL) return(ErrCode_Null);
- limit = (N_word) last;
- for ( count = 0; ((!error) and (count <= limit)); count++ )
- {
- if ( BIT_VECTOR_TST_BIT(Z,count) )
- {
- if (first)
- {
- first = FALSE;
- if (count) { BitVector_Copy(X,T); }
- else { if (X != Y) BitVector_Copy(X,Y); }
- }
- else error = BitVector_Multiply(X,T,X); /* order important because T > X */
- }
- if ((!error) and (count < limit))
- {
- if (count) error = BitVector_Multiply(T,T,T);
- else error = BitVector_Multiply(T,Y,Y);
- }
- }
- BitVector_Destroy(T);
- return(error);
-}
-
-void BitVector_Block_Store(wordptr addr, charptr buffer, N_int length)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- N_word value;
- N_word count;
-
- /* provide translation for independence of endian-ness: */
- if (size > 0)
- {
- while (size-- > 0)
- {
- value = 0;
- for ( count = 0; (length > 0) and (count < BITS); count += 8 )
- {
- value |= (((N_word) *buffer++) << count); length--;
- }
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
-}
-
-charptr BitVector_Block_Read(wordptr addr, N_intptr length)
-{
- N_word size = size_(addr);
- N_word value;
- N_word count;
- charptr buffer;
- charptr target;
-
- /* provide translation for independence of endian-ness: */
- *length = size << FACTOR;
- buffer = (charptr) yasm_xmalloc((size_t) ((*length)+1));
- if (buffer == NULL) return(NULL);
- target = buffer;
- if (size > 0)
- {
- *(addr+size-1) &= mask_(addr);
- while (size-- > 0)
- {
- value = *addr++;
- count = BITS >> 3;
- while (count-- > 0)
- {
- *target++ = (N_char) (value AND 0x00FF);
- if (count > 0) value >>= 8;
- }
- }
- }
- *target = (N_char) '\0';
- return(buffer);
-}
-
-void BitVector_Word_Store(wordptr addr, N_int offset, N_int value)
-{
- N_word size = size_(addr);
-
- if (size > 0)
- {
- if (offset < size) *(addr+offset) = value;
- *(addr+size-1) &= mask_(addr);
- }
-}
-
-N_int BitVector_Word_Read(wordptr addr, N_int offset)
-{
- N_word size = size_(addr);
-
- if (size > 0)
- {
- *(addr+size-1) &= mask_(addr);
- if (offset < size) return( *(addr+offset) );
- }
- return( (N_int) 0 );
-}
-
-void BitVector_Word_Insert(wordptr addr, N_int offset, N_int count,
- boolean clear)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- wordptr last = addr+size-1;
-
- if (size > 0)
- {
- *last &= mask;
- if (offset > size) offset = size;
- BIT_VECTOR_ins_words(addr+offset,size-offset,count,clear);
- *last &= mask;
- }
-}
-
-void BitVector_Word_Delete(wordptr addr, N_int offset, N_int count,
- boolean clear)
-{
- N_word size = size_(addr);
- N_word mask = mask_(addr);
- wordptr last = addr+size-1;
-
- if (size > 0)
- {
- *last &= mask;
- if (offset > size) offset = size;
- BIT_VECTOR_del_words(addr+offset,size-offset,count,clear);
- *last &= mask;
- }
-}
-
-void BitVector_Chunk_Store(wordptr addr, N_int chunksize, N_int offset,
- N_long value)
-{
- N_word bits = bits_(addr);
- N_word mask;
- N_word temp;
-
- if ((chunksize > 0) and (offset < bits))
- {
- if (chunksize > LONGBITS) chunksize = LONGBITS;
- if ((offset + chunksize) > bits) chunksize = bits - offset;
- addr += offset >> LOGBITS;
- offset &= MODMASK;
- while (chunksize > 0)
- {
- mask = (N_word) (~0L << offset);
- bits = offset + chunksize;
- if (bits < BITS)
- {
- mask &= (N_word) ~(~0L << bits);
- bits = chunksize;
- }
- else bits = BITS - offset;
- temp = (N_word) (value << offset);
- temp &= mask;
- *addr &= NOT mask;
- *addr++ |= temp;
- value >>= bits;
- chunksize -= bits;
- offset = 0;
- }
- }
-}
-
-N_long BitVector_Chunk_Read(wordptr addr, N_int chunksize, N_int offset)
-{
- N_word bits = bits_(addr);
- N_word chunkbits = 0;
- N_long value = 0L;
- N_long temp;
- N_word mask;
-
- if ((chunksize > 0) and (offset < bits))
- {
- if (chunksize > LONGBITS) chunksize = LONGBITS;
- if ((offset + chunksize) > bits) chunksize = bits - offset;
- addr += offset >> LOGBITS;
- offset &= MODMASK;
- while (chunksize > 0)
- {
- bits = offset + chunksize;
- if (bits < BITS)
- {
- mask = (N_word) ~(~0L << bits);
- bits = chunksize;
- }
- else
- {
- mask = (N_word) ~0L;
- bits = BITS - offset;
- }
- temp = (N_long) ((*addr++ AND mask) >> offset);
- value |= temp << chunkbits;
- chunkbits += bits;
- chunksize -= bits;
- offset = 0;
- }
- }
- return(value);
-}
-
- /*******************/
- /* set operations: */
- /*******************/
-
-void Set_Union(wordptr X, wordptr Y, wordptr Z) /* X = Y + Z */
-{
- N_word bits = bits_(X);
- N_word size = size_(X);
- N_word mask = mask_(X);
-
- if ((size > 0) and (bits == bits_(Y)) and (bits == bits_(Z)))
- {
- while (size-- > 0) *X++ = *Y++ OR *Z++;
- *(--X) &= mask;
- }
-}
-
-void Set_Intersection(wordptr X, wordptr Y, wordptr Z) /* X = Y * Z */
-{
- N_word bits = bits_(X);
- N_word size = size_(X);
- N_word mask = mask_(X);
-
- if ((size > 0) and (bits == bits_(Y)) and (bits == bits_(Z)))
- {
- while (size-- > 0) *X++ = *Y++ AND *Z++;
- *(--X) &= mask;
- }
-}
-
-void Set_Difference(wordptr X, wordptr Y, wordptr Z) /* X = Y \ Z */
-{
- N_word bits = bits_(X);
- N_word size = size_(X);
- N_word mask = mask_(X);
-
- if ((size > 0) and (bits == bits_(Y)) and (bits == bits_(Z)))
- {
- while (size-- > 0) *X++ = *Y++ AND NOT *Z++;
- *(--X) &= mask;
- }
-}
-
-void Set_ExclusiveOr(wordptr X, wordptr Y, wordptr Z) /* X=(Y+Z)\(Y*Z) */
-{
- N_word bits = bits_(X);
- N_word size = size_(X);
- N_word mask = mask_(X);
-
- if ((size > 0) and (bits == bits_(Y)) and (bits == bits_(Z)))
- {
- while (size-- > 0) *X++ = *Y++ XOR *Z++;
- *(--X) &= mask;
- }
-}
-
-void Set_Complement(wordptr X, wordptr Y) /* X = ~Y */
-{
- N_word size = size_(X);
- N_word mask = mask_(X);
-
- if ((size > 0) and (bits_(X) == bits_(Y)))
- {
- while (size-- > 0) *X++ = NOT *Y++;
- *(--X) &= mask;
- }
-}
-
- /******************/
- /* set functions: */
- /******************/
-
-boolean Set_subset(wordptr X, wordptr Y) /* X subset Y ? */
-{
- N_word size = size_(X);
- boolean r = FALSE;
-
- if ((size > 0) and (bits_(X) == bits_(Y)))
- {
- r = TRUE;
- while (r and (size-- > 0)) r = ((*X++ AND NOT *Y++) == 0);
- }
- return(r);
-}
-
-N_int Set_Norm(wordptr addr) /* = | X | */
-{
- N_word size = size_(addr);
- N_int count = 0;
- N_word c;
-
- while (size-- > 0)
- {
- c = *addr++;
- while (c)
- {
- c &= c - 1;
- count++;
- }
- }
- return(count);
-}
-
-Z_long Set_Min(wordptr addr) /* = min(X) */
-{
- boolean empty = TRUE;
- N_word size = size_(addr);
- N_word i = 0;
- N_word c = 0; /* silence compiler warning */
-
- while (empty and (size-- > 0))
- {
- if ((c = *addr++)) empty = false; else i++;
- }
- if (empty) return((Z_long) LONG_MAX); /* plus infinity */
- i <<= LOGBITS;
- while (not (c AND LSB))
- {
- c >>= 1;
- i++;
- }
- return((Z_long) i);
-}
-
-Z_long Set_Max(wordptr addr) /* = max(X) */
-{
- boolean empty = TRUE;
- N_word size = size_(addr);
- N_word i = size;
- N_word c = 0; /* silence compiler warning */
-
- addr += size-1;
- while (empty and (size-- > 0))
- {
- if ((c = *addr--)) empty = false; else i--;
- }
- if (empty) return((Z_long) LONG_MIN); /* minus infinity */
- i <<= LOGBITS;
- while (not (c AND MSB))
- {
- c <<= 1;
- i--;
- }
- return((Z_long) --i);
-}
-
- /**********************************/
- /* matrix-of-booleans operations: */
- /**********************************/
-
-void Matrix_Multiplication(wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY,
- wordptr Z, N_int rowsZ, N_int colsZ)
-{
- N_word i;
- N_word j;
- N_word k;
- N_word indxX;
- N_word indxY;
- N_word indxZ;
- N_word termX;
- N_word termY;
- N_word sum;
-
- if ((colsY == rowsZ) and (rowsX == rowsY) and (colsX == colsZ) and
- (bits_(X) == rowsX*colsX) and
- (bits_(Y) == rowsY*colsY) and
- (bits_(Z) == rowsZ*colsZ))
- {
- for ( i = 0; i < rowsY; i++ )
- {
- termX = i * colsX;
- termY = i * colsY;
- for ( j = 0; j < colsZ; j++ )
- {
- indxX = termX + j;
- sum = 0;
- for ( k = 0; k < colsY; k++ )
- {
- indxY = termY + k;
- indxZ = k * colsZ + j;
- if ( BIT_VECTOR_TST_BIT(Y,indxY) &&
- BIT_VECTOR_TST_BIT(Z,indxZ) ) sum ^= 1;
- }
- if (sum) BIT_VECTOR_SET_BIT(X,indxX)
- else BIT_VECTOR_CLR_BIT(X,indxX)
- }
- }
- }
-}
-
-void Matrix_Product(wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY,
- wordptr Z, N_int rowsZ, N_int colsZ)
-{
- N_word i;
- N_word j;
- N_word k;
- N_word indxX;
- N_word indxY;
- N_word indxZ;
- N_word termX;
- N_word termY;
- N_word sum;
-
- if ((colsY == rowsZ) and (rowsX == rowsY) and (colsX == colsZ) and
- (bits_(X) == rowsX*colsX) and
- (bits_(Y) == rowsY*colsY) and
- (bits_(Z) == rowsZ*colsZ))
- {
- for ( i = 0; i < rowsY; i++ )
- {
- termX = i * colsX;
- termY = i * colsY;
- for ( j = 0; j < colsZ; j++ )
- {
- indxX = termX + j;
- sum = 0;
- for ( k = 0; k < colsY; k++ )
- {
- indxY = termY + k;
- indxZ = k * colsZ + j;
- if ( BIT_VECTOR_TST_BIT(Y,indxY) &&
- BIT_VECTOR_TST_BIT(Z,indxZ) ) sum |= 1;
- }
- if (sum) BIT_VECTOR_SET_BIT(X,indxX)
- else BIT_VECTOR_CLR_BIT(X,indxX)
- }
- }
- }
-}
-
-void Matrix_Closure(wordptr addr, N_int rows, N_int cols)
-{
- N_word i;
- N_word j;
- N_word k;
- N_word ii;
- N_word ij;
- N_word ik;
- N_word kj;
- N_word termi;
- N_word termk;
-
- if ((rows == cols) and (bits_(addr) == rows*cols))
- {
- for ( i = 0; i < rows; i++ )
- {
- ii = i * cols + i;
- BIT_VECTOR_SET_BIT(addr,ii)
- }
- for ( k = 0; k < rows; k++ )
- {
- termk = k * cols;
- for ( i = 0; i < rows; i++ )
- {
- termi = i * cols;
- ik = termi + k;
- for ( j = 0; j < rows; j++ )
- {
- ij = termi + j;
- kj = termk + j;
- if ( BIT_VECTOR_TST_BIT(addr,ik) &&
- BIT_VECTOR_TST_BIT(addr,kj) )
- BIT_VECTOR_SET_BIT(addr,ij)
- }
- }
- }
- }
-}
-
-void Matrix_Transpose(wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY)
-{
- N_word i;
- N_word j;
- N_word ii;
- N_word ij;
- N_word ji;
- N_word addii;
- N_word addij;
- N_word addji;
- N_word bitii;
- N_word bitij;
- N_word bitji;
- N_word termi;
- N_word termj;
- boolean swap;
-
- /* BEWARE that "in-place" is ONLY possible if the matrix is quadratic!! */
-
- if ((rowsX == colsY) and (colsX == rowsY) and
- (bits_(X) == rowsX*colsX) and
- (bits_(Y) == rowsY*colsY))
- {
- if (rowsY == colsY) /* in-place is possible! */
- {
- for ( i = 0; i < rowsY; i++ )
- {
- termi = i * colsY;
- for ( j = 0; j < i; j++ )
- {
- termj = j * colsX;
- ij = termi + j;
- ji = termj + i;
- addij = ij >> LOGBITS;
- addji = ji >> LOGBITS;
- bitij = BITMASKTAB[ij AND MODMASK];
- bitji = BITMASKTAB[ji AND MODMASK];
- swap = ((*(Y+addij) AND bitij) != 0);
- if ((*(Y+addji) AND bitji) != 0)
- *(X+addij) |= bitij;
- else
- *(X+addij) &= NOT bitij;
- if (swap)
- *(X+addji) |= bitji;
- else
- *(X+addji) &= NOT bitji;
- }
- ii = termi + i;
- addii = ii >> LOGBITS;
- bitii = BITMASKTAB[ii AND MODMASK];
- if ((*(Y+addii) AND bitii) != 0)
- *(X+addii) |= bitii;
- else
- *(X+addii) &= NOT bitii;
- }
- }
- else /* rowsX != colsX, in-place is NOT possible! */
- {
- for ( i = 0; i < rowsY; i++ )
- {
- termi = i * colsY;
- for ( j = 0; j < colsY; j++ )
- {
- termj = j * colsX;
- ij = termi + j;
- ji = termj + i;
- addij = ij >> LOGBITS;
- addji = ji >> LOGBITS;
- bitij = BITMASKTAB[ij AND MODMASK];
- bitji = BITMASKTAB[ji AND MODMASK];
- if ((*(Y+addij) AND bitij) != 0)
- *(X+addji) |= bitji;
- else
- *(X+addji) &= NOT bitji;
- }
- }
- }
- }
-}
-
-/*****************************************************************************/
-/* VERSION: 6.3 */
-/*****************************************************************************/
-/* VERSION HISTORY: */
-/*****************************************************************************/
-/* */
-/* Version 6.3 28.09.02 Added "Create_List()" and "GCD2()". */
-/* Version 6.2 15.09.02 Overhauled error handling. Fixed "GCD()". */
-/* Version 6.1 08.10.01 Make VMS linker happy: _lsb,_msb => _lsb_,_msb_ */
-/* Version 6.0 08.10.00 Corrected overflow handling. */
-/* Version 5.8 14.07.00 Added "Power()". Changed "Copy()". */
-/* Version 5.7 19.05.99 Quickened "Div_Pos()". Added "Product()". */
-/* Version 5.6 02.11.98 Leading zeros eliminated in "to_Hex()". */
-/* Version 5.5 21.09.98 Fixed bug of uninitialized "error" in Multiply. */
-/* Version 5.4 07.09.98 Fixed bug of uninitialized "error" in Divide. */
-/* Version 5.3 12.05.98 Improved Norm. Completed history. */
-/* Version 5.2 31.03.98 Improved Norm. */
-/* Version 5.1 09.03.98 No changes. */
-/* Version 5.0 01.03.98 Major additions and rewrite. */
-/* Version 4.2 16.07.97 Added is_empty, is_full. */
-/* Version 4.1 30.06.97 Added word-ins/del, move-left/right, inc/dec. */
-/* Version 4.0 23.04.97 Rewrite. Added bit shift and bool. matrix ops. */
-/* Version 3.2 04.02.97 Added interval methods. */
-/* Version 3.1 21.01.97 Fixed bug on 64 bit machines. */
-/* Version 3.0 12.01.97 Added flip. */
-/* Version 2.0 14.12.96 Efficiency and consistency improvements. */
-/* Version 1.1 08.01.96 Added Resize and ExclusiveOr. */
-/* Version 1.0 14.12.95 First version under UNIX (with Perl module). */
-/* Version 0.9 01.11.93 First version of C library under MS-DOS. */
-/* Version 0.1 ??.??.89 First version in Turbo Pascal under CP/M. */
-/* */
-/*****************************************************************************/
-/* AUTHOR: */
-/*****************************************************************************/
-/* */
-/* Steffen Beyer */
-/* mailto:sb@engelschall.com */
-/* http://www.engelschall.com/u/sb/download/ */
-/* */
-/*****************************************************************************/
-/* COPYRIGHT: */
-/*****************************************************************************/
-/* */
-/* Copyright (c) 1995 - 2002 by Steffen Beyer. */
-/* All rights reserved. */
-/* */
-/*****************************************************************************/
-/* LICENSE: */
-/*****************************************************************************/
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU Library General Public */
-/* License as published by the Free Software Foundation; either */
-/* version 2 of the License, or (at your option) any later version. */
-/* */
-/* This library 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 */
-/* Library General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU Library General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., */
-/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* */
-/* or download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0 */
-/* */
-/*****************************************************************************/
+++ /dev/null
-/* $IdPath$ */
-
-#ifndef YASM_BITVECT_H
-#define YASM_BITVECT_H
-/*****************************************************************************/
-/* MODULE NAME: BitVector.h MODULE TYPE: (adt) */
-/*****************************************************************************/
-/* MODULE IMPORTS: */
-/*****************************************************************************/
-
-/* ToolBox.h */
-/*****************************************************************************/
-/* NOTE: The type names that have been chosen here are somewhat weird on */
-/* purpose, in order to avoid name clashes with system header files */
-/* and your own application(s) which might - directly or indirectly - */
-/* include this definitions file. */
-/*****************************************************************************/
-
-typedef unsigned char N_char;
-typedef unsigned char N_byte;
-typedef unsigned short N_short;
-typedef unsigned short N_shortword;
-typedef unsigned int N_int;
-typedef unsigned int N_word;
-typedef unsigned long N_long;
-typedef unsigned long N_longword;
-
-/* Mnemonic 1: The natural numbers, N = { 0, 1, 2, 3, ... } */
-/* Mnemonic 2: Nnnn = u_N_signed, _N_ot signed */
-
-typedef signed char Z_char;
-typedef signed char Z_byte;
-typedef signed short Z_short;
-typedef signed short Z_shortword;
-typedef signed int Z_int;
-typedef signed int Z_word;
-typedef signed long Z_long;
-typedef signed long Z_longword;
-
-/* Mnemonic 1: The whole numbers, Z = { 0, -1, 1, -2, 2, -3, 3, ... } */
-/* Mnemonic 2: Zzzz = Ssss_igned */
-
-typedef void *voidptr;
-typedef N_char *charptr;
-typedef N_byte *byteptr;
-typedef N_short *shortptr;
-typedef N_shortword *shortwordptr;
-typedef N_int *intptr;
-typedef N_word *wordptr;
-typedef N_long *longptr;
-typedef N_longword *longwordptr;
-
-typedef N_char *N_charptr;
-typedef N_byte *N_byteptr;
-typedef N_short *N_shortptr;
-typedef N_shortword *N_shortwordptr;
-typedef N_int *N_intptr;
-typedef N_word *N_wordptr;
-typedef N_long *N_longptr;
-typedef N_longword *N_longwordptr;
-
-typedef Z_char *Z_charptr;
-typedef Z_byte *Z_byteptr;
-typedef Z_short *Z_shortptr;
-typedef Z_shortword *Z_shortwordptr;
-typedef Z_int *Z_intptr;
-typedef Z_word *Z_wordptr;
-typedef Z_long *Z_longptr;
-typedef Z_longword *Z_longwordptr;
-
-#ifndef FALSE
-#define FALSE (0!=0)
-#endif
-
-#ifndef TRUE
-#define TRUE (0==0)
-#endif
-
-#ifdef __cplusplus
- typedef bool boolean;
-#else
- #ifdef MACOS_TRADITIONAL
- #define boolean Boolean
- #else
- typedef enum { false = FALSE, true = TRUE } boolean;
- #endif
-#endif
-
-/*****************************************************************************/
-/* MODULE INTERFACE: */
-/*****************************************************************************/
-
-typedef enum
- {
- ErrCode_Ok = 0, /* everything went allright */
-
- ErrCode_Type, /* types word and size_t have incompatible sizes */
- ErrCode_Bits, /* bits of word and sizeof(word) are inconsistent */
- ErrCode_Word, /* size of word is less than 16 bits */
- ErrCode_Long, /* size of word is greater than size of long */
- ErrCode_Powr, /* number of bits of word is not a power of two */
- ErrCode_Loga, /* error in calculation of logarithm */
-
- ErrCode_Null, /* unable to allocate memory */
-
- ErrCode_Indx, /* index out of range */
- ErrCode_Ordr, /* minimum > maximum index */
- ErrCode_Size, /* bit vector size mismatch */
- ErrCode_Pars, /* input string syntax error */
- ErrCode_Ovfl, /* numeric overflow error */
- ErrCode_Same, /* operands must be distinct */
- ErrCode_Expo, /* exponent must be positive */
- ErrCode_Zero /* division by zero error */
- } ErrCode;
-
-typedef wordptr *listptr;
-
-/* ===> MISCELLANEOUS BASIC FUNCTIONS: <=== */
-
-const char * BitVector_Error (ErrCode error); /* return string for err code */
-
-ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */
-void BitVector_Shutdown (void); /* undo Boot */
-
-N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */
-N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */
-
-/* ===> CLASS METHODS: <=== */
-
-const char * BitVector_Version (void); /* returns version string */
-
-N_int BitVector_Word_Bits (void); /* return # of bits in machine word */
-N_int BitVector_Long_Bits (void); /* return # of bits in unsigned long */
-
-/* ===> CONSTRUCTOR METHODS: <=== */
-
-/*@only@*/ wordptr BitVector_Create (N_int bits, boolean clear); /* malloc */
-listptr BitVector_Create_List(N_int bits, boolean clear, N_int count);
-
-wordptr BitVector_Resize (wordptr oldaddr, N_int bits); /* realloc */
-
-wordptr BitVector_Shadow (wordptr addr); /* make new same size but empty */
-wordptr BitVector_Clone (wordptr addr); /* make exact duplicate */
-
-wordptr BitVector_Concat (wordptr X, wordptr Y); /* return concatenation */
-
-/* ===> DESTRUCTOR METHODS: <=== */
-
-void BitVector_Dispose (/*@only@*/ /*@out@*/ charptr string); /* string */
-void BitVector_Destroy (/*@only@*/ wordptr addr); /* bitvec */
-void BitVector_Destroy_List (listptr list, N_int count); /* list */
-
-/* ===> OBJECT METHODS: <=== */
-
-/* ===> bit vector copy function: */
-
-void BitVector_Copy (wordptr X, wordptr Y); /* X = Y */
-
-/* ===> bit vector initialization: */
-
-void BitVector_Empty (wordptr addr); /* X = {} */
-void BitVector_Fill (wordptr addr); /* X = ~{} */
-void BitVector_Flip (wordptr addr); /* X = ~X */
-
-void BitVector_Primes (wordptr addr);
-
-/* ===> miscellaneous functions: */
-
-void BitVector_Reverse (wordptr X, wordptr Y);
-
-/* ===> bit vector interval operations and functions: */
-
-void BitVector_Interval_Empty (/*@out@*/ wordptr addr, N_int lower, N_int upper);
-void BitVector_Interval_Fill (/*@out@*/ wordptr addr, N_int lower, N_int upper);
-void BitVector_Interval_Flip (/*@out@*/ wordptr addr, N_int lower, N_int upper);
-void BitVector_Interval_Reverse (/*@out@*/ wordptr addr, N_int lower, N_int upper);
-
-boolean BitVector_interval_scan_inc (wordptr addr, N_int start,
- N_intptr min, N_intptr max);
-boolean BitVector_interval_scan_dec (wordptr addr, N_int start,
- N_intptr min, N_intptr max);
-
-void BitVector_Interval_Copy (/*@out@*/ wordptr X, wordptr Y, N_int Xoffset,
- N_int Yoffset, N_int length);
-
-wordptr BitVector_Interval_Substitute(/*@out@*/ wordptr X, wordptr Y,
- N_int Xoffset, N_int Xlength,
- N_int Yoffset, N_int Ylength);
-
-/* ===> bit vector test functions: */
-
-boolean BitVector_is_empty (wordptr addr); /* X == {} ? */
-boolean BitVector_is_full (wordptr addr); /* X == ~{} ? */
-
-boolean BitVector_equal (wordptr X, wordptr Y); /* X == Y ? */
-Z_int BitVector_Lexicompare(wordptr X, wordptr Y); /* X <,=,> Y ? */
-Z_int BitVector_Compare (wordptr X, wordptr Y); /* X <,=,> Y ? */
-
-/* ===> bit vector string conversion functions: */
-
-/*@only@*/ charptr BitVector_to_Hex (wordptr addr);
-ErrCode BitVector_from_Hex (/*@out@*/wordptr addr, charptr string);
-
-ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
-
-/*@only@*/ charptr BitVector_to_Bin (wordptr addr);
-ErrCode BitVector_from_Bin (/*@out@*/ wordptr addr, charptr string);
-
-/*@only@*/ charptr BitVector_to_Dec (wordptr addr);
-ErrCode BitVector_from_Dec (/*@out@*/ wordptr addr, charptr string);
-
-ErrCode BitVector_from_Dec_static_Boot(N_word bits);
-void BitVector_from_Dec_static_Shutdown(void);
-ErrCode BitVector_from_Dec_static(/*@out@*/ wordptr addr, charptr string);
-
-/*@only@*/ charptr BitVector_to_Enum (wordptr addr);
-ErrCode BitVector_from_Enum (/*@out@*/ wordptr addr, charptr string);
-
-/* ===> bit vector bit operations, functions & tests: */
-
-void BitVector_Bit_Off (/*@out@*/ wordptr addr, N_int indx); /* X = X \ {x} */
-void BitVector_Bit_On (/*@out@*/ wordptr addr, N_int indx); /* X = X + {x} */
-boolean BitVector_bit_flip (/*@out@*/ wordptr addr, N_int indx); /* (X+{x})\(X*{x}) */
-
-boolean BitVector_bit_test (wordptr addr, N_int indx); /* {x} in X ? */
-
-void BitVector_Bit_Copy (/*@out@*/ wordptr addr, N_int indx, boolean bit);
-
-/* ===> bit vector bit shift & rotate functions: */
-
-void BitVector_LSB (/*@out@*/ wordptr addr, boolean bit);
-void BitVector_MSB (/*@out@*/ wordptr addr, boolean bit);
-boolean BitVector_lsb_ (wordptr addr);
-boolean BitVector_msb_ (wordptr addr);
-boolean /*@alt void@*/ BitVector_rotate_left (wordptr addr);
-boolean /*@alt void@*/ BitVector_rotate_right (wordptr addr);
-boolean /*@alt void@*/ BitVector_shift_left (wordptr addr, boolean carry_in);
-boolean /*@alt void@*/ BitVector_shift_right (wordptr addr, boolean carry_in);
-void BitVector_Move_Left (wordptr addr, N_int bits);
-void BitVector_Move_Right (wordptr addr, N_int bits);
-
-/* ===> bit vector insert/delete bits: */
-
-void BitVector_Insert (wordptr addr, N_int offset, N_int count,
- boolean clear);
-void BitVector_Delete (wordptr addr, N_int offset, N_int count,
- boolean clear);
-
-/* ===> bit vector arithmetic: */
-
-boolean /*@alt void@*/ BitVector_increment (wordptr addr); /* X++ */
-boolean /*@alt void@*/ BitVector_decrement (wordptr addr); /* X-- */
-
-boolean /*@alt void@*/ BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
- /*@out@*/ boolean *carry);
-boolean /*@alt void@*/ BitVector_add (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
-boolean /*@alt void@*/ BitVector_sub (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
-boolean /*@alt void@*/ BitVector_inc (wordptr X, wordptr Y);
-boolean /*@alt void@*/ BitVector_dec (wordptr X, wordptr Y);
-
-void BitVector_Negate (wordptr X, wordptr Y);
-void BitVector_Absolute (wordptr X, wordptr Y);
-Z_int BitVector_Sign (wordptr addr);
-ErrCode BitVector_Mul_Pos (wordptr X, wordptr Y, wordptr Z, boolean strict);
-ErrCode BitVector_Multiply (wordptr X, wordptr Y, wordptr Z);
-ErrCode BitVector_Div_Pos (wordptr Q, wordptr X, wordptr Y, wordptr R);
-ErrCode BitVector_Divide (wordptr Q, wordptr X, wordptr Y, wordptr R);
-ErrCode BitVector_GCD (wordptr X, wordptr Y, wordptr Z);
-ErrCode BitVector_GCD2 (wordptr U, wordptr V, wordptr W, /* O */
- wordptr X, wordptr Y); /* I */
-ErrCode BitVector_Power (wordptr X, wordptr Y, wordptr Z);
-
-/* ===> direct memory access functions: */
-
-void BitVector_Block_Store(wordptr addr, charptr buffer, N_int length);
-charptr BitVector_Block_Read (wordptr addr, /*@out@*/ N_intptr length);
-
-/* ===> word array functions: */
-
-void BitVector_Word_Store (wordptr addr, N_int offset, N_int value);
-N_int BitVector_Word_Read (wordptr addr, N_int offset);
-
-void BitVector_Word_Insert(wordptr addr, N_int offset, N_int count,
- boolean clear);
-void BitVector_Word_Delete(wordptr addr, N_int offset, N_int count,
- boolean clear);
-
-/* ===> arbitrary size chunk functions: */
-
-void BitVector_Chunk_Store(wordptr addr, N_int chunksize,
- N_int offset, N_long value);
-N_long BitVector_Chunk_Read (wordptr addr, N_int chunksize,
- N_int offset);
-
-/* ===> set operations: */
-
-void Set_Union (wordptr X, wordptr Y, wordptr Z); /* X = Y + Z */
-void Set_Intersection (wordptr X, wordptr Y, wordptr Z); /* X = Y * Z */
-void Set_Difference (wordptr X, wordptr Y, wordptr Z); /* X = Y \ Z */
-void Set_ExclusiveOr (wordptr X, wordptr Y, wordptr Z); /*(Y+Z)\(Y*Z)*/
-void Set_Complement (wordptr X, wordptr Y); /* X = ~Y */
-
-/* ===> set functions: */
-
-boolean Set_subset (wordptr X, wordptr Y); /* X in Y ? */
-
-N_int Set_Norm (wordptr addr); /* = | X | */
-Z_long Set_Min (wordptr addr); /* = min(X) */
-Z_long Set_Max (wordptr addr); /* = max(X) */
-
-/* ===> matrix-of-booleans operations: */
-
-void Matrix_Multiplication(wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY,
- wordptr Z, N_int rowsZ, N_int colsZ);
-
-void Matrix_Product (wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY,
- wordptr Z, N_int rowsZ, N_int colsZ);
-
-void Matrix_Closure (wordptr addr, N_int rows, N_int cols);
-
-void Matrix_Transpose (wordptr X, N_int rowsX, N_int colsX,
- wordptr Y, N_int rowsY, N_int colsY);
-
-/*****************************************************************************/
-/* VERSION: 6.3 */
-/*****************************************************************************/
-/* VERSION HISTORY: */
-/*****************************************************************************/
-/* */
-/* Version 6.3 28.09.02 Added "Create_List()" and "GCD2()". */
-/* Version 6.2 15.09.02 Overhauled error handling. Fixed "GCD()". */
-/* Version 6.1 08.10.01 Make VMS linker happy: _lsb,_msb => _lsb_,_msb_ */
-/* Version 6.0 08.10.00 Corrected overflow handling. */
-/* Version 5.8 14.07.00 Added "Power()". Changed "Copy()". */
-/* Version 5.7 19.05.99 Quickened "Div_Pos()". Added "Product()". */
-/* Version 5.6 02.11.98 Leading zeros eliminated in "to_Hex()". */
-/* Version 5.5 21.09.98 Fixed bug of uninitialized "error" in Multiply. */
-/* Version 5.4 07.09.98 Fixed bug of uninitialized "error" in Divide. */
-/* Version 5.3 12.05.98 Improved Norm. Completed history. */
-/* Version 5.2 31.03.98 Improved Norm. */
-/* Version 5.1 09.03.98 No changes. */
-/* Version 5.0 01.03.98 Major additions and rewrite. */
-/* Version 4.2 16.07.97 Added is_empty, is_full. */
-/* Version 4.1 30.06.97 Added word-ins/del, move-left/right, inc/dec. */
-/* Version 4.0 23.04.97 Rewrite. Added bit shift and bool. matrix ops. */
-/* Version 3.2 04.02.97 Added interval methods. */
-/* Version 3.1 21.01.97 Fixed bug on 64 bit machines. */
-/* Version 3.0 12.01.97 Added flip. */
-/* Version 2.0 14.12.96 Efficiency and consistency improvements. */
-/* Version 1.1 08.01.96 Added Resize and ExclusiveOr. */
-/* Version 1.0 14.12.95 First version under UNIX (with Perl module). */
-/* Version 0.9 01.11.93 First version of C library under MS-DOS. */
-/* Version 0.1 ??.??.89 First version in Turbo Pascal under CP/M. */
-/* */
-/*****************************************************************************/
-/* AUTHOR: */
-/*****************************************************************************/
-/* */
-/* Steffen Beyer */
-/* mailto:sb@engelschall.com */
-/* http://www.engelschall.com/u/sb/download/ */
-/* */
-/*****************************************************************************/
-/* COPYRIGHT: */
-/*****************************************************************************/
-/* */
-/* Copyright (c) 1995 - 2002 by Steffen Beyer. */
-/* All rights reserved. */
-/* */
-/*****************************************************************************/
-/* LICENSE: */
-/*****************************************************************************/
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU Library General Public */
-/* License as published by the Free Software Foundation; either */
-/* version 2 of the License, or (at your option) any later version. */
-/* */
-/* This library 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 */
-/* Library General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU Library General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., */
-/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* */
-/* or download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0 */
-/* */
-/*****************************************************************************/
-#endif
+++ /dev/null
-/*
- * Bytecode utility functions
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-#include "objfmt.h"
-
-#include "arch.h"
-
-#include "bc-int.h"
-#include "expr-int.h"
-
-
-struct yasm_dataval {
- /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;
-
- enum { DV_EMPTY, DV_EXPR, DV_STRING } type;
-
- union {
- /*@only@*/ yasm_expr *expn;
- /*@only@*/ char *str_val;
- } data;
-};
-
-typedef struct bytecode_data {
- yasm_bytecode bc; /* base structure */
-
- /* non-converted data (linked list) */
- yasm_datavalhead datahead;
-
- /* final (converted) size of each element (in bytes) */
- unsigned char size;
-} bytecode_data;
-
-typedef struct bytecode_reserve {
- yasm_bytecode bc; /* base structure */
-
- /*@only@*/ yasm_expr *numitems; /* number of items to reserve */
- unsigned char itemsize; /* size of each item (in bytes) */
-} bytecode_reserve;
-
-typedef struct bytecode_incbin {
- yasm_bytecode bc; /* base structure */
-
- /*@only@*/ char *filename; /* file to include data from */
-
- /* starting offset to read from (NULL=0) */
- /*@only@*/ /*@null@*/ yasm_expr *start;
-
- /* maximum number of bytes to read (NULL=no limit) */
- /*@only@*/ /*@null@*/ yasm_expr *maxlen;
-} bytecode_incbin;
-
-typedef struct bytecode_align {
- yasm_bytecode bc; /* base structure */
-
- unsigned long boundary; /* alignment boundary */
-} bytecode_align;
-
-typedef struct bytecode_objfmt_data {
- yasm_bytecode bc; /* base structure */
-
- unsigned int type; /* objfmt-specific type */
- /*@dependent@*/ yasm_objfmt *of; /* objfmt that created the data */
- /*@only@*/ void *data; /* objfmt-specific data */
-} bytecode_objfmt_data;
-
-/* Static structures for when NULL is passed to conversion functions. */
-/* for Convert*ToBytes() */
-unsigned char bytes_static[16];
-
-/*@dependent@*/ static yasm_arch *cur_arch;
-
-
-void
-yasm_bc_initialize(yasm_arch *a)
-{
- cur_arch = a;
-}
-
-yasm_immval *
-yasm_imm_new_int(unsigned long int_val, unsigned long lindex)
-{
- return yasm_imm_new_expr(
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(int_val)),
- lindex));
-}
-
-yasm_immval *
-yasm_imm_new_expr(yasm_expr *expr_ptr)
-{
- yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
-
- im->val = expr_ptr;
- im->len = 0;
- im->sign = 0;
-
- return im;
-}
-
-const yasm_expr *
-yasm_ea_get_disp(const yasm_effaddr *ptr)
-{
- return ptr->disp;
-}
-
-void
-yasm_ea_set_len(yasm_effaddr *ptr, unsigned char len)
-{
- if (!ptr)
- return;
-
- /* Currently don't warn if length truncated, as this is called only from
- * an explicit override, where we expect the user knows what they're doing.
- */
-
- ptr->len = len;
-}
-
-void
-yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned char nosplit)
-{
- if (!ptr)
- return;
-
- ptr->nosplit = nosplit;
-}
-
-/*@-nullstate@*/
-void
-yasm_ea_delete(yasm_effaddr *ea)
-{
- if (cur_arch->ea_data_delete)
- cur_arch->ea_data_delete(ea);
- yasm_expr_delete(ea->disp);
- yasm_xfree(ea);
-}
-/*@=nullstate@*/
-
-/*@-nullstate@*/
-void
-yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea)
-{
- fprintf(f, "%*sDisp=", indent_level, "");
- yasm_expr_print(f, ea->disp);
- fprintf(f, "\n%*sLen=%u\n", indent_level, "", (unsigned int)ea->len);
- fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
- if (cur_arch->ea_data_print)
- cur_arch->ea_data_print(f, indent_level, ea);
-}
-/*@=nullstate@*/
-
-void
-yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
-{
- if (bc->multiple)
- bc->multiple = yasm_expr_new_tree(bc->multiple, YASM_EXPR_MUL, e,
- e->line);
- else
- bc->multiple = e;
-}
-
-yasm_bytecode *
-yasm_bc_new_common(yasm_bytecode_type type, size_t size, unsigned long lindex)
-{
- yasm_bytecode *bc = yasm_xmalloc(size);
-
- bc->type = type;
-
- bc->multiple = (yasm_expr *)NULL;
- bc->len = 0;
-
- bc->line = lindex;
-
- bc->offset = 0;
-
- bc->opt_flags = 0;
-
- return bc;
-}
-
-yasm_bytecode *
-yasm_bc_new_data(yasm_datavalhead *datahead, unsigned char size,
- unsigned long lindex)
-{
- bytecode_data *data;
-
- data = (bytecode_data *)
- yasm_bc_new_common(YASM_BC__DATA, sizeof(bytecode_data), lindex);
-
- data->datahead = *datahead;
- data->size = size;
-
- return (yasm_bytecode *)data;
-}
-
-yasm_bytecode *
-yasm_bc_new_reserve(yasm_expr *numitems, unsigned char itemsize,
- unsigned long lindex)
-{
- bytecode_reserve *reserve;
-
- reserve = (bytecode_reserve *)
- yasm_bc_new_common(YASM_BC__RESERVE, sizeof(bytecode_reserve), lindex);
-
- /*@-mustfree@*/
- reserve->numitems = numitems;
- /*@=mustfree@*/
- reserve->itemsize = itemsize;
-
- return (yasm_bytecode *)reserve;
-}
-
-yasm_bytecode *
-yasm_bc_new_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
- unsigned long lindex)
-{
- bytecode_incbin *incbin;
-
- incbin = (bytecode_incbin *)
- yasm_bc_new_common(YASM_BC__INCBIN, sizeof(bytecode_incbin), lindex);
-
- /*@-mustfree@*/
- incbin->filename = filename;
- incbin->start = start;
- incbin->maxlen = maxlen;
- /*@=mustfree@*/
-
- return (yasm_bytecode *)incbin;
-}
-
-yasm_bytecode *
-yasm_bc_new_align(unsigned long boundary, unsigned long lindex)
-{
- bytecode_align *align;
-
- align = (bytecode_align *)
- yasm_bc_new_common(YASM_BC__ALIGN, sizeof(bytecode_align), lindex);
-
- align->boundary = boundary;
-
- return (yasm_bytecode *)align;
-}
-
-yasm_bytecode *
-yasm_bc_new_objfmt_data(unsigned int type, unsigned long len, yasm_objfmt *of,
- void *data, unsigned long lindex)
-{
- bytecode_objfmt_data *objfmt_data;
-
- objfmt_data = (bytecode_objfmt_data *)
- yasm_bc_new_common(YASM_BC__OBJFMT_DATA, sizeof(bytecode_objfmt_data),
- lindex);
-
- objfmt_data->type = type;
- objfmt_data->of = of;
- /*@-mustfree@*/
- objfmt_data->data = data;
- /*@=mustfree@*/
-
- /* Yes, this breaks the paradigm just a little. But this data is very
- * unlike other bytecode data--it's internally generated after the
- * other bytecodes have been resolved, and the length is ALWAYS known.
- */
- objfmt_data->bc.len = len;
-
- return (yasm_bytecode *)objfmt_data;
-}
-
-void
-yasm_bc_delete(yasm_bytecode *bc)
-{
- bytecode_data *data;
- bytecode_reserve *reserve;
- bytecode_incbin *incbin;
- bytecode_objfmt_data *objfmt_data;
-
- if (!bc)
- return;
-
- /*@-branchstate@*/
- switch (bc->type) {
- case YASM_BC__EMPTY:
- break;
- case YASM_BC__DATA:
- data = (bytecode_data *)bc;
- yasm_dvs_delete(&data->datahead);
- break;
- case YASM_BC__RESERVE:
- reserve = (bytecode_reserve *)bc;
- yasm_expr_delete(reserve->numitems);
- break;
- case YASM_BC__INCBIN:
- incbin = (bytecode_incbin *)bc;
- yasm_xfree(incbin->filename);
- yasm_expr_delete(incbin->start);
- yasm_expr_delete(incbin->maxlen);
- break;
- case YASM_BC__ALIGN:
- break;
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (bytecode_objfmt_data *)bc;
- if (objfmt_data->of->bc_objfmt_data_delete)
- objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
- objfmt_data->data);
- else
- yasm_internal_error(
- N_("objfmt can't handle its own objfmt data bytecode"));
- break;
- default:
- if (bc->type < cur_arch->bc.type_max)
- cur_arch->bc.bc_delete(bc);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- break;
- }
- /*@=branchstate@*/
-
- yasm_expr_delete(bc->multiple);
- yasm_xfree(bc);
-}
-
-void
-yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
-{
- const bytecode_data *data;
- const bytecode_reserve *reserve;
- const bytecode_incbin *incbin;
- const bytecode_align *align;
- const bytecode_objfmt_data *objfmt_data;
-
- switch (bc->type) {
- case YASM_BC__EMPTY:
- fprintf(f, "%*s_Empty_\n", indent_level, "");
- break;
- case YASM_BC__DATA:
- data = (const bytecode_data *)bc;
- fprintf(f, "%*s_Data_\n", indent_level, "");
- fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
- (unsigned int)data->size);
- fprintf(f, "%*sElements:\n", indent_level+1, "");
- yasm_dvs_print(f, indent_level+2, &data->datahead);
- break;
- case YASM_BC__RESERVE:
- reserve = (const bytecode_reserve *)bc;
- fprintf(f, "%*s_Reserve_\n", indent_level, "");
- fprintf(f, "%*sNum Items=", indent_level, "");
- yasm_expr_print(f, reserve->numitems);
- fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
- (unsigned int)reserve->itemsize);
- break;
- case YASM_BC__INCBIN:
- incbin = (const bytecode_incbin *)bc;
- fprintf(f, "%*s_IncBin_\n", indent_level, "");
- fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
- incbin->filename);
- fprintf(f, "%*sStart=", indent_level, "");
- if (!incbin->start)
- fprintf(f, "nil (0)");
- else
- yasm_expr_print(f, incbin->start);
- fprintf(f, "%*sMax Len=", indent_level, "");
- if (!incbin->maxlen)
- fprintf(f, "nil (unlimited)");
- else
- yasm_expr_print(f, incbin->maxlen);
- fprintf(f, "\n");
- break;
- case YASM_BC__ALIGN:
- align = (const bytecode_align *)bc;
- fprintf(f, "%*s_Align_\n", indent_level, "");
- fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
- break;
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (const bytecode_objfmt_data *)bc;
- fprintf(f, "%*s_ObjFmt_Data_\n", indent_level, "");
- if (objfmt_data->of->bc_objfmt_data_print)
- objfmt_data->of->bc_objfmt_data_print(f, indent_level,
- objfmt_data->type,
- objfmt_data->data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level, "");
- break;
- default:
- if (bc->type < cur_arch->bc.type_max)
- cur_arch->bc.bc_print(f, indent_level, bc);
- else
- fprintf(f, "%*s_Unknown_\n", indent_level, "");
- break;
- }
- fprintf(f, "%*sMultiple=", indent_level, "");
- if (!bc->multiple)
- fprintf(f, "nil (1)");
- else
- yasm_expr_print(f, bc->multiple);
- fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
- fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
- fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
-}
-
-/*@null@*/ yasm_intnum *
-yasm_common_calc_bc_dist(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2)
-{
- unsigned int dist;
- yasm_intnum *intn;
-
- if (precbc2) {
- dist = precbc2->offset + precbc2->len;
- if (precbc1) {
- if (dist < precbc1->offset + precbc1->len) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len
- - dist);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
- return intn;
- }
- dist -= precbc1->offset + precbc1->len;
- }
- return yasm_intnum_new_uint(dist);
- } else {
- if (precbc1) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
- return intn;
- } else {
- return yasm_intnum_new_uint(0);
- }
- }
-}
-
-static yasm_bc_resolve_flags
-bc_resolve_data(bytecode_data *bc_data, unsigned long *len)
-{
- yasm_dataval *dv;
- size_t slen;
-
- /* Count up element sizes, rounding up string length. */
- STAILQ_FOREACH(dv, &bc_data->datahead, link) {
- switch (dv->type) {
- case DV_EMPTY:
- break;
- case DV_EXPR:
- *len += bc_data->size;
- break;
- case DV_STRING:
- slen = strlen(dv->data.str_val);
- /* find count, rounding up to nearest multiple of size */
- slen = (slen + bc_data->size - 1) / bc_data->size;
- *len += slen*bc_data->size;
- break;
- }
- }
-
- return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-static yasm_bc_resolve_flags
-bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len,
- int save, unsigned long line, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
- /*@null@*/ yasm_expr *temp;
- yasm_expr **tempp;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
-
- if (save) {
- temp = NULL;
- tempp = &reserve->numitems;
- } else {
- temp = yasm_expr_copy(reserve->numitems);
- assert(temp != NULL);
- tempp = &temp;
- }
- num = yasm_expr_get_intnum(tempp, calc_bc_dist);
- if (!num) {
- /* For reserve, just say non-constant quantity instead of allowing
- * the circular reference error to filter through.
- */
- if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT))
- yasm__error(line,
- N_("expression must not contain floating point value"));
- else
- yasm__error(line,
- N_("attempt to reserve non-constant quantity of space"));
- retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
- } else
- *len += yasm_intnum_get_uint(num)*reserve->itemsize;
- yasm_expr_delete(temp);
- return retval;
-}
-
-static yasm_bc_resolve_flags
-bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
- unsigned long line, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- FILE *f;
- /*@null@*/ yasm_expr *temp;
- yasm_expr **tempp;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- unsigned long start = 0, maxlen = 0xFFFFFFFFUL, flen;
-
- /* Try to convert start to integer value */
- if (incbin->start) {
- if (save) {
- temp = NULL;
- tempp = &incbin->start;
- } else {
- temp = yasm_expr_copy(incbin->start);
- assert(temp != NULL);
- tempp = &temp;
- }
- num = yasm_expr_get_intnum(tempp, calc_bc_dist);
- if (num)
- start = yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
- if (!num)
- return YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
-
- /* Try to convert maxlen to integer value */
- if (incbin->maxlen) {
- if (save) {
- temp = NULL;
- tempp = &incbin->maxlen;
- } else {
- temp = yasm_expr_copy(incbin->maxlen);
- assert(temp != NULL);
- tempp = &temp;
- }
- num = yasm_expr_get_intnum(tempp, calc_bc_dist);
- if (num)
- maxlen = yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
- if (!num)
- return YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
-
- /* FIXME: Search include path for filename. Save full path back into
- * filename if save is true.
- */
-
- /* Open file and determine its length */
- f = fopen(incbin->filename, "rb");
- if (!f) {
- yasm__error(line, N_("`incbin': unable to open file `%s'"),
- incbin->filename);
- return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- if (fseek(f, 0L, SEEK_END) < 0) {
- yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
- incbin->filename);
- return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
- }
- flen = (unsigned long)ftell(f);
- fclose(f);
-
- /* Compute length of incbin from start, maxlen, and len */
- if (start > flen) {
- yasm__warning(YASM_WARN_GENERAL, line,
- N_("`incbin': start past end of file `%s'"),
- incbin->filename);
- start = flen;
- }
- flen -= start;
- if (incbin->maxlen)
- if (maxlen < flen)
- flen = maxlen;
- *len += flen;
- return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-yasm_bc_resolve_flags
-yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
- /*@null@*/ yasm_expr *temp;
- yasm_expr **tempp;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
-
- bc->len = 0; /* start at 0 */
-
- switch (bc->type) {
- case YASM_BC__EMPTY:
- yasm_internal_error(N_("got empty bytecode in bc_calc_len"));
- /*break;*/
- case YASM_BC__DATA:
- retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
- break;
- case YASM_BC__RESERVE:
- retval = bc_resolve_reserve((bytecode_reserve *)bc, &bc->len,
- save, bc->line, sect, calc_bc_dist);
- break;
- case YASM_BC__INCBIN:
- retval = bc_resolve_incbin((bytecode_incbin *)bc, &bc->len,
- save, bc->line, sect, calc_bc_dist);
- break;
- case YASM_BC__ALIGN:
- /* TODO */
- yasm_internal_error(N_("TODO: align bytecode not implemented!"));
- /*break;*/
- case YASM_BC__OBJFMT_DATA:
- yasm_internal_error(N_("resolving objfmt data bytecode?"));
- /*break;*/
- default:
- if (bc->type < cur_arch->bc.type_max)
- retval = cur_arch->bc.bc_resolve(bc, save, sect,
- calc_bc_dist);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- }
-
- /* Multiply len by number of multiples */
- if (bc->multiple) {
- if (save) {
- temp = NULL;
- tempp = &bc->multiple;
- } else {
- temp = yasm_expr_copy(bc->multiple);
- assert(temp != NULL);
- tempp = &temp;
- }
- num = yasm_expr_get_intnum(tempp, calc_bc_dist);
- if (!num) {
- retval = YASM_BC_RESOLVE_UNKNOWN_LEN;
- if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT)) {
- yasm__error(bc->line,
- N_("expression must not contain floating point value"));
- retval |= YASM_BC_RESOLVE_ERROR;
- }
- } else
- bc->len *= yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
- }
-
- /* If we got an error somewhere along the line, clear out any calc len */
- if (retval & YASM_BC_RESOLVE_UNKNOWN_LEN)
- bc->len = 0;
-
- return retval;
-}
-
-static int
-bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
- const yasm_section *sect, const yasm_bytecode *bc, void *d,
- yasm_output_expr_func output_expr)
- /*@sets **bufp@*/
-{
- yasm_dataval *dv;
- size_t slen;
- size_t i;
- unsigned char *bufp_orig = *bufp;
-
- STAILQ_FOREACH(dv, &bc_data->datahead, link) {
- switch (dv->type) {
- case DV_EMPTY:
- break;
- case DV_EXPR:
- if (output_expr(&dv->data.expn, bufp, bc_data->size,
- *bufp-bufp_orig, sect, bc, 0, d))
- return 1;
- break;
- case DV_STRING:
- slen = strlen(dv->data.str_val);
- strncpy((char *)*bufp, dv->data.str_val, slen);
- *bufp += slen;
- /* pad with 0's to nearest multiple of size */
- slen %= bc_data->size;
- if (slen > 0) {
- slen = bc_data->size-slen;
- for (i=0; i<slen; i++)
- YASM_WRITE_8(*bufp, 0);
- }
- break;
- }
- }
-
- return 0;
-}
-
-static int
-bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
- unsigned long len, unsigned long line)
- /*@sets **bufp@*/
-{
- FILE *f;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- unsigned long start = 0;
-
- /* Convert start to integer value */
- if (incbin->start) {
- num = yasm_expr_get_intnum(&incbin->start, NULL);
- if (!num)
- yasm_internal_error(
- N_("could not determine start in bc_tobytes_incbin"));
- start = yasm_intnum_get_uint(num);
- }
-
- /* Open file */
- f = fopen(incbin->filename, "rb");
- if (!f) {
- yasm__error(line, N_("`incbin': unable to open file `%s'"),
- incbin->filename);
- return 1;
- }
-
- /* Seek to start of data */
- if (fseek(f, (long)start, SEEK_SET) < 0) {
- yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
- incbin->filename);
- fclose(f);
- return 1;
- }
-
- /* Read len bytes */
- if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
- yasm__error(line,
- N_("`incbin': unable to read %lu bytes from file `%s'"),
- len, incbin->filename);
- fclose(f);
- return 1;
- }
-
- *bufp += len;
- fclose(f);
- return 0;
-}
-
-/*@null@*/ /*@only@*/ unsigned char *
-yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
- /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr,
- /*@null@*/ yasm_output_bc_objfmt_data_func
- output_bc_objfmt_data)
- /*@sets *buf@*/
-{
- /*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
- unsigned char *origbuf, *destbuf;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- bytecode_objfmt_data *objfmt_data;
- unsigned long datasize;
- int error = 0;
-
- if (bc->multiple) {
- num = yasm_expr_get_intnum(&bc->multiple, NULL);
- if (!num)
- yasm_internal_error(
- N_("could not determine multiple in bc_tobytes"));
- *multiple = yasm_intnum_get_uint(num);
- if (*multiple == 0) {
- *bufsize = 0;
- return NULL;
- }
- } else
- *multiple = 1;
-
- datasize = bc->len / (*multiple);
- *bufsize = datasize;
-
- if (bc->type == YASM_BC__RESERVE) {
- *gap = 1;
- return NULL; /* we didn't allocate a buffer */
- }
-
- *gap = 0;
-
- if (*bufsize < datasize) {
- mybuf = yasm_xmalloc(sizeof(bc->len));
- origbuf = mybuf;
- destbuf = mybuf;
- } else {
- origbuf = buf;
- destbuf = buf;
- }
-
- switch (bc->type) {
- case YASM_BC__EMPTY:
- yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
- /*break;*/
- case YASM_BC__DATA:
- error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
- output_expr);
- break;
- case YASM_BC__INCBIN:
- error = bc_tobytes_incbin((bytecode_incbin *)bc, &destbuf, bc->len,
- bc->line);
- break;
- case YASM_BC__ALIGN:
- /* TODO */
- yasm_internal_error(N_("TODO: align bytecode not implemented!"));
- /*break;*/
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (bytecode_objfmt_data *)bc;
- if (output_bc_objfmt_data)
- error = output_bc_objfmt_data(objfmt_data->type,
- objfmt_data->data, &destbuf);
- else
- yasm_internal_error(
- N_("Have objfmt data bytecode but no way to output it"));
- break;
- default:
- if (bc->type < cur_arch->bc.type_max)
- error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d,
- output_expr);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- }
-
- if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
- yasm_internal_error(
- N_("written length does not match optimized length"));
- return mybuf;
-}
-
-yasm_bytecode *
-yasm_bcs_last(yasm_bytecodehead *headp)
-{
- return STAILQ_LAST(headp, yasm_bytecode, link);
-}
-
-void
-yasm_bcs_delete(yasm_bytecodehead *headp)
-{
- yasm_bytecode *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- yasm_bc_delete(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
-}
-
-yasm_bytecode *
-yasm_bcs_append(yasm_bytecodehead *headp, yasm_bytecode *bc)
-{
- if (bc) {
- if (bc->type != YASM_BC__EMPTY) {
- STAILQ_INSERT_TAIL(headp, bc, link);
- return bc;
- } else {
- yasm_xfree(bc);
- }
- }
- return (yasm_bytecode *)NULL;
-}
-
-void
-yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp)
-{
- yasm_bytecode *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
- yasm_bc_print(f, indent_level+1, cur);
- }
-}
-
-int
-yasm_bcs_traverse(yasm_bytecodehead *headp, void *d,
- int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
-{
- yasm_bytecode *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- int retval = func(cur, d);
- if (retval != 0)
- return retval;
- }
- return 0;
-}
-
-yasm_dataval *
-yasm_dv_new_expr(yasm_expr *expn)
-{
- yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
-
- retval->type = DV_EXPR;
- retval->data.expn = expn;
-
- return retval;
-}
-
-yasm_dataval *
-yasm_dv_new_string(char *str_val)
-{
- yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
-
- retval->type = DV_STRING;
- retval->data.str_val = str_val;
-
- return retval;
-}
-
-void
-yasm_dvs_delete(yasm_datavalhead *headp)
-{
- yasm_dataval *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- switch (cur->type) {
- case DV_EXPR:
- yasm_expr_delete(cur->data.expn);
- break;
- case DV_STRING:
- yasm_xfree(cur->data.str_val);
- break;
- default:
- break;
- }
- yasm_xfree(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
-}
-
-yasm_dataval *
-yasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv)
-{
- if (dv) {
- STAILQ_INSERT_TAIL(headp, dv, link);
- return dv;
- }
- return (yasm_dataval *)NULL;
-}
-
-void
-yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
-{
- yasm_dataval *cur;
-
- STAILQ_FOREACH(cur, head, link) {
- switch (cur->type) {
- case DV_EMPTY:
- fprintf(f, "%*sEmpty\n", indent_level, "");
- break;
- case DV_EXPR:
- fprintf(f, "%*sExpr=", indent_level, "");
- yasm_expr_print(f, cur->data.expn);
- fprintf(f, "\n");
- break;
- case DV_STRING:
- fprintf(f, "%*sString=%s\n", indent_level, "",
- cur->data.str_val);
- break;
- }
- }
-}
+++ /dev/null
-/* $IdPath$
- * YASM bytecode utility functions header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_BYTECODE_H
-#define YASM_BYTECODE_H
-
-typedef struct yasm_effaddr yasm_effaddr;
-typedef struct yasm_immval yasm_immval;
-typedef /*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval)
- yasm_datavalhead;
-typedef struct yasm_dataval yasm_dataval;
-
-/* Additional types may be architecture-defined starting at
- * YASM_BYTECODE_TYPE_BASE.
- */
-typedef enum {
- YASM_BC__EMPTY = 0,
- YASM_BC__DATA,
- YASM_BC__RESERVE,
- YASM_BC__INCBIN,
- YASM_BC__ALIGN,
- YASM_BC__OBJFMT_DATA
-} yasm_bytecode_type;
-#define YASM_BYTECODE_TYPE_BASE YASM_BC__OBJFMT_DATA+1
-
-void yasm_bc_initialize(yasm_arch *a);
-
-/*@only@*/ yasm_immval *yasm_imm_new_int(unsigned long int_val,
- unsigned long lindex);
-/*@only@*/ yasm_immval *yasm_imm_new_expr(/*@keep@*/ yasm_expr *e);
-
-/*@observer@*/ const yasm_expr *yasm_ea_get_disp(const yasm_effaddr *ea);
-void yasm_ea_set_len(yasm_effaddr *ea, unsigned char len);
-void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned char nosplit);
-void yasm_ea_delete(/*@only@*/ yasm_effaddr *ea);
-void yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea);
-
-void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
-
-/*@only@*/ yasm_bytecode *yasm_bc_new_common(yasm_bytecode_type type,
- size_t datasize,
- unsigned long lindex);
-/*@only@*/ yasm_bytecode *yasm_bc_new_data(yasm_datavalhead *datahead,
- unsigned char size,
- unsigned long lindex);
-/*@only@*/ yasm_bytecode *yasm_bc_new_reserve(/*@only@*/ yasm_expr *numitems,
- unsigned char itemsize,
- unsigned long lindex);
-/*@only@*/ yasm_bytecode *yasm_bc_new_incbin
- (/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
- /*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long lindex);
-/*@only@*/ yasm_bytecode *yasm_bc_new_align(unsigned long boundary,
- unsigned long lindex);
-/*@only@*/ yasm_bytecode *yasm_bc_new_objfmt_data
- (unsigned int type, unsigned long len, yasm_objfmt *of,
- /*@only@*/ void *data, unsigned long lindex);
-
-void yasm_bc_delete(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
-
-void yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-
-/* A common version of a calc_bc_dist function that should work for the final
- * stages of optimizers as well as in objfmt expr output functions. It takes
- * the offsets from the bytecodes.
- */
-/*@null@*/ yasm_intnum *yasm_common_calc_bc_dist
- (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2);
-
-/* Return value flags for bc_resolve() */
-typedef enum {
- YASM_BC_RESOLVE_NONE = 0, /* Ok, but length is not minimum */
- YASM_BC_RESOLVE_ERROR = 1<<0, /* Error found, output */
- YASM_BC_RESOLVE_MIN_LEN = 1<<1, /* Length is minimum possible */
- YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /* Length indeterminate */
-} yasm_bc_resolve_flags;
-
-/* Resolves labels in bytecode, and calculates its length.
- * Tries to minimize the length as much as possible.
- * Returns whether the length is the minimum possible, indeterminate, and
- * if there was an error recognized and output during execution (see above
- * for return flags).
- * Note: sometimes it's impossible to determine if a length is the minimum
- * possible. In this case, this function returns that the length is NOT
- * the minimum.
- * resolve_label is the function used to determine the value (offset) of a
- * in-file label (eg, not an EXTERN variable, which is indeterminate).
- * When save is zero, this function does *not* modify bc other than the
- * length/size values (i.e. it doesn't keep the values returned by
- * resolve_label except temporarily to try to minimize the length).
- * When save is nonzero, all fields in bc may be modified by this function.
- */
-yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
- const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
-
-/* Converts the bytecode bc into its byte representation.
- * Inputs:
- * bc - the bytecode to convert
- * buf - where to put the byte representation
- * bufsize - the size of buf
- * d - the data to pass to each call to output_expr()
- * output_expr - the function to call to convert expressions to byte rep
- * output_bc_objfmt_data - the function to call to convert objfmt data
- * bytecodes into their byte representation
- * Outputs:
- * bufsize - the size of the generated data.
- * multiple - the number of times the data should be dup'ed when output
- * gap - indicates the data does not really need to exist in the
- * object file. buf's contents are undefined if true.
- * Returns either NULL (if buf was big enough to hold the entire byte
- * representation), or a newly allocated buffer that should be used instead
- * of buf for reading the byte representation.
- */
-/*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
- (yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
- /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
- const yasm_section *sect, void *d, yasm_output_expr_func output_expr,
- /*@null@*/ yasm_output_bc_objfmt_data_func output_bc_objfmt_data)
- /*@sets *buf@*/;
-
-/* void yasm_bcs_initialize(yasm_bytecodehead *headp); */
-#define yasm_bcs_initialize(headp) STAILQ_INIT(headp)
-
-/* yasm_bytecode *yasm_bcs_first(yasm_bytecodehead *headp); */
-#define yasm_bcs_first(headp) STAILQ_FIRST(headp)
-
-/*@null@*/ yasm_bytecode *yasm_bcs_last(yasm_bytecodehead *headp);
-void yasm_bcs_delete(yasm_bytecodehead *headp);
-
-/* Adds bc to the list of bytecodes headp.
- * NOTE: Does not make a copy of bc; so don't pass this function
- * static or local variables, and discard the bc pointer after calling
- * this function. If bc was actually appended (it wasn't NULL or empty),
- * then returns bc, otherwise returns NULL.
- */
-/*@only@*/ /*@null@*/ yasm_bytecode *yasm_bcs_append
- (yasm_bytecodehead *headp,
- /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
-
-void yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp);
-
-/* Calls func for each bytecode in the linked list of bytecodes pointed to by
- * headp. The data pointer d is passed to each func call.
- *
- * Stops early (and returns func's return value) if func returns a nonzero
- * value. Otherwise returns 0.
- */
-int yasm_bcs_traverse(yasm_bytecodehead *headp, /*@null@*/ void *d,
- int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
-
-yasm_dataval *yasm_dv_new_expr(/*@keep@*/ yasm_expr *expn);
-yasm_dataval *yasm_dv_new_float(/*@keep@*/ yasm_floatnum *flt);
-yasm_dataval *yasm_dv_new_string(/*@keep@*/ char *str_val);
-
-/* void yasm_dvs_initialize(yasm_datavalhead *headp); */
-#define yasm_dvs_initialize(headp) STAILQ_INIT(headp)
-
-void yasm_dvs_delete(yasm_datavalhead *headp);
-
-/* Adds dv to the list of datavals headp.
- * NOTE: Does not make a copy of dv; so don't pass this function
- * static or local variables, and discard the dv pointer after calling
- * this function. If dv was actually appended (it wasn't NULL), then
- * returns dv, otherwise returns NULL.
- */
-/*@null@*/ yasm_dataval *yasm_dvs_append
- (yasm_datavalhead *headp, /*@returned@*/ /*@null@*/ yasm_dataval *dv);
-
-void yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head);
-
-#endif
+++ /dev/null
-/* $IdPath$
- * <sys/queue.h> implementation for systems that don't have it.
- *
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * 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 University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $
- */
-
-#ifndef SYS_QUEUE_H
-#define SYS_QUEUE_H
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * singly-linked tail queues, lists, tail queues, and circular queues.
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction. Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A singly-linked tail queue is headed by a pair of pointers, one to the
- * head of the list and the other to the tail of the list. The elements are
- * singly linked for minimum space and pointer manipulation overhead at the
- * expense of O(n) removal for arbitrary elements. New elements can be added
- * to the list after an existing element, at the head of the list, or at the
- * end of the list. Elements being removed from the head of the tail queue
- * should use the explicit macro for this purpose for optimum efficiency.
- * A singly-linked tail queue may only be traversed in the forward direction.
- * Singly-linked tail queues are ideal for applications with large datasets
- * and few or no removals or for implementing a FIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *
- *
- * SLIST LIST STAILQ TAILQ CIRCLEQ
- * _HEAD + + + + +
- * _ENTRY + + + + +
- * _INIT + + + + +
- * _EMPTY + + + + +
- * _FIRST + + + + +
- * _NEXT + + + + +
- * _PREV - - - + +
- * _LAST - - + + +
- * _FOREACH + + + + +
- * _FOREACH_REVERSE - - - + +
- * _INSERT_HEAD + + + + +
- * _INSERT_BEFORE - + - + +
- * _INSERT_AFTER + + + + +
- * _INSERT_TAIL - - + + +
- * _REMOVE_HEAD + - + - -
- * _REMOVE + + + + +
- *
- */
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define SLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define SLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
-
-#define SLIST_FIRST(head) ((head)->slh_first)
-
-#define SLIST_FOREACH(var, head, field) \
- for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define SLIST_INIT(head) { \
- (head)->slh_first = NULL; \
-}
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
- (elm)->field.sle_next = (slistelm)->field.sle_next; \
- (slistelm)->field.sle_next = (elm); \
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.sle_next = (head)->slh_first; \
- (head)->slh_first = (elm); \
-} while (0)
-
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_REMOVE_HEAD(head, field) do { \
- (head)->slh_first = (head)->slh_first->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do { \
- if ((head)->slh_first == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
- } \
- else { \
- struct type *curelm = (head)->slh_first; \
- while( curelm->field.sle_next != (elm) ) \
- curelm = curelm->field.sle_next; \
- curelm->field.sle_next = \
- curelm->field.sle_next->field.sle_next; \
- } \
-} while (0)
-
-/*
- * Singly-linked Tail queue definitions.
- */
-#define STAILQ_HEAD(name, type) \
-struct name { \
- /*@reldef@*/ struct type *stqh_first;/* first element */ \
- /*@reldef@*/ struct type **stqh_last;/* addr of last next element */ \
-}
-
-#define STAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).stqh_first }
-
-#define STAILQ_ENTRY(type) \
-struct { \
- /*@reldef@*/ struct type *stqe_next; /* next element */ \
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
-
-#define STAILQ_INIT(head) do { \
- (head)->stqh_first = NULL; \
- /*@-immediatetrans@*/ \
- (head)->stqh_last = &(head)->stqh_first; \
- /*@=immediatetrans@*/ \
-} while (0)
-
-#define STAILQ_FIRST(head) ((head)->stqh_first)
-
-#define STAILQ_LAST(head, type, field) \
- (STAILQ_EMPTY(head) ? \
- NULL : \
- ((struct type *) \
- ((char *)((head)->stqh_last) - offsetof(struct type, field))))
-
-#define STAILQ_FOREACH(var, head, field) \
- for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
-
-#define STAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
- (head)->stqh_last = &(elm)->field.stqe_next; \
- (head)->stqh_first = (elm); \
-} while (0)
-
-#define STAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.stqe_next = NULL; \
- /*@-onlytrans -mustfree -immediatetrans@*/ \
- *(head)->stqh_last = (elm); \
- (head)->stqh_last = &(elm)->field.stqe_next; \
- /*@=onlytrans =mustfree =immediatetrans@*/ \
-} while (0)
-
-#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
- if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
- (head)->stqh_last = &(elm)->field.stqe_next; \
- (tqelm)->field.stqe_next = (elm); \
-} while (0)
-
-#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
-
-#define STAILQ_REMOVE_HEAD(head, field) do { \
- if (((head)->stqh_first = \
- (head)->stqh_first->field.stqe_next) == NULL) \
- (head)->stqh_last = &(head)->stqh_first; \
-} while (0)
-
-#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
- if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
- (head)->stqh_last = &(head)->stqh_first; \
-} while (0)
-
-#define STAILQ_REMOVE(head, elm, type, field) do { \
- if ((head)->stqh_first == (elm)) { \
- STAILQ_REMOVE_HEAD(head, field); \
- } \
- else { \
- struct type *curelm = (head)->stqh_first; \
- while( curelm->field.stqe_next != (elm) ) \
- curelm = curelm->field.stqe_next; \
- if((curelm->field.stqe_next = \
- curelm->field.stqe_next->field.stqe_next) == NULL) \
- (head)->stqh_last = &(curelm)->field.stqe_next; \
- } \
-} while (0)
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-
-#define LIST_FIRST(head) ((head)->lh_first)
-
-#define LIST_FOREACH(var, head, field) \
- for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
-
-#define LIST_INIT(head) do { \
- (head)->lh_first = NULL; \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (0)
-
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-
-#define TAILQ_FOREACH(var, head, field) \
- for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for ((var) = TAILQ_LAST((head), headname); \
- (var); \
- (var) = TAILQ_PREV((var), headname, field))
-
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
-
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = (head)->cqh_first; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_next)
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = (head)->cqh_last; \
- (var) != (void *)(head); \
- (var) = (var)->field.cqe_prev)
-
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-
-#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
-
-#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-} while (0)
-
-#endif /* !SYS_QUEUE_H */
+++ /dev/null
-/* $IdPath$
- * YASM core (used by many modules/header files) type definitions.
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_CORETYPE_H
-#define YASM_CORETYPE_H
-
-typedef struct yasm_arch yasm_arch;
-
-typedef struct yasm_preproc yasm_preproc;
-typedef struct yasm_parser yasm_parser;
-typedef struct yasm_optimizer yasm_optimizer;
-typedef struct yasm_objfmt yasm_objfmt;
-typedef struct yasm_dbgfmt yasm_dbgfmt;
-
-typedef struct yasm_bytecode yasm_bytecode;
-typedef /*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode)
- yasm_bytecodehead;
-
-typedef struct yasm_section yasm_section;
-typedef /*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section)
- yasm_sectionhead;
-
-typedef struct yasm_symrec yasm_symrec;
-
-typedef struct yasm_expr yasm_expr;
-typedef struct yasm_intnum yasm_intnum;
-typedef struct yasm_floatnum yasm_floatnum;
-
-typedef struct yasm_linemgr yasm_linemgr;
-
-typedef enum {
- YASM_EXPR_ADD,
- YASM_EXPR_SUB,
- YASM_EXPR_MUL,
- YASM_EXPR_DIV,
- YASM_EXPR_SIGNDIV,
- YASM_EXPR_MOD,
- YASM_EXPR_SIGNMOD,
- YASM_EXPR_NEG,
- YASM_EXPR_NOT,
- YASM_EXPR_OR,
- YASM_EXPR_AND,
- YASM_EXPR_XOR,
- YASM_EXPR_SHL,
- YASM_EXPR_SHR,
- YASM_EXPR_LOR,
- YASM_EXPR_LAND,
- YASM_EXPR_LNOT,
- YASM_EXPR_LT,
- YASM_EXPR_GT,
- YASM_EXPR_EQ,
- YASM_EXPR_LE,
- YASM_EXPR_GE,
- YASM_EXPR_NE,
- YASM_EXPR_SEG,
- YASM_EXPR_WRT,
- YASM_EXPR_SEGOFF, /* The ':' in SEG:OFF */
- YASM_EXPR_IDENT /* no operation, just a value */
-} yasm_expr_op;
-
-/* EXTERN and COMMON are mutually exclusive */
-typedef enum {
- YASM_SYM_LOCAL = 0, /* default, local only */
- YASM_SYM_GLOBAL = 1 << 0, /* if it's declared GLOBAL */
- YASM_SYM_COMMON = 1 << 1, /* if it's declared COMMON */
- YASM_SYM_EXTERN = 1 << 2 /* if it's declared EXTERN */
-} yasm_sym_vis;
-
-/* Determines the distance, in bytes, between the starting offsets of two
- * bytecodes in a section.
- * Inputs: sect, the section in which the bytecodes reside.
- * precbc1, preceding bytecode to the first bytecode
- * precbc2, preceding bytecode to the second bytecode
- * Outputs: dist, the distance in bytes (bc2-bc1)
- * Returns distance in bytes (bc2-bc1), or NULL if the distance was
- * indeterminate.
- */
-typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
- (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2);
-
-/* Converts an expr to its byte representation. Usually implemented by
- * object formats to keep track of relocations and verify legal expressions.
- * Inputs:
- * ep - (double) pointer to the expression to output
- * bufp - (double) pointer to buffer to contain byte representation
- * valsize - the size (in bytes) to be used for the byte rep
- * offset - the offset (in bytes) of the expr contents from the bc start
- * sect - current section (usually passed into higher-level calling fct)
- * bc - current bytecode (usually passed into higher-level calling fct)
- * rel - should the expr be treated as PC/IP-relative? (nonzero=yes)
- * d - objfmt-specific data (passed into higher-level calling fct)
- * Returns nonzero if an error occurred, 0 otherwise
- */
-typedef int (*yasm_output_expr_func)
- (yasm_expr **ep, unsigned char **bufp, unsigned long valsize,
- unsigned long offset, /*@observer@*/ const yasm_section *sect,
- /*@observer@*/ const yasm_bytecode *bc, int rel, /*@null@*/ void *d)
- /*@uses *ep@*/ /*@sets **bufp@*/;
-
-/* Converts a objfmt data bytecode into its byte representation. Usually
- * implemented by object formats to output their own generated data.
- * Inputs:
- * type - objfmt-specific type
- * data - objfmt-specific data
- * bufp - (double) pointer to buffer to contain byte representation
- * bufp is guaranteed to have enough space to store the data into (as given
- * by the original bc_new_objfmt_data() call).
- * Returns nonzero if an error occurred, 0 otherwise.
- */
-typedef int (*yasm_output_bc_objfmt_data_func)
- (unsigned int type, /*@observer@*/ void *data, unsigned char **bufp)
- /*@sets **bufp@*/;
-#endif
+++ /dev/null
-/* $IdPath$
- * YASM debug format module interface header file
- *
- * Copyright (C) 2002 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.
- *
- * 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.
- */
-#ifndef YASM_DBGFMT_H
-#define YASM_DBGFMT_H
-
-/* Interface to the object format module(s) */
-struct yasm_dbgfmt {
- /* one-line description of the format */
- const char *name;
-
- /* keyword used to select format on the command line */
- const char *keyword;
-
- /* Initializes debug output. Must be called before any other debug
- * format functions. The filenames are provided solely for informational
- * purposes. May be NULL if not needed by the debug format.
- */
- void (*initialize) (const char *in_filename, const char *obj_filename);
-
- /* Cleans up anything allocated by initialize.
- * May be NULL if not needed by the debug format.
- */
- void (*cleanup) (void);
-};
-
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/dbgfmts/null/Makefile.inc
-
-include src/dbgfmts/null/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-null.la
-
-yasm_null_la_SOURCES = \
- src/dbgfmts/null/null-dbgfmt.c
-yasm_null_la_LDFLAGS = -module -avoid-version
-yasm_null_la_LIBADD = libyasm.la
-yasm_LDADD += -dlpreopen yasm-null.la
+++ /dev/null
-/*
- * Null debugging format (creates NO debugging information)
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "dbgfmt.h"
-
-
-/* Define preproc structure -- see preproc.h for details */
-yasm_dbgfmt yasm_null_LTX_dbgfmt = {
- "No debugging info",
- "null",
- NULL, /*null_dbgfmt_initialize*/
- NULL /*null_dbgfmt_cleanup*/
-};
+++ /dev/null
-/*
- * Error and warning reporting and related functions.
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include <ctype.h>
-
-#ifdef STDC_HEADERS
-# include <stdarg.h>
-#endif
-
-#include "linemgr.h"
-#include "errwarn.h"
-
-
-#define MSG_MAXSIZE 1024
-
-/* Default handlers for replacable functions */
-static /*@exits@*/ void def_internal_error_
- (const char *file, unsigned int line, const char *message);
-static /*@exits@*/ void def_fatal(const char *message);
-static const char *def_gettext_hook(const char *msgid);
-
-/* Storage for errwarn's "extern" functions */
-/*@exits@*/ void (*yasm_internal_error_)
- (const char *file, unsigned int line, const char *message)
- = def_internal_error_;
-/*@exits@*/ void (*yasm_fatal) (const char *message) = def_fatal;
-const char * (*yasm_gettext_hook) (const char *msgid) = def_gettext_hook;
-
-/* Enabled warnings. See errwarn.h for a list. */
-static unsigned long warn_class_enabled;
-
-/* Total error count */
-static unsigned int error_count;
-
-/* Total warning count */
-static unsigned int warning_count;
-
-typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data)
- errwarndatahead;
-static /*@only@*/ /*@null@*/ errwarndatahead errwarns;
-
-typedef struct errwarn_data {
- /*@reldef@*/ SLIST_ENTRY(errwarn_data) link;
-
- enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type;
-
- unsigned long line;
- /* FIXME: This should not be a fixed size. But we don't have vasprintf()
- * right now. */
- char msg[MSG_MAXSIZE];
-} errwarn_data;
-
-/* Last inserted error/warning. Used to speed up insertions. */
-static /*@null@*/ errwarn_data *previous_we;
-
-/* Static buffer for use by conv_unprint(). */
-static char unprint[5];
-
-
-static const char *
-def_gettext_hook(const char *msgid)
-{
- return msgid;
-}
-
-void
-yasm_errwarn_initialize(void)
-{
- /* Default enabled warnings. See errwarn.h for a list. */
- warn_class_enabled =
- (1UL<<YASM_WARN_GENERAL) | (1UL<<YASM_WARN_UNREC_CHAR) |
- (1UL<<YASM_WARN_PREPROC);
-
- error_count = 0;
- warning_count = 0;
- SLIST_INIT(&errwarns);
- previous_we = NULL;
-}
-
-void
-yasm_errwarn_cleanup(void)
-{
- errwarn_data *we;
-
- /* Delete all error/warnings */
- while (!SLIST_EMPTY(&errwarns)) {
- we = SLIST_FIRST(&errwarns);
-
- SLIST_REMOVE_HEAD(&errwarns, link);
- yasm_xfree(we);
- }
-}
-
-/* Convert a possibly unprintable character into a printable string, using
- * standard cat(1) convention for unprintable characters.
- */
-char *
-yasm__conv_unprint(char ch)
-{
- int pos = 0;
-
- if (((ch & ~0x7F) != 0) /*!isascii(ch)*/ && !isprint(ch)) {
- unprint[pos++] = 'M';
- unprint[pos++] = '-';
- ch &= toascii(ch);
- }
- if (iscntrl(ch)) {
- unprint[pos++] = '^';
- unprint[pos++] = (ch == '\177') ? '?' : ch | 0100;
- } else
- unprint[pos++] = ch;
- unprint[pos] = '\0';
-
- return unprint;
-}
-
-/* Report an internal error. Essentially a fatal error with trace info.
- * Exit immediately because it's essentially an assert() trap.
- */
-static void
-def_internal_error_(const char *file, unsigned int line, const char *message)
-{
- fprintf(stderr,
- yasm_gettext_hook(N_("INTERNAL ERROR at %s, line %u: %s\n")),
- file, line, yasm_gettext_hook(message));
-#ifdef HAVE_ABORT
- abort();
-#else
- exit(EXIT_FAILURE);
-#endif
-}
-
-/* Report a fatal error. These are unrecoverable (such as running out of
- * memory), so just exit immediately.
- */
-static void
-def_fatal(const char *message)
-{
- fprintf(stderr, yasm_gettext_hook(N_("FATAL: %s\n")),
- yasm_gettext_hook(message));
-#ifdef HAVE_ABORT
- abort();
-#else
- exit(EXIT_FAILURE);
-#endif
-}
-
-/* Create an errwarn structure in the correct linked list location.
- * If replace_parser_error is nonzero, overwrites the last error if its
- * type is WE_PARSERERROR.
- */
-static errwarn_data *
-errwarn_data_new(unsigned long lindex, int replace_parser_error)
-{
- errwarn_data *first, *next, *ins_we, *we;
- enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
-
- /* Find the entry with either line=lindex or the last one with line<lindex.
- * Start with the last entry added to speed the search.
- */
- ins_we = previous_we;
- first = SLIST_FIRST(&errwarns);
- if (!ins_we || !first)
- action = INS_HEAD;
- while (action == INS_NONE) {
- next = SLIST_NEXT(ins_we, link);
- if (lindex < ins_we->line) {
- if (ins_we == first)
- action = INS_HEAD;
- else
- ins_we = first;
- } else if (!next)
- action = INS_AFTER;
- else if (lindex >= ins_we->line && lindex < next->line)
- action = INS_AFTER;
- else
- ins_we = next;
- }
-
- if (replace_parser_error && ins_we && ins_we->type == WE_PARSERERROR) {
- /* overwrite last error */
- we = ins_we;
- } else {
- /* add a new error */
- we = yasm_xmalloc(sizeof(errwarn_data));
-
- we->type = WE_UNKNOWN;
- we->line = lindex;
-
- if (action == INS_HEAD)
- SLIST_INSERT_HEAD(&errwarns, we, link);
- else if (action == INS_AFTER) {
- assert(ins_we != NULL);
- SLIST_INSERT_AFTER(ins_we, we, link);
- } else
- yasm_internal_error(N_("Unexpected errwarn insert action"));
- }
-
- /* Remember previous err/warn */
- previous_we = we;
-
- return we;
-}
-
-/* Register an error at line lindex. Does not print the error, only stores it
- * for output_all() to print.
- */
-void
-yasm__error_va(unsigned long lindex, const char *fmt, va_list va)
-{
- errwarn_data *we = errwarn_data_new(lindex, 1);
-
- we->type = WE_ERROR;
-
-#ifdef HAVE_VSNPRINTF
- vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
-#else
- vsprintf(we->msg, yasm_gettext_hook(fmt), va);
-#endif
-
- error_count++;
-}
-
-/* Register an warning at line lindex. Does not print the warning, only stores
- * it for output_all() to print.
- */
-void
-yasm__warning_va(yasm_warn_class num, unsigned long lindex, const char *fmt,
- va_list va)
-{
- errwarn_data *we;
-
- if (!(warn_class_enabled & (1UL<<num)))
- return; /* warning is part of disabled class */
-
- we = errwarn_data_new(lindex, 0);
-
- we->type = WE_WARNING;
-
-#ifdef HAVE_VSNPRINTF
- vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
-#else
- vsprintf(we->msg, yasm_gettext_hook(fmt), va);
-#endif
-
- warning_count++;
-}
-
-/* Register an error at line lindex. Does not print the error, only stores it
- * for output_all() to print.
- */
-void
-yasm__error(unsigned long lindex, const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- yasm__error_va(lindex, fmt, va);
- va_end(va);
-}
-
-/* Register an warning at line lindex. Does not print the warning, only stores
- * it for output_all() to print.
- */
-void
-yasm__warning(yasm_warn_class num, unsigned long lindex, const char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- yasm__warning_va(num, lindex, fmt, va);
- va_end(va);
-}
-
-/* Parser error handler. Moves YACC-style error into our error handling
- * system.
- */
-void
-yasm__parser_error(unsigned long lindex, const char *s)
-{
- yasm__error(lindex, N_("parser error: %s"), s);
- previous_we->type = WE_PARSERERROR;
-}
-
-void
-yasm_warn_enable(yasm_warn_class num)
-{
- warn_class_enabled |= (1UL<<num);
-}
-
-void
-yasm_warn_disable(yasm_warn_class num)
-{
- warn_class_enabled &= ~(1UL<<num);
-}
-
-void
-yasm_warn_disable_all(void)
-{
- warn_class_enabled = 0;
-}
-
-unsigned int
-yasm_get_num_errors(int warning_as_error)
-{
- if (warning_as_error)
- return error_count+warning_count;
- else
- return error_count;
-}
-
-void
-yasm_errwarn_output_all(yasm_linemgr *lm, int warning_as_error,
- void (*print_error) (const char *fn, unsigned long line, const char *msg),
- void (*print_warning) (const char *fn, unsigned long line,
- const char *msg))
-{
- errwarn_data *we;
- const char *filename;
- unsigned long line;
-
- /* If we're treating warnings as errors, tell the user about it. */
- if (warning_as_error && warning_as_error != 2) {
- print_error("", 0,
- yasm_gettext_hook(N_("warnings being treated as errors")));
- warning_as_error = 2;
- }
-
- /* Output error/warnings. */
- SLIST_FOREACH(we, &errwarns, link) {
- /* Output error/warning */
- lm->lookup(we->line, &filename, &line);
- if (we->type == WE_ERROR)
- print_error(filename, line, we->msg);
- else
- print_warning(filename, line, we->msg);
- }
-}
+++ /dev/null
-/* $IdPath$
- * YASM error and warning reporting and related functions header file.
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_ERRWARN_H
-#define YASM_ERRWARN_H
-
-/* Warning classes (may be enabled/disabled). */
-typedef enum {
- YASM_WARN_GENERAL = 0, /* non-specific warnings */
- YASM_WARN_UNREC_CHAR, /* unrecognized characters (while tokenizing) */
- YASM_WARN_PREPROC /* preprocessor warnings */
-} yasm_warn_class;
-
-/* Initialize any internal data structures. */
-void yasm_errwarn_initialize(void);
-
-/* Cleans up any memory allocated by initialize or other functions. */
-void yasm_errwarn_cleanup(void);
-
-/* Reporting point of internal errors. These are usually due to sanity
- * check failures in the code.
- * This function must NOT return to calling code. Either exit or longjmp.
- */
-extern /*@exits@*/ void (*yasm_internal_error_)
- (const char *file, unsigned int line, const char *message);
-#define yasm_internal_error(msg) \
- yasm_internal_error_(__FILE__, __LINE__, msg)
-
-/* Reporting point of fatal errors.
- * This function must NOT return to calling code. Either exit or longjmp.
- */
-extern /*@exits@*/ void (*yasm_fatal) (const char *message);
-
-/* va_list versions of the below two functions */
-void yasm__error_va(unsigned long lindex, const char *, va_list va);
-void yasm__warning_va(yasm_warn_class, unsigned long lindex, const char *,
- va_list va);
-
-void yasm__error(unsigned long lindex, const char *, ...) /*@printflike@*/;
-void yasm__warning(yasm_warn_class, unsigned long lindex, const char *, ...)
- /*@printflike@*/;
-
-/* Logs a parser error. These can be overwritten by non-parser errors on
- * the same line.
- */
-void yasm__parser_error(unsigned long lindex, const char *);
-
-/* Enables/disables a class of warnings. */
-void yasm_warn_enable(yasm_warn_class);
-void yasm_warn_disable(yasm_warn_class);
-void yasm_warn_disable_all(void);
-
-/* Returns total number of errors logged to this point.
- * If warning_as_error is nonzero, warnings are treated as errors.
- */
-unsigned int yasm_get_num_errors(int warning_as_error);
-
-/* Outputs all errors/warnings by calling print_error and print_warning. */
-void yasm_errwarn_output_all
- (yasm_linemgr *lm, int warning_as_error,
- void (*print_error) (const char *fn, unsigned long line, const char *msg),
- void (*print_warning) (const char *fn, unsigned long line,
- const char *msg));
-
-/* Convert a possibly unprintable character into a printable string. */
-char *yasm__conv_unprint(char ch);
-
-/* Map to gettext() if gettext is being used. */
-extern const char * (*yasm_gettext_hook) (const char *msgid);
-
-#endif
+++ /dev/null
-/* $IdPath$
- * Expressions internal structures header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_EXPR_INT_H
-#define YASM_EXPR_INT_H
-
-/* Types listed in canonical sorting order. See expr_order_terms(). */
-typedef enum {
- YASM_EXPR_NONE = 0,
- YASM_EXPR_REG = 1<<0,
- YASM_EXPR_INT = 1<<1,
- YASM_EXPR_FLOAT = 1<<2,
- YASM_EXPR_SYM = 1<<3,
- YASM_EXPR_EXPR = 1<<4
-} yasm_expr__type;
-
-struct yasm_expr__item {
- yasm_expr__type type;
- union {
- yasm_symrec *sym;
- yasm_expr *expn;
- yasm_intnum *intn;
- yasm_floatnum *flt;
- unsigned long reg;
- } data;
-};
-
-/* Some operations may allow more than two operand terms:
- * ADD, MUL, OR, AND, XOR
- */
-struct yasm_expr {
- yasm_expr_op op;
- unsigned long line;
- int numterms;
- yasm_expr__item terms[2]; /* structure may be extended to include more */
-};
-
-/* Traverse over expression tree in order, calling func for each leaf
- * (non-operation). The data pointer d is passed to each func call.
- *
- * Stops early (and returns 1) if func returns 1. Otherwise returns 0.
- */
-int yasm_expr__traverse_leaves_in_const
- (const yasm_expr *e, /*@null@*/ void *d,
- int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d));
-int yasm_expr__traverse_leaves_in
- (yasm_expr *e, /*@null@*/ void *d,
- int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d));
-
-/* Reorder terms of e into canonical order. Only reorders if reordering
- * doesn't change meaning of expression. (eg, doesn't reorder SUB).
- * Canonical order: REG, INT, FLOAT, SYM, EXPR.
- * Multiple terms of a single type are kept in the same order as in
- * the original expression.
- * NOTE: Only performs reordering on *one* level (no recursion).
- */
-void yasm_expr__order_terms(yasm_expr *e);
-
-/* Copy entire expression EXCEPT for index "except" at *top level only*. */
-yasm_expr *yasm_expr__copy_except(const yasm_expr *e, int except);
-
-int yasm_expr__contains(const yasm_expr *e, yasm_expr__type t);
-
-#endif
+++ /dev/null
-/*
- * Expression handling
- *
- * Copyright (C) 2001 Michael Urman, 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "bitvect.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-
-#include "arch.h"
-
-#include "expr-int.h"
-
-
-static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e,
- /*@null@*/ void *d,
- int (*func) (/*@null@*/ yasm_expr *e,
- /*@null@*/ void *d));
-
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-
-void
-yasm_expr_initialize(yasm_arch *a)
-{
- cur_arch = a;
-}
-
-/* allocate a new expression node, with children as defined.
- * If it's a unary operator, put the element in left and set right=NULL. */
-/*@-compmempass@*/
-yasm_expr *
-yasm_expr_new(yasm_expr_op op, yasm_expr__item *left, yasm_expr__item *right,
- unsigned long lindex)
-{
- yasm_expr *ptr, *sube;
- ptr = yasm_xmalloc(sizeof(yasm_expr));
-
- ptr->op = op;
- ptr->numterms = 0;
- ptr->terms[0].type = YASM_EXPR_NONE;
- ptr->terms[1].type = YASM_EXPR_NONE;
- if (left) {
- ptr->terms[0] = *left; /* structure copy */
- yasm_xfree(left);
- ptr->numterms++;
-
- /* Search downward until we find something *other* than an
- * IDENT, then bring it up to the current level.
- */
- while (ptr->terms[0].type == YASM_EXPR_EXPR &&
- ptr->terms[0].data.expn->op == YASM_EXPR_IDENT) {
- sube = ptr->terms[0].data.expn;
- ptr->terms[0] = sube->terms[0]; /* structure copy */
- /*@-usereleased@*/
- yasm_xfree(sube);
- /*@=usereleased@*/
- }
- } else {
- yasm_internal_error(N_("Right side of expression must exist"));
- }
-
- if (right) {
- ptr->terms[1] = *right; /* structure copy */
- yasm_xfree(right);
- ptr->numterms++;
-
- /* Search downward until we find something *other* than an
- * IDENT, then bring it up to the current level.
- */
- while (ptr->terms[1].type == YASM_EXPR_EXPR &&
- ptr->terms[1].data.expn->op == YASM_EXPR_IDENT) {
- sube = ptr->terms[1].data.expn;
- ptr->terms[1] = sube->terms[0]; /* structure copy */
- /*@-usereleased@*/
- yasm_xfree(sube);
- /*@=usereleased@*/
- }
- }
-
- ptr->line = lindex;
-
- return ptr;
-}
-/*@=compmempass@*/
-
-/* helpers */
-yasm_expr__item *
-yasm_expr_sym(yasm_symrec *s)
-{
- yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
- e->type = YASM_EXPR_SYM;
- e->data.sym = s;
- return e;
-}
-
-yasm_expr__item *
-yasm_expr_expr(yasm_expr *x)
-{
- yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
- e->type = YASM_EXPR_EXPR;
- e->data.expn = x;
- return e;
-}
-
-yasm_expr__item *
-yasm_expr_int(yasm_intnum *i)
-{
- yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
- e->type = YASM_EXPR_INT;
- e->data.intn = i;
- return e;
-}
-
-yasm_expr__item *
-yasm_expr_float(yasm_floatnum *f)
-{
- yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
- e->type = YASM_EXPR_FLOAT;
- e->data.flt = f;
- return e;
-}
-
-yasm_expr__item *
-yasm_expr_reg(unsigned long reg)
-{
- yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
- e->type = YASM_EXPR_REG;
- e->data.reg = reg;
- return e;
-}
-
-/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into integers if
- * possible. Also transforms single symrec's that reference absolute sections.
- * Uses a simple n^2 algorithm because n is usually quite small.
- */
-static /*@only@*/ yasm_expr *
-expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- int i;
- /*@dependent@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
- /*@null@*/ yasm_intnum *dist;
- int numterms;
-
- for (i=0; i<e->numterms; i++) {
- /* Transform symrecs that reference absolute sections into
- * absolute start expr + intnum(dist).
- */
- if (e->terms[i].type == YASM_EXPR_SYM &&
- yasm_symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
- yasm_section_is_absolute(sect) &&
- (dist = calc_bc_dist(sect, NULL, precbc))) {
- const yasm_expr *start = yasm_section_get_start(sect);
- e->terms[i].type = YASM_EXPR_EXPR;
- e->terms[i].data.expn =
- yasm_expr_new(YASM_EXPR_ADD,
- yasm_expr_expr(yasm_expr_copy(start)),
- yasm_expr_int(dist), start->line);
- }
- }
-
- /* Handle symrec-symrec in ADD exprs by looking for (-1*symrec) and
- * symrec term pairs (where both symrecs are in the same segment).
- */
- if (e->op != YASM_EXPR_ADD)
- return e;
-
- for (i=0; i<e->numterms; i++) {
- int j;
- yasm_expr *sube;
- yasm_intnum *intn;
- yasm_symrec *sym;
- /*@dependent@*/ yasm_section *sect2;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;
-
- /* First look for an (-1*symrec) term */
- if (e->terms[i].type != YASM_EXPR_EXPR)
- continue;
- sube = e->terms[i].data.expn;
- if (sube->op != YASM_EXPR_MUL || sube->numterms != 2)
- continue;
-
- if (sube->terms[0].type == YASM_EXPR_INT &&
- sube->terms[1].type == YASM_EXPR_SYM) {
- intn = sube->terms[0].data.intn;
- sym = sube->terms[1].data.sym;
- } else if (sube->terms[0].type == YASM_EXPR_SYM &&
- sube->terms[1].type == YASM_EXPR_INT) {
- sym = sube->terms[0].data.sym;
- intn = sube->terms[1].data.intn;
- } else
- continue;
-
- if (!yasm_intnum_is_neg1(intn))
- continue;
-
- yasm_symrec_get_label(sym, §2, &precbc);
-
- /* Now look for a symrec term in the same segment */
- for (j=0; j<e->numterms; j++) {
- if (e->terms[j].type == YASM_EXPR_SYM &&
- yasm_symrec_get_label(e->terms[j].data.sym, §, &precbc2) &&
- sect == sect2 &&
- (dist = calc_bc_dist(sect, precbc, precbc2))) {
- /* Change the symrec term to an integer */
- e->terms[j].type = YASM_EXPR_INT;
- e->terms[j].data.intn = dist;
- /* Delete the matching (-1*symrec) term */
- yasm_expr_delete(sube);
- e->terms[i].type = YASM_EXPR_NONE;
- break; /* stop looking for matching symrec term */
- }
- }
- }
-
- /* Clean up any deleted (EXPR_NONE) terms */
- numterms = 0;
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type != YASM_EXPR_NONE)
- e->terms[numterms++] = e->terms[i]; /* structure copy */
- }
- if (e->numterms != numterms) {
- e->numterms = numterms;
- e = yasm_xrealloc(e, sizeof(yasm_expr)+((numterms<2) ? 0 :
- sizeof(yasm_expr__item)*(numterms-2)));
- if (numterms == 1)
- e->op = YASM_EXPR_IDENT;
- }
-
- return e;
-}
-
-/* Negate just a single ExprItem by building a -1*ei subexpression */
-static void
-expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei)
-{
- yasm_expr *sube = yasm_xmalloc(sizeof(yasm_expr));
-
- /* Build -1*ei subexpression */
- sube->op = YASM_EXPR_MUL;
- sube->line = e->line;
- sube->numterms = 2;
- sube->terms[0].type = YASM_EXPR_INT;
- sube->terms[0].data.intn = yasm_intnum_new_int(-1);
- sube->terms[1] = *ei; /* structure copy */
-
- /* Replace original ExprItem with subexp */
- ei->type = YASM_EXPR_EXPR;
- ei->data.expn = sube;
-}
-
-/* Negates e by multiplying by -1, with distribution over lower-precedence
- * operators (eg ADD) and special handling to simplify result w/ADD, NEG, and
- * others.
- *
- * Returns a possibly reallocated e.
- */
-static /*@only@*/ yasm_expr *
-expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
-{
- yasm_expr *ne;
- int i;
-
- switch (e->op) {
- case YASM_EXPR_ADD:
- /* distribute (recursively if expr) over terms */
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_EXPR)
- e->terms[i].data.expn =
- expr_xform_neg_helper(e->terms[i].data.expn);
- else
- expr_xform_neg_item(e, &e->terms[i]);
- }
- break;
- case YASM_EXPR_SUB:
- /* change op to ADD, and recursively negate left side (if expr) */
- e->op = YASM_EXPR_ADD;
- if (e->terms[0].type == YASM_EXPR_EXPR)
- e->terms[0].data.expn =
- expr_xform_neg_helper(e->terms[0].data.expn);
- else
- expr_xform_neg_item(e, &e->terms[0]);
- break;
- case YASM_EXPR_NEG:
- /* Negating a negated value? Make it an IDENT. */
- e->op = YASM_EXPR_IDENT;
- break;
- case YASM_EXPR_IDENT:
- /* Negating an ident? Change it into a MUL w/ -1 if there's no
- * floatnums present below; if there ARE floatnums, recurse.
- */
- if (e->terms[0].type == YASM_EXPR_FLOAT)
- yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL,
- e->line);
- else if (e->terms[0].type == YASM_EXPR_EXPR &&
- yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT))
- expr_xform_neg_helper(e->terms[0].data.expn);
- else {
- e->op = YASM_EXPR_MUL;
- e->numterms = 2;
- e->terms[1].type = YASM_EXPR_INT;
- e->terms[1].data.intn = yasm_intnum_new_int(-1);
- }
- break;
- default:
- /* Everything else. MUL will be combined when it's leveled.
- * Make a new expr (to replace e) with -1*e.
- */
- ne = yasm_xmalloc(sizeof(yasm_expr));
- ne->op = YASM_EXPR_MUL;
- ne->line = e->line;
- ne->numterms = 2;
- ne->terms[0].type = YASM_EXPR_INT;
- ne->terms[0].data.intn = yasm_intnum_new_int(-1);
- ne->terms[1].type = YASM_EXPR_EXPR;
- ne->terms[1].data.expn = e;
- return ne;
- }
- return e;
-}
-
-/* Transforms negatives into expressions that are easier to combine:
- * -x -> -1*x
- * a-b -> a+(-1*b)
- *
- * Call post-order on an expression tree to transform the entire tree.
- *
- * Returns a possibly reallocated e.
- */
-static /*@only@*/ yasm_expr *
-expr_xform_neg(/*@returned@*/ /*@only@*/ yasm_expr *e)
-{
- switch (e->op) {
- case YASM_EXPR_NEG:
- /* Turn -x into -1*x */
- e->op = YASM_EXPR_IDENT;
- return expr_xform_neg_helper(e);
- case YASM_EXPR_SUB:
- /* Turn a-b into a+(-1*b) */
-
- /* change op to ADD, and recursively negate right side (if expr) */
- e->op = YASM_EXPR_ADD;
- if (e->terms[1].type == YASM_EXPR_EXPR)
- e->terms[1].data.expn =
- expr_xform_neg_helper(e->terms[1].data.expn);
- else
- expr_xform_neg_item(e, &e->terms[1]);
- break;
- default:
- break;
- }
-
- return e;
-}
-
-/* Look for simple identities that make the entire result constant:
- * 0*&x, -1|x, etc.
- */
-static int
-expr_is_constant(yasm_expr_op op, yasm_intnum *intn)
-{
- return ((yasm_intnum_is_zero(intn) && op == YASM_EXPR_MUL) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_AND) ||
- (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_OR));
-}
-
-/* Look for simple "left" identities like 0+x, 1*x, etc. */
-static int
-expr_can_delete_int_left(yasm_expr_op op, yasm_intnum *intn)
-{
- return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_ADD) ||
- (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_OR));
-}
-
-/* Look for simple "right" identities like x+|-0, x*&/1 */
-static int
-expr_can_delete_int_right(yasm_expr_op op, yasm_intnum *intn)
-{
- return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
- (yasm_intnum_is_pos1(intn) && op == YASM_EXPR_DIV) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_ADD) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_SUB) ||
- (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_OR) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_SHL) ||
- (yasm_intnum_is_zero(intn) && op == YASM_EXPR_SHR));
-}
-
-/* Check for and simplify identities. Returns new number of expr terms.
- * Sets e->op = EXPR_IDENT if numterms ends up being 1.
- * Uses numterms parameter instead of e->numterms for basis of "new" number
- * of terms.
- * Assumes int_term is *only* integer term in e.
- * NOTE: Really designed to only be used by expr_level_op().
- */
-static int
-expr_simplify_identity(yasm_expr *e, int numterms, int int_term)
-{
- int i;
-
- /* Check for simple identities that delete the intnum.
- * Don't delete if the intnum is the only thing in the expn.
- */
- if ((int_term == 0 && numterms > 1 &&
- expr_can_delete_int_left(e->op, e->terms[0].data.intn)) ||
- (int_term > 0 &&
- expr_can_delete_int_right(e->op, e->terms[int_term].data.intn))) {
- /* Delete the intnum */
- yasm_intnum_delete(e->terms[int_term].data.intn);
-
- /* Slide everything to its right over by 1 */
- if (int_term != numterms-1) /* if it wasn't last.. */
- memmove(&e->terms[int_term], &e->terms[int_term+1],
- (numterms-1-int_term)*sizeof(yasm_expr__item));
-
- /* Update numterms */
- numterms--;
- }
-
- /* Check for simple identites that delete everything BUT the intnum.
- * Don't bother if the intnum is the only thing in the expn.
- */
- if (numterms > 1 &&
- expr_is_constant(e->op, e->terms[int_term].data.intn)) {
- /* Loop through, deleting everything but the integer term */
- for (i=0; i<e->numterms; i++)
- if (i != int_term)
- switch (e->terms[i].type) {
- case YASM_EXPR_INT:
- yasm_intnum_delete(e->terms[i].data.intn);
- break;
- case YASM_EXPR_FLOAT:
- yasm_floatnum_delete(e->terms[i].data.flt);
- break;
- case YASM_EXPR_EXPR:
- yasm_expr_delete(e->terms[i].data.expn);
- break;
- default:
- break;
- }
-
- /* Move integer term to the first term (if not already there) */
- if (int_term != 0)
- e->terms[0] = e->terms[int_term]; /* structure copy */
-
- /* Set numterms to 1 */
- numterms = 1;
- }
-
- /* Change expression to IDENT if possible. */
- if (numterms == 1)
- e->op = YASM_EXPR_IDENT;
-
- /* Return the updated numterms */
- return numterms;
-}
-
-/* Levels the expression tree starting at e. Eg:
- * a+(b+c) -> a+b+c
- * (a+b)+(c+d) -> a+b+c+d
- * Naturally, only levels operators that allow more than two operand terms.
- * NOTE: only does *one* level of leveling (no recursion). Should be called
- * post-order on a tree to combine deeper levels.
- * Also brings up any IDENT values into the current level (for ALL operators).
- * Folds (combines by evaluation) *integer* constant values if fold_const != 0.
- *
- * Returns a possibly reallocated e.
- */
-/*@-mustfree@*/
-static /*@only@*/ yasm_expr *
-expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
- int simplify_ident)
-{
- int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
- int first_int_term = -1;
-
- /* Determine how many operands will need to be brought up (for leveling).
- * Go ahead and bring up any IDENT'ed values.
- */
- while (e->op == YASM_EXPR_IDENT && e->terms[0].type == YASM_EXPR_EXPR) {
- yasm_expr *sube = e->terms[0].data.expn;
- yasm_xfree(e);
- e = sube;
- }
- level_numterms = e->numterms;
- level_fold_numterms = 0;
- for (i=0; i<e->numterms; i++) {
- /* Search downward until we find something *other* than an
- * IDENT, then bring it up to the current level.
- */
- while (e->terms[i].type == YASM_EXPR_EXPR &&
- e->terms[i].data.expn->op == YASM_EXPR_IDENT) {
- yasm_expr *sube = e->terms[i].data.expn;
- e->terms[i] = sube->terms[0];
- yasm_xfree(sube);
- }
-
- if (e->terms[i].type == YASM_EXPR_EXPR &&
- e->terms[i].data.expn->op == e->op) {
- /* It's an expression w/the same operator, add in its numterms.
- * But don't forget to subtract one for the expr itself!
- */
- level_numterms += e->terms[i].data.expn->numterms - 1;
-
- /* If we're folding constants, count up the number of constants
- * that will be merged in.
- */
- if (fold_const)
- for (j=0; j<e->terms[i].data.expn->numterms; j++)
- if (e->terms[i].data.expn->terms[j].type ==
- YASM_EXPR_INT)
- level_fold_numterms++;
- }
-
- /* Find the first integer term (if one is present) if we're folding
- * constants.
- */
- if (fold_const && first_int_term == -1 &&
- e->terms[i].type == YASM_EXPR_INT)
- first_int_term = i;
- }
-
- /* Look for other integer terms if there's one and combine.
- * Also eliminate empty spaces when combining and adjust numterms
- * variables.
- */
- fold_numterms = e->numterms;
- if (first_int_term != -1) {
- for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_INT) {
- yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op,
- e->terms[i].data.intn);
- fold_numterms--;
- level_numterms--;
- /* make sure to delete folded intnum */
- yasm_intnum_delete(e->terms[i].data.intn);
- } else if (o != i) {
- /* copy term if it changed places */
- e->terms[o++] = e->terms[i];
- }
- }
-
- if (simplify_ident)
- /* Simplify identities and make IDENT if possible. */
- fold_numterms = expr_simplify_identity(e, fold_numterms,
- first_int_term);
- else if (fold_numterms == 1)
- e->op = YASM_EXPR_IDENT;
- }
-
- /* Only level operators that allow more than two operand terms.
- * Also don't bother leveling if it's not necessary to bring up any terms.
- */
- if ((e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL &&
- e->op != YASM_EXPR_OR && e->op != YASM_EXPR_AND &&
- e->op != YASM_EXPR_XOR) ||
- level_numterms <= fold_numterms) {
- /* Downsize e if necessary */
- if (fold_numterms < e->numterms && e->numterms > 2)
- e = yasm_xrealloc(e, sizeof(yasm_expr)+((fold_numterms<2) ? 0 :
- sizeof(yasm_expr__item)*(fold_numterms-2)));
- /* Update numterms */
- e->numterms = fold_numterms;
- return e;
- }
-
- /* Adjust numterms for constant folding from terms being "pulled up".
- * Careful: if there's no integer term in e, then save space for it.
- */
- if (fold_const) {
- level_numterms -= level_fold_numterms;
- if (first_int_term == -1 && level_fold_numterms != 0)
- level_numterms++;
- }
-
- /* Alloc more (or conceivably less, but not usually) space for e */
- e = yasm_xrealloc(e, sizeof(yasm_expr)+((level_numterms<2) ? 0 :
- sizeof(yasm_expr__item)*(level_numterms-2)));
-
- /* Copy up ExprItem's. Iterate from right to left to keep the same
- * ordering as was present originally.
- * Combine integer terms as necessary.
- */
- for (i=e->numterms-1, o=level_numterms-1; i>=0; i--) {
- if (e->terms[i].type == YASM_EXPR_EXPR &&
- e->terms[i].data.expn->op == e->op) {
- /* bring up subexpression */
- yasm_expr *sube = e->terms[i].data.expn;
-
- /* copy terms right to left */
- for (j=sube->numterms-1; j>=0; j--) {
- if (fold_const && sube->terms[j].type == YASM_EXPR_INT) {
- /* Need to fold it in.. but if there's no int term already,
- * just copy into a new one.
- */
- if (first_int_term == -1) {
- first_int_term = o--;
- e->terms[first_int_term] = sube->terms[j]; /* struc */
- } else {
- yasm_intnum_calc(e->terms[first_int_term].data.intn,
- e->op, sube->terms[j].data.intn);
- /* make sure to delete folded intnum */
- yasm_intnum_delete(sube->terms[j].data.intn);
- }
- } else {
- if (o == first_int_term)
- o--;
- e->terms[o--] = sube->terms[j]; /* structure copy */
- }
- }
-
- /* delete subexpression, but *don't delete nodes* (as we've just
- * copied them!)
- */
- yasm_xfree(sube);
- } else if (o != i) {
- /* copy operand if it changed places */
- if (o == first_int_term)
- o--;
- e->terms[o] = e->terms[i];
- /* If we moved the first_int_term, change first_int_num too */
- if (i == first_int_term)
- first_int_term = o;
- o--;
- }
- }
-
- /* Simplify identities, make IDENT if possible, and save to e->numterms. */
- if (simplify_ident && first_int_term != -1) {
- e->numterms = expr_simplify_identity(e, level_numterms,
- first_int_term);
- } else {
- e->numterms = level_numterms;
- if (level_numterms == 1)
- e->op = YASM_EXPR_IDENT;
- }
-
- return e;
-}
-/*@=mustfree@*/
-
-typedef struct yasm__exprentry {
- /*@reldef@*/ SLIST_ENTRY(yasm__exprentry) next;
- /*@null@*/ const yasm_expr *e;
-} yasm__exprentry;
-
-/* Level an entire expn tree, expanding equ's as we go */
-yasm_expr *
-yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
- yasm_calc_bc_dist_func calc_bc_dist,
- yasm_expr_xform_func expr_xform_extra,
- void *expr_xform_extra_data, yasm__exprhead *eh)
-{
- int i;
- yasm__exprhead eh_local;
- yasm__exprentry ee;
-
- if (!e)
- return 0;
-
- if (!eh) {
- eh = &eh_local;
- SLIST_INIT(eh);
- }
-
- e = expr_xform_neg(e);
-
- ee.e = NULL;
-
- /* traverse terms */
- for (i=0; i<e->numterms; i++) {
- /* First expand equ's */
- if (e->terms[i].type == YASM_EXPR_SYM) {
- const yasm_expr *equ_expr =
- yasm_symrec_get_equ(e->terms[i].data.sym);
- if (equ_expr) {
- yasm__exprentry *np;
-
- /* Check for circular reference */
- SLIST_FOREACH(np, eh, next) {
- if (np->e == equ_expr) {
- yasm__error(e->line,
- N_("circular reference detected."));
- return e;
- }
- }
-
- e->terms[i].type = YASM_EXPR_EXPR;
- e->terms[i].data.expn = yasm_expr_copy(equ_expr);
-
- ee.e = equ_expr;
- SLIST_INSERT_HEAD(eh, &ee, next);
- }
- }
-
- if (e->terms[i].type == YASM_EXPR_EXPR)
- e->terms[i].data.expn =
- yasm_expr__level_tree(e->terms[i].data.expn, fold_const,
- simplify_ident, calc_bc_dist,
- expr_xform_extra, expr_xform_extra_data,
- eh);
-
- if (ee.e) {
- SLIST_REMOVE_HEAD(eh, next);
- ee.e = NULL;
- }
- }
-
- /* do callback */
- e = expr_level_op(e, fold_const, simplify_ident);
- if (calc_bc_dist || expr_xform_extra) {
- if (calc_bc_dist)
- e = expr_xform_bc_dist(e, calc_bc_dist);
- if (expr_xform_extra)
- e = expr_xform_extra(e, expr_xform_extra_data);
- e = yasm_expr__level_tree(e, fold_const, simplify_ident, NULL, NULL,
- NULL, NULL);
- }
- return e;
-}
-
-/* Comparison function for expr_order_terms().
- * Assumes ExprType enum is in canonical order.
- */
-static int
-expr_order_terms_compare(const void *va, const void *vb)
-{
- const yasm_expr__item *a = va, *b = vb;
- return (a->type - b->type);
-}
-
-/* Reorder terms of e into canonical order. Only reorders if reordering
- * doesn't change meaning of expression. (eg, doesn't reorder SUB).
- * Canonical order: REG, INT, FLOAT, SYM, EXPR.
- * Multiple terms of a single type are kept in the same order as in
- * the original expression.
- * NOTE: Only performs reordering on *one* level (no recursion).
- */
-void
-yasm_expr__order_terms(yasm_expr *e)
-{
- /* don't bother reordering if only one element */
- if (e->numterms == 1)
- return;
-
- /* only reorder some types of operations */
- switch (e->op) {
- case YASM_EXPR_ADD:
- case YASM_EXPR_MUL:
- case YASM_EXPR_OR:
- case YASM_EXPR_AND:
- case YASM_EXPR_XOR:
- /* Use mergesort to sort. It's fast on already sorted values and a
- * stable sort (multiple terms of same type are kept in the same
- * order).
- */
- mergesort(e->terms, (size_t)e->numterms, sizeof(yasm_expr__item),
- expr_order_terms_compare);
- break;
- default:
- break;
- }
-}
-
-/* Copy entire expression EXCEPT for index "except" at *top level only*. */
-yasm_expr *
-yasm_expr__copy_except(const yasm_expr *e, int except)
-{
- yasm_expr *n;
- int i;
-
- n = yasm_xmalloc(sizeof(yasm_expr) +
- sizeof(yasm_expr__item)*(e->numterms<2?0:e->numterms-2));
-
- n->op = e->op;
- n->line = e->line;
- n->numterms = e->numterms;
- for (i=0; i<e->numterms; i++) {
- yasm_expr__item *dest = &n->terms[i];
- const yasm_expr__item *src = &e->terms[i];
-
- if (i != except) {
- dest->type = src->type;
- switch (src->type) {
- case YASM_EXPR_SYM:
- /* Symbols don't need to be copied */
- dest->data.sym = src->data.sym;
- break;
- case YASM_EXPR_EXPR:
- dest->data.expn =
- yasm_expr__copy_except(src->data.expn, -1);
- break;
- case YASM_EXPR_INT:
- dest->data.intn = yasm_intnum_copy(src->data.intn);
- break;
- case YASM_EXPR_FLOAT:
- dest->data.flt = yasm_floatnum_copy(src->data.flt);
- break;
- case YASM_EXPR_REG:
- dest->data.reg = src->data.reg;
- break;
- default:
- break;
- }
- }
- }
-
- return n;
-}
-
-yasm_expr *
-yasm_expr_copy(const yasm_expr *e)
-{
- return yasm_expr__copy_except(e, -1);
-}
-
-static int
-expr_delete_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
-{
- int i;
- for (i=0; i<e->numterms; i++) {
- switch (e->terms[i].type) {
- case YASM_EXPR_INT:
- yasm_intnum_delete(e->terms[i].data.intn);
- break;
- case YASM_EXPR_FLOAT:
- yasm_floatnum_delete(e->terms[i].data.flt);
- break;
- default:
- break; /* none of the other types needs to be deleted */
- }
- }
- yasm_xfree(e); /* free ourselves */
- return 0; /* don't stop recursion */
-}
-
-/*@-mustfree@*/
-void
-yasm_expr_delete(yasm_expr *e)
-{
- expr_traverse_nodes_post(e, NULL, expr_delete_each);
-}
-/*@=mustfree@*/
-
-static int
-expr_contains_callback(const yasm_expr__item *ei, void *d)
-{
- yasm_expr__type *t = d;
- return (ei->type & *t);
-}
-
-int
-yasm_expr__contains(const yasm_expr *e, yasm_expr__type t)
-{
- return yasm_expr__traverse_leaves_in_const(e, &t, expr_contains_callback);
-}
-
-/* Traverse over expression tree, calling func for each operation AFTER the
- * branches (if expressions) have been traversed (eg, postorder
- * traversal). The data pointer d is passed to each func call.
- *
- * Stops early (and returns 1) if func returns 1. Otherwise returns 0.
- */
-static int
-expr_traverse_nodes_post(yasm_expr *e, void *d,
- int (*func) (/*@null@*/ yasm_expr *e,
- /*@null@*/ void *d))
-{
- int i;
-
- if (!e)
- return 0;
-
- /* traverse terms */
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_EXPR &&
- expr_traverse_nodes_post(e->terms[i].data.expn, d, func))
- return 1;
- }
-
- /* do callback */
- return func(e, d);
-}
-
-/* Traverse over expression tree in order, calling func for each leaf
- * (non-operation). The data pointer d is passed to each func call.
- *
- * Stops early (and returns 1) if func returns 1. Otherwise returns 0.
- */
-int
-yasm_expr__traverse_leaves_in_const(const yasm_expr *e, void *d,
- int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d))
-{
- int i;
-
- if (!e)
- return 0;
-
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_EXPR) {
- if (yasm_expr__traverse_leaves_in_const(e->terms[i].data.expn, d,
- func))
- return 1;
- } else {
- if (func(&e->terms[i], d))
- return 1;
- }
- }
- return 0;
-}
-
-/* Traverse over expression tree in order, calling func for each leaf
- * (non-operation). The data pointer d is passed to each func call.
- *
- * Stops early (and returns 1) if func returns 1. Otherwise returns 0.
- */
-int
-yasm_expr__traverse_leaves_in(yasm_expr *e, void *d,
- int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d))
-{
- int i;
-
- if (!e)
- return 0;
-
- for (i=0; i<e->numterms; i++) {
- if (e->terms[i].type == YASM_EXPR_EXPR) {
- if (yasm_expr__traverse_leaves_in(e->terms[i].data.expn, d, func))
- return 1;
- } else {
- if (func(&e->terms[i], d))
- return 1;
- }
- }
- return 0;
-}
-
-yasm_symrec *
-yasm_expr_extract_symrec(yasm_expr **ep, yasm_calc_bc_dist_func calc_bc_dist)
-{
- yasm_symrec *sym = NULL;
- int i, symterm = -1;
-
- switch ((*ep)->op) {
- case YASM_EXPR_IDENT:
- /* Replace sym with 0 value, return sym */
- if ((*ep)->terms[0].type == YASM_EXPR_SYM) {
- sym = (*ep)->terms[0].data.sym;
- symterm = 0;
- }
- break;
- case YASM_EXPR_ADD:
- /* Search for sym, if found, delete it from expr and return it */
- for (i=0; i<(*ep)->numterms; i++) {
- if ((*ep)->terms[i].type == YASM_EXPR_SYM) {
- sym = (*ep)->terms[i].data.sym;
- symterm = i;
- break;
- }
- }
- break;
- default:
- break;
- }
- if (sym) {
- /*@dependent@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
- /*@null@*/ yasm_intnum *intn;
-
- if (yasm_symrec_get_label(sym, §, &precbc)) {
- intn = calc_bc_dist(sect, NULL, precbc);
- if (!intn)
- return NULL;
- } else
- intn = yasm_intnum_new_uint(0);
- (*ep)->terms[symterm].type = YASM_EXPR_INT;
- (*ep)->terms[symterm].data.intn = intn;
- }
- return sym;
-}
-
-/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
-const yasm_intnum *
-yasm_expr_get_intnum(yasm_expr **ep, yasm_calc_bc_dist_func calc_bc_dist)
-{
- *ep = yasm_expr_simplify(*ep, calc_bc_dist);
-
- if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_INT)
- return (*ep)->terms[0].data.intn;
- else
- return (yasm_intnum *)NULL;
-}
-/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
-
-/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
-const yasm_floatnum *
-yasm_expr_get_floatnum(yasm_expr **ep)
-{
- *ep = yasm_expr_simplify(*ep, NULL);
-
- if ((*ep)->op == YASM_EXPR_IDENT &&
- (*ep)->terms[0].type == YASM_EXPR_FLOAT)
- return (*ep)->terms[0].data.flt;
- else
- return (yasm_floatnum *)NULL;
-}
-/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
-
-/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
-const yasm_symrec *
-yasm_expr_get_symrec(yasm_expr **ep, int simplify)
-{
- if (simplify)
- *ep = yasm_expr_simplify(*ep, NULL);
-
- if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_SYM)
- return (*ep)->terms[0].data.sym;
- else
- return (yasm_symrec *)NULL;
-}
-/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
-
-/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
-const unsigned long *
-yasm_expr_get_reg(yasm_expr **ep, int simplify)
-{
- if (simplify)
- *ep = yasm_expr_simplify(*ep, NULL);
-
- if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_REG)
- return &((*ep)->terms[0].data.reg);
- else
- return NULL;
-}
-/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
-
-void
-yasm_expr_print(FILE *f, const yasm_expr *e)
-{
- char opstr[6];
- int i;
-
- if (!e) {
- fprintf(f, "(nil)");
- return;
- }
-
- switch (e->op) {
- case YASM_EXPR_ADD:
- strcpy(opstr, "+");
- break;
- case YASM_EXPR_SUB:
- strcpy(opstr, "-");
- break;
- case YASM_EXPR_MUL:
- strcpy(opstr, "*");
- break;
- case YASM_EXPR_DIV:
- strcpy(opstr, "/");
- break;
- case YASM_EXPR_SIGNDIV:
- strcpy(opstr, "//");
- break;
- case YASM_EXPR_MOD:
- strcpy(opstr, "%");
- break;
- case YASM_EXPR_SIGNMOD:
- strcpy(opstr, "%%");
- break;
- case YASM_EXPR_NEG:
- fprintf(f, "-");
- opstr[0] = 0;
- break;
- case YASM_EXPR_NOT:
- fprintf(f, "~");
- opstr[0] = 0;
- break;
- case YASM_EXPR_OR:
- strcpy(opstr, "|");
- break;
- case YASM_EXPR_AND:
- strcpy(opstr, "&");
- break;
- case YASM_EXPR_XOR:
- strcpy(opstr, "^");
- break;
- case YASM_EXPR_SHL:
- strcpy(opstr, "<<");
- break;
- case YASM_EXPR_SHR:
- strcpy(opstr, ">>");
- break;
- case YASM_EXPR_LOR:
- strcpy(opstr, "||");
- break;
- case YASM_EXPR_LAND:
- strcpy(opstr, "&&");
- break;
- case YASM_EXPR_LNOT:
- strcpy(opstr, "!");
- break;
- case YASM_EXPR_LT:
- strcpy(opstr, "<");
- break;
- case YASM_EXPR_GT:
- strcpy(opstr, ">");
- break;
- case YASM_EXPR_LE:
- strcpy(opstr, "<=");
- break;
- case YASM_EXPR_GE:
- strcpy(opstr, ">=");
- break;
- case YASM_EXPR_NE:
- strcpy(opstr, "!=");
- break;
- case YASM_EXPR_EQ:
- strcpy(opstr, "==");
- break;
- case YASM_EXPR_SEG:
- fprintf(f, "SEG ");
- opstr[0] = 0;
- break;
- case YASM_EXPR_WRT:
- strcpy(opstr, " WRT ");
- break;
- case YASM_EXPR_SEGOFF:
- strcpy(opstr, ":");
- break;
- case YASM_EXPR_IDENT:
- opstr[0] = 0;
- break;
- }
- for (i=0; i<e->numterms; i++) {
- switch (e->terms[i].type) {
- case YASM_EXPR_SYM:
- fprintf(f, "%s", yasm_symrec_get_name(e->terms[i].data.sym));
- break;
- case YASM_EXPR_EXPR:
- fprintf(f, "(");
- yasm_expr_print(f, e->terms[i].data.expn);
- fprintf(f, ")");
- break;
- case YASM_EXPR_INT:
- yasm_intnum_print(f, e->terms[i].data.intn);
- break;
- case YASM_EXPR_FLOAT:
- yasm_floatnum_print(f, e->terms[i].data.flt);
- break;
- case YASM_EXPR_REG:
- cur_arch->reg_print(f, e->terms[i].data.reg);
- break;
- case YASM_EXPR_NONE:
- break;
- }
- if (i < e->numterms-1)
- fprintf(f, "%s", opstr);
- }
-}
+++ /dev/null
-/* $IdPath$
- * Expression handling header file
- *
- * Copyright (C) 2001 Michael Urman, 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.
- *
- * 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.
- */
-#ifndef YASM_EXPR_H
-#define YASM_EXPR_H
-
-typedef struct yasm_expr__item yasm_expr__item;
-
-void yasm_expr_initialize(yasm_arch *a);
-
-/*@only@*/ yasm_expr *yasm_expr_new(yasm_expr_op, /*@only@*/ yasm_expr__item *,
- /*@only@*/ /*@null@*/ yasm_expr__item *,
- unsigned long lindex);
-
-/*@only@*/ yasm_expr__item *yasm_expr_sym(/*@keep@*/ yasm_symrec *);
-/*@only@*/ yasm_expr__item *yasm_expr_expr(/*@keep@*/ yasm_expr *);
-/*@only@*/ yasm_expr__item *yasm_expr_int(/*@keep@*/ yasm_intnum *);
-/*@only@*/ yasm_expr__item *yasm_expr_float(/*@keep@*/ yasm_floatnum *);
-/*@only@*/ yasm_expr__item *yasm_expr_reg(unsigned long reg);
-
-#define yasm_expr_new_tree(l,o,r,i) \
- yasm_expr_new ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
-#define yasm_expr_new_branch(o,r,i) \
- yasm_expr_new ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
-#define yasm_expr_new_ident(r,i) \
- yasm_expr_new (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
-
-/* allocates and makes an exact duplicate of e */
-yasm_expr *yasm_expr_copy(const yasm_expr *e);
-
-void yasm_expr_delete(/*@only@*/ /*@null@*/ yasm_expr *e);
-
-/* "Extra" transformation function that may be inserted into an
- * expr_level_tree() invocation.
- * Inputs: e, the expression being simplified
- * d, data provided as expr_xform_extra_data to expr_level_tree()
- * Returns updated e.
- */
-typedef /*@only@*/ yasm_expr * (*yasm_expr_xform_func)
- (/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ void *d);
-
-typedef SLIST_HEAD(yasm__exprhead, yasm__exprentry) yasm__exprhead;
-/* Level an entire expn tree. Call with eh = NULL */
-/*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree
- (/*@returned@*/ /*@only@*/ /*@null@*/ yasm_expr *e, int fold_const,
- int simplify_ident, /*@null@*/ yasm_calc_bc_dist_func calc_bc_dist,
- /*@null@*/ yasm_expr_xform_func expr_xform_extra,
- /*@null@*/ void *expr_xform_extra_data, /*@null@*/ yasm__exprhead *eh);
-
-/* Simplifies the expression e as much as possible, eliminating extraneous
- * branches and simplifying integer-only subexpressions.
- */
-#define yasm_expr_simplify(e, cbd) \
- yasm_expr__level_tree(e, 1, 1, cbd, NULL, NULL, NULL)
-
-/* Extracts a single symrec out of an expression, replacing it with the
- * symrec's value (if it's a label). Returns NULL if it's unable to extract a
- * symrec (too complex of expr, none present, etc).
- */
-/*@dependent@*/ /*@null@*/ yasm_symrec *yasm_expr_extract_symrec
- (yasm_expr **ep, yasm_calc_bc_dist_func calc_bc_dist);
-
-/* Gets the integer value of e if the expression is just an integer. If the
- * expression is more complex (contains anything other than integers, ie
- * floats, non-valued labels, registers), returns NULL.
- */
-/*@dependent@*/ /*@null@*/ const yasm_intnum *yasm_expr_get_intnum
- (yasm_expr **ep, /*@null@*/ yasm_calc_bc_dist_func calc_bc_dist);
-
-/* Gets the float value of e if the expression is just an float. If the
- * expression is more complex (contains anything other than floats, ie
- * integers, non-valued labels, registers), returns NULL.
- */
-/*@dependent@*/ /*@null@*/ const yasm_floatnum *yasm_expr_get_floatnum
- (yasm_expr **ep);
-
-/* Gets the symrec value of e if the expression is just an symbol. If the
- * expression is more complex, returns NULL. Simplifies the expr first if
- * simplify is nonzero.
- */
-/*@dependent@*/ /*@null@*/ const yasm_symrec *yasm_expr_get_symrec
- (yasm_expr **ep, int simplify);
-
-/* Gets the register value of e if the expression is just a register. If the
- * expression is more complex, returns NULL. Simplifies the expr first if
- * simplify is nonzero.
- */
-/*@dependent@*/ /*@null@*/ const unsigned long *yasm_expr_get_reg
- (yasm_expr **ep, int simplify);
-
-void yasm_expr_print(FILE *f, /*@null@*/ const yasm_expr *);
-
-#endif
+++ /dev/null
-/*
- * Little-endian file functions.
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-
-size_t
-yasm_fwrite_16_l(unsigned short val, FILE *f)
-{
- if (fputc(val & 0xFF, f) == EOF)
- return 0;
- if (fputc((val >> 8) & 0xFF, f) == EOF)
- return 0;
- return 1;
-}
-
-size_t
-yasm_fwrite_32_l(unsigned long val, FILE *f)
-{
- if (fputc((int)(val & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
- return 0;
- return 1;
-}
-
-size_t
-yasm_fwrite_16_b(unsigned short val, FILE *f)
-{
- if (fputc((val >> 8) & 0xFF, f) == EOF)
- return 0;
- if (fputc(val & 0xFF, f) == EOF)
- return 0;
- return 1;
-}
-
-size_t
-yasm_fwrite_32_b(unsigned long val, FILE *f)
-{
- if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
- return 0;
- if (fputc((int)(val & 0xFF), f) == EOF)
- return 0;
- return 1;
-}
+++ /dev/null
-/* $IdPath$
- * Big and little endian file functions header file.
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_FILE_H
-#define YASM_FILE_H
-
-/* These functions only work properly if p is an (unsigned char *) */
-
-#define YASM_WRITE_8(ptr, val) \
- *((ptr)++) = (unsigned char)((val) & 0xFF)
-
-#define YASM_WRITE_16_L(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- } while (0)
-
-#define YASM_WRITE_32_L(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
- } while (0)
-
-#define YASM_WRITE_16_B(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- } while (0)
-
-#define YASM_WRITE_32_B(ptr, val) \
- do { \
- *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)++) = (unsigned char)((val) & 0xFF); \
- } while (0)
-
-
-/* Non-incrementing versions of the above. */
-
-#define YASM_SAVE_8(ptr, val) \
- *(ptr) = (unsigned char)((val) & 0xFF)
-
-#define YASM_SAVE_16_L(ptr, val) \
- do { \
- *(ptr) = (unsigned char)((val) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
- } while (0)
-
-#define YASM_SAVE_32_L(ptr, val) \
- do { \
- *(ptr) = (unsigned char)((val) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+2) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \
- } while (0)
-
-#define YASM_SAVE_16_B(ptr, val) \
- do { \
- *(ptr) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+1) = (unsigned char)((val) & 0xFF); \
- } while (0)
-
-#define YASM_SAVE_32_B(ptr, val) \
- do { \
- *(ptr) = (unsigned char)(((val) >> 24) & 0xFF); \
- *((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \
- *((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF); \
- *((ptr)+3) = (unsigned char)((val) & 0xFF); \
- } while (0)
-
-/* Direct-to-file versions of the above. Using the above macros and a single
- * fwrite() will probably be faster than calling these functions many times.
- * These functions return 1 if the write was successful, 0 if not (so their
- * return values can be used like the return value from fwrite()).
- */
-
-size_t yasm_fwrite_16_l(unsigned short val, FILE *f);
-size_t yasm_fwrite_32_l(unsigned long val, FILE *f);
-size_t yasm_fwrite_16_b(unsigned short val, FILE *f);
-size_t yasm_fwrite_32_b(unsigned long val, FILE *f);
-
-/* Read/Load versions. val is the variable to receive the data. */
-
-#define YASM_READ_8(val, ptr) \
- (val) = *((ptr)++) & 0xFF
-
-#define YASM_READ_16_L(val, ptr) \
- do { \
- (val) = *((ptr)++) & 0xFF; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- } while (0)
-
-#define YASM_READ_32_L(val, ptr) \
- do { \
- (val) = *((ptr)++) & 0xFF; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- (val) |= (*((ptr)++) & 0xFF) << 16; \
- (val) |= (*((ptr)++) & 0xFF) << 24; \
- } while (0)
-
-#define YASM_READ_16_B(val, ptr) \
- do { \
- (val) = (*((ptr)++) & 0xFF) << 8; \
- (val) |= *((ptr)++) & 0xFF; \
- } while (0)
-
-#define YASM_READ_32_B(val, ptr) \
- do { \
- (val) = (*((ptr)++) & 0xFF) << 24; \
- (val) |= (*((ptr)++) & 0xFF) << 16; \
- (val) |= (*((ptr)++) & 0xFF) << 8; \
- (val) |= *((ptr)++) & 0xFF; \
- } while (0)
-
-/* Non-incrementing versions of the above. */
-
-#define YASM_LOAD_8(val, ptr) \
- (val) = *(ptr) & 0xFF
-
-#define YASM_LOAD_16_L(val, ptr) \
- do { \
- (val) = *(ptr) & 0xFF; \
- (val) |= (*((ptr)+1) & 0xFF) << 8; \
- } while (0)
-
-#define YASM_LOAD_32_L(val, ptr) \
- do { \
- (val) = (unsigned long)(*(ptr) & 0xFF); \
- (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \
- (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \
- (val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \
- } while (0)
-
-#define YASM_LOAD_16_B(val, ptr) \
- do { \
- (val) = (*(ptr) & 0xFF) << 8; \
- (val) |= *((ptr)+1) & 0xFF; \
- } while (0)
-
-#define YASM_LOAD_32_B(val, ptr) \
- do { \
- (val) = (unsigned long)((*(ptr) & 0xFF) << 24); \
- (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16); \
- (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8); \
- (val) |= (unsigned long)(*((ptr)+3) & 0xFF); \
- } while (0)
-
-#endif
+++ /dev/null
-/*
- * Floating point number functions.
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * Based on public-domain x86 assembly code by Randall Hyde (8/28/91).
- *
- * 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include <ctype.h>
-
-#include "bitvect.h"
-#include "file.h"
-
-#include "errwarn.h"
-#include "floatnum.h"
-
-
-/* 97-bit internal floating point format:
- * 0000000s eeeeeeee eeeeeeee m.....................................m
- * Sign exponent mantissa (80 bits)
- * 79 0
- *
- * Only L.O. bit of Sign byte is significant. The rest is zero.
- * Exponent is bias 32767.
- * Mantissa does NOT have an implied one bit (it's explicit).
- */
-struct yasm_floatnum {
- /*@only@*/ wordptr mantissa; /* Allocated to MANT_BITS bits */
- unsigned short exponent;
- unsigned char sign;
- unsigned char flags;
-};
-
-/* constants describing parameters of internal floating point format */
-#define MANT_BITS 80
-#define MANT_BYTES 10
-#define MANT_SIGDIGITS 24
-#define EXP_BIAS 0x7FFF
-#define EXP_INF 0xFFFF
-#define EXP_MAX 0xFFFE
-#define EXP_MIN 1
-#define EXP_ZERO 0
-
-/* Flag settings for flags field */
-#define FLAG_ISZERO 1<<0
-
-/* Note this structure integrates the floatnum structure */
-typedef struct POT_Entry_s {
- yasm_floatnum f;
- int dec_exponent;
-} POT_Entry;
-
-/* "Source" for POT_Entry. */
-typedef struct POT_Entry_Source_s {
- unsigned char mantissa[MANT_BYTES]; /* little endian mantissa */
- unsigned short exponent; /* Bias 32767 exponent */
-} POT_Entry_Source;
-
-/* Power of ten tables used by the floating point I/O routines.
- * The POT_Table? arrays are built from the POT_Table?_Source arrays at
- * runtime by POT_Table_Init().
- */
-
-/* This table contains the powers of ten raised to negative powers of two:
- *
- * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
- * entry[13] = 1.0
- */
-static /*@only@*/ POT_Entry *POT_TableN;
-static POT_Entry_Source POT_TableN_Source[] = {
- {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
- {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
- {{0xa6,0x87,0xbd,0xc0,0x57,0xda,0xa5,0x82,0xa6,0xa2},0x72b5}, /* 1e-1024 */
- {{0x33,0x71,0x1c,0xd2,0x23,0xdb,0x32,0xee,0x49,0x90},0x795a}, /* 1e-512 */
- {{0x91,0xfa,0x39,0x19,0x7a,0x63,0x25,0x43,0x31,0xc0},0x7cac}, /* 1e-256 */
- {{0x7d,0xac,0xa0,0xe4,0xbc,0x64,0x7c,0x46,0xd0,0xdd},0x7e55}, /* 1e-128 */
- {{0x24,0x3f,0xa5,0xe9,0x39,0xa5,0x27,0xea,0x7f,0xa8},0x7f2a}, /* 1e-64 */
- {{0xde,0x67,0xba,0x94,0x39,0x45,0xad,0x1e,0xb1,0xcf},0x7f94}, /* 1e-32 */
- {{0x2f,0x4c,0x5b,0xe1,0x4d,0xc4,0xbe,0x94,0x95,0xe6},0x7fc9}, /* 1e-16 */
- {{0xc2,0xfd,0xfc,0xce,0x61,0x84,0x11,0x77,0xcc,0xab},0x7fe4}, /* 1e-8 */
- {{0xc3,0xd3,0x2b,0x65,0x19,0xe2,0x58,0x17,0xb7,0xd1},0x7ff1}, /* 1e-4 */
- {{0x71,0x3d,0x0a,0xd7,0xa3,0x70,0x3d,0x0a,0xd7,0xa3},0x7ff8}, /* 1e-2 */
- {{0xcd,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc},0x7ffb}, /* 1e-1 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e-0 */
-};
-
-/* This table contains the powers of ten raised to positive powers of two:
- *
- * entry[12-n] = 10 ** (2 ** n) for 0 <= n <= 12.
- * entry[13] = 1.0
- * entry[-1] = entry[0];
- *
- * There is a -1 entry since it is possible for the algorithm to back up
- * before the table. This -1 entry is created at runtime by duplicating the
- * 0 entry.
- */
-static /*@only@*/ POT_Entry *POT_TableP;
-static POT_Entry_Source POT_TableP_Source[] = {
- {{0x4c,0xc9,0x9a,0x97,0x20,0x8a,0x02,0x52,0x60,0xc4},0xb525}, /* 1e+4096 */
- {{0x4d,0xa7,0xe4,0x5d,0x3d,0xc5,0x5d,0x3b,0x8b,0x9e},0x9a92}, /* 1e+2048 */
- {{0x0d,0x65,0x17,0x0c,0x75,0x81,0x86,0x75,0x76,0xc9},0x8d48}, /* 1e+1024 */
- {{0x65,0xcc,0xc6,0x91,0x0e,0xa6,0xae,0xa0,0x19,0xe3},0x86a3}, /* 1e+512 */
- {{0xbc,0xdd,0x8d,0xde,0xf9,0x9d,0xfb,0xeb,0x7e,0xaa},0x8351}, /* 1e+256 */
- {{0x6f,0xc6,0xdf,0x8c,0xe9,0x80,0xc9,0x47,0xba,0x93},0x81a8}, /* 1e+128 */
- {{0xbf,0x3c,0xd5,0xa6,0xcf,0xff,0x49,0x1f,0x78,0xc2},0x80d3}, /* 1e+64 */
- {{0x20,0xf0,0x9d,0xb5,0x70,0x2b,0xa8,0xad,0xc5,0x9d},0x8069}, /* 1e+32 */
- {{0x00,0x00,0x00,0x00,0x00,0x04,0xbf,0xc9,0x1b,0x8e},0x8034}, /* 1e+16 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xbc,0xbe},0x8019}, /* 1e+8 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9c},0x800c}, /* 1e+4 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8},0x8005}, /* 1e+2 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0},0x8002}, /* 1e+1 */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */
-};
-
-
-static void
-POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
-{
- /* Save decimal exponent */
- e->dec_exponent = dec_exp;
-
- /* Initialize mantissa */
- e->f.mantissa = BitVector_Create(MANT_BITS, FALSE);
- BitVector_Block_Store(e->f.mantissa, s->mantissa, MANT_BYTES);
-
- /* Initialize exponent */
- e->f.exponent = s->exponent;
-
- /* Set sign to 0 (positive) */
- e->f.sign = 0;
-
- /* Clear flags */
- e->f.flags = 0;
-}
-
-/*@-compdef@*/
-void
-yasm_floatnum_initialize(void)
-/*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source,
- POT_TableN_Source @*/
-{
- int dec_exp = 1;
- int i;
-
- /* Allocate space for two POT tables */
- POT_TableN = yasm_xmalloc(14*sizeof(POT_Entry));
- POT_TableP = yasm_xmalloc(15*sizeof(POT_Entry)); /* note 1 extra for -1 */
-
- /* Initialize entry[0..12] */
- for (i=12; i>=0; i--) {
- POT_Table_Init_Entry(&POT_TableN[i], &POT_TableN_Source[i], 0-dec_exp);
- POT_Table_Init_Entry(&POT_TableP[i+1], &POT_TableP_Source[i], dec_exp);
- dec_exp *= 2; /* Update decimal exponent */
- }
-
- /* Initialize entry[13] */
- POT_Table_Init_Entry(&POT_TableN[13], &POT_TableN_Source[13], 0);
- POT_Table_Init_Entry(&POT_TableP[14], &POT_TableP_Source[13], 0);
-
- /* Initialize entry[-1] for POT_TableP */
- POT_Table_Init_Entry(&POT_TableP[0], &POT_TableP_Source[0], 4096);
-
- /* Offset POT_TableP so that [0] becomes [-1] */
- POT_TableP++;
-}
-/*@=compdef@*/
-
-/*@-globstate@*/
-void
-yasm_floatnum_cleanup(void)
-{
- int i;
-
- /* Un-offset POT_TableP */
- POT_TableP--;
-
- for (i=0; i<14; i++) {
- BitVector_Destroy(POT_TableN[i].f.mantissa);
- BitVector_Destroy(POT_TableP[i].f.mantissa);
- }
- BitVector_Destroy(POT_TableP[14].f.mantissa);
-
- yasm_xfree(POT_TableN);
- yasm_xfree(POT_TableP);
-}
-/*@=globstate@*/
-
-static void
-floatnum_normalize(yasm_floatnum *flt)
-{
- long norm_amt;
-
- if (BitVector_is_empty(flt->mantissa)) {
- flt->exponent = 0;
- return;
- }
-
- /* Look for the highest set bit, shift to make it the MSB, and adjust
- * exponent. Don't let exponent go negative. */
- norm_amt = (MANT_BITS-1)-Set_Max(flt->mantissa);
- if (norm_amt > (long)flt->exponent)
- norm_amt = (long)flt->exponent;
- BitVector_Move_Left(flt->mantissa, (N_int)norm_amt);
- flt->exponent -= norm_amt;
-}
-
-/* acc *= op */
-static void
-floatnum_mul(yasm_floatnum *acc, const yasm_floatnum *op)
-{
- long exp;
- wordptr product, op1, op2;
- long norm_amt;
-
- /* Compute the new sign */
- acc->sign ^= op->sign;
-
- /* Check for multiply by 0 */
- if (BitVector_is_empty(acc->mantissa) || BitVector_is_empty(op->mantissa)) {
- BitVector_Empty(acc->mantissa);
- acc->exponent = EXP_ZERO;
- return;
- }
-
- /* Add exponents, checking for overflow/underflow. */
- exp = (((int)acc->exponent)-EXP_BIAS) + (((int)op->exponent)-EXP_BIAS);
- exp += EXP_BIAS;
- if (exp > EXP_MAX) {
- /* Overflow; return infinity. */
- BitVector_Empty(acc->mantissa);
- acc->exponent = EXP_INF;
- return;
- } else if (exp < EXP_MIN) {
- /* Underflow; return zero. */
- BitVector_Empty(acc->mantissa);
- acc->exponent = EXP_ZERO;
- return;
- }
-
- /* Add one to the final exponent, as the multiply shifts one extra time. */
- acc->exponent = (unsigned short)(exp+1);
-
- /* Allocate space for the multiply result */
- product = BitVector_Create((N_int)((MANT_BITS+1)*2), FALSE);
-
- /* Allocate 1-bit-longer fields to force the operands to be unsigned */
- op1 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
- op2 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
-
- /* Make the operands unsigned after copying from original operands */
- BitVector_Copy(op1, acc->mantissa);
- BitVector_MSB(op1, 0);
- BitVector_Copy(op2, op->mantissa);
- BitVector_MSB(op2, 0);
-
- /* Compute the product of the mantissas */
- BitVector_Multiply(product, op1, op2);
-
- /* Normalize the product. Note: we know the product is non-zero because
- * both of the original operands were non-zero.
- *
- * Look for the highest set bit, shift to make it the MSB, and adjust
- * exponent. Don't let exponent go negative.
- */
- norm_amt = (MANT_BITS*2-1)-Set_Max(product);
- if (norm_amt > (long)acc->exponent)
- norm_amt = (long)acc->exponent;
- BitVector_Move_Left(product, (N_int)norm_amt);
- acc->exponent -= norm_amt;
-
- /* Store the highest bits of the result */
- BitVector_Interval_Copy(acc->mantissa, product, 0, MANT_BITS, MANT_BITS);
-
- /* Free allocated variables */
- BitVector_Destroy(product);
- BitVector_Destroy(op1);
- BitVector_Destroy(op2);
-}
-
-yasm_floatnum *
-yasm_floatnum_new(const char *str)
-{
- yasm_floatnum *flt;
- int dec_exponent, dec_exp_add; /* decimal (powers of 10) exponent */
- int POT_index;
- wordptr operand[2];
- int sig_digits;
- int decimal_pt;
- boolean carry;
-
- flt = yasm_xmalloc(sizeof(yasm_floatnum));
-
- flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
-
- /* allocate and initialize calculation variables */
- operand[0] = BitVector_Create(MANT_BITS, TRUE);
- operand[1] = BitVector_Create(MANT_BITS, TRUE);
- dec_exponent = 0;
- sig_digits = 0;
- decimal_pt = 1;
-
- /* set initial flags to 0 */
- flt->flags = 0;
-
- /* check for + or - character and skip */
- if (*str == '-') {
- flt->sign = 1;
- str++;
- } else if (*str == '+') {
- flt->sign = 0;
- str++;
- } else
- flt->sign = 0;
-
- /* eliminate any leading zeros (which do not count as significant digits) */
- while (*str == '0')
- str++;
-
- /* When we reach the end of the leading zeros, first check for a decimal
- * point. If the number is of the form "0---0.0000" we need to get rid
- * of the zeros after the decimal point and not count them as significant
- * digits.
- */
- if (*str == '.') {
- str++;
- while (*str == '0') {
- str++;
- dec_exponent--;
- }
- } else {
- /* The number is of the form "yyy.xxxx" (where y <> 0). */
- while (isdigit(*str)) {
- /* See if we've processed more than the max significant digits: */
- if (sig_digits < MANT_SIGDIGITS) {
- /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
- BitVector_shift_left(flt->mantissa, 0);
- BitVector_Copy(operand[0], flt->mantissa);
- BitVector_Move_Left(flt->mantissa, 2);
- carry = 0;
- BitVector_add(operand[1], operand[0], flt->mantissa, &carry);
-
- /* Add in current digit */
- BitVector_Empty(operand[0]);
- BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
- carry = 0;
- BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
- } else {
- /* Can't integrate more digits with mantissa, so instead just
- * raise by a power of ten.
- */
- dec_exponent++;
- }
- sig_digits++;
- str++;
- }
-
- if (*str == '.')
- str++;
- else
- decimal_pt = 0;
- }
-
- if (decimal_pt) {
- /* Process the digits to the right of the decimal point. */
- while (isdigit(*str)) {
- /* See if we've processed more than 19 significant digits: */
- if (sig_digits < 19) {
- /* Raise by a power of ten */
- dec_exponent--;
-
- /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
- BitVector_shift_left(flt->mantissa, 0);
- BitVector_Copy(operand[0], flt->mantissa);
- BitVector_Move_Left(flt->mantissa, 2);
- carry = 0;
- BitVector_add(operand[1], operand[0], flt->mantissa, &carry);
-
- /* Add in current digit */
- BitVector_Empty(operand[0]);
- BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
- carry = 0;
- BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
- }
- sig_digits++;
- str++;
- }
- }
-
- if (*str == 'e' || *str == 'E') {
- str++;
- /* We just saw the "E" character, now read in the exponent value and
- * add it into dec_exponent.
- */
- dec_exp_add = 0;
- sscanf(str, "%d", &dec_exp_add);
- dec_exponent += dec_exp_add;
- }
-
- /* Free calculation variables. */
- BitVector_Destroy(operand[1]);
- BitVector_Destroy(operand[0]);
-
- /* Normalize the number, checking for 0 first. */
- if (BitVector_is_empty(flt->mantissa)) {
- /* Mantissa is 0, zero exponent too. */
- flt->exponent = 0;
- /* Set zero flag so output functions don't see 0 value as underflow. */
- flt->flags |= FLAG_ISZERO;
- /* Return 0 value. */
- return flt;
- }
- /* Exponent if already norm. */
- flt->exponent = (unsigned short)(0x7FFF+(MANT_BITS-1));
- floatnum_normalize(flt);
-
- /* The number is normalized. Now multiply by 10 the number of times
- * specified in DecExponent. This uses the power of ten tables to speed
- * up this operation (and make it more accurate).
- */
- if (dec_exponent > 0) {
- POT_index = 0;
- /* Until we hit 1.0 or finish exponent or overflow */
- while ((POT_index < 14) && (dec_exponent != 0) &&
- (flt->exponent != EXP_INF)) {
- /* Find the first power of ten in the table which is just less than
- * the exponent.
- */
- while (dec_exponent < POT_TableP[POT_index].dec_exponent)
- POT_index++;
-
- if (POT_index < 14) {
- /* Subtract out what we're multiplying in from exponent */
- dec_exponent -= POT_TableP[POT_index].dec_exponent;
-
- /* Multiply by current power of 10 */
- floatnum_mul(flt, &POT_TableP[POT_index].f);
- }
- }
- } else if (dec_exponent < 0) {
- POT_index = 0;
- /* Until we hit 1.0 or finish exponent or underflow */
- while ((POT_index < 14) && (dec_exponent != 0) &&
- (flt->exponent != EXP_ZERO)) {
- /* Find the first power of ten in the table which is just less than
- * the exponent.
- */
- while (dec_exponent > POT_TableN[POT_index].dec_exponent)
- POT_index++;
-
- if (POT_index < 14) {
- /* Subtract out what we're multiplying in from exponent */
- dec_exponent -= POT_TableN[POT_index].dec_exponent;
-
- /* Multiply by current power of 10 */
- floatnum_mul(flt, &POT_TableN[POT_index].f);
- }
- }
- }
-
- /* Round the result. (Don't round underflow or overflow). */
- if ((flt->exponent != EXP_INF) && (flt->exponent != EXP_ZERO))
- BitVector_increment(flt->mantissa);
-
- return flt;
-}
-
-yasm_floatnum *
-yasm_floatnum_copy(const yasm_floatnum *flt)
-{
- yasm_floatnum *f = yasm_xmalloc(sizeof(yasm_floatnum));
-
- f->mantissa = BitVector_Clone(flt->mantissa);
- f->exponent = flt->exponent;
- f->sign = flt->sign;
- f->flags = flt->flags;
-
- return f;
-}
-
-void
-yasm_floatnum_delete(yasm_floatnum *flt)
-{
- BitVector_Destroy(flt->mantissa);
- yasm_xfree(flt);
-}
-
-void
-yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- /*@unused@*/ yasm_floatnum *operand, unsigned long lindex)
-{
- if (op != YASM_EXPR_NEG)
- yasm__error(lindex,
- N_("Unsupported floating-point arithmetic operation"));
- else
- acc->sign ^= 1;
-}
-
-int
-yasm_floatnum_get_int(const yasm_floatnum *flt, unsigned long *ret_val)
-{
- unsigned char t[4];
-
- if (yasm_floatnum_get_sized(flt, t, 4)) {
- *ret_val = 0xDEADBEEFUL; /* Obviously incorrect return value */
- return 1;
- }
-
- YASM_LOAD_32_L(*ret_val, &t[0]);
- return 0;
-}
-
-/* Function used by conversion routines to actually perform the conversion.
- *
- * ptr -> the array to return the little-endian floating point value into.
- * flt -> the floating point value to convert.
- * byte_size -> the size in bytes of the output format.
- * mant_bits -> the size in bits of the output mantissa.
- * implicit1 -> does the output format have an implicit 1? 1=yes, 0=no.
- * exp_bits -> the size in bits of the output exponent.
- *
- * Returns 0 on success, 1 if overflow, -1 if underflow.
- */
-static int
-floatnum_get_common(const yasm_floatnum *flt, /*@out@*/ unsigned char *ptr,
- N_int byte_size, N_int mant_bits, int implicit1,
- N_int exp_bits)
-{
- long exponent = (long)flt->exponent;
- wordptr output;
- charptr buf;
- unsigned int len;
- unsigned int overflow = 0, underflow = 0;
- int retval = 0;
- long exp_bias = (1<<(exp_bits-1))-1;
- long exp_inf = (1<<exp_bits)-1;
-
- output = BitVector_Create(byte_size*8, TRUE);
-
- /* copy mantissa */
- BitVector_Interval_Copy(output, flt->mantissa, 0,
- (N_int)((MANT_BITS-implicit1)-mant_bits),
- mant_bits);
-
- /* round mantissa */
- if (BitVector_bit_test(flt->mantissa, (MANT_BITS-implicit1)-(mant_bits+1)))
- BitVector_increment(output);
-
- if (BitVector_bit_test(output, mant_bits)) {
- /* overflowed, so zero mantissa (and set explicit bit if necessary) */
- BitVector_Empty(output);
- BitVector_Bit_Copy(output, mant_bits-1, !implicit1);
- /* and up the exponent (checking for overflow) */
- if (exponent+1 >= EXP_INF)
- overflow = 1;
- else
- exponent++;
- }
-
- /* adjust the exponent to the output bias, checking for overflow */
- exponent -= EXP_BIAS-exp_bias;
- if (exponent >= exp_inf)
- overflow = 1;
- else if (exponent <= 0)
- underflow = 1;
-
- /* underflow and overflow both set!? */
- if (underflow && overflow)
- yasm_internal_error(N_("Both underflow and overflow set"));
-
- /* check for underflow or overflow and set up appropriate output */
- if (underflow) {
- BitVector_Empty(output);
- exponent = 0;
- if (!(flt->flags & FLAG_ISZERO))
- retval = -1;
- } else if (overflow) {
- BitVector_Empty(output);
- exponent = exp_inf;
- retval = 1;
- }
-
- /* move exponent into place */
- BitVector_Chunk_Store(output, exp_bits, mant_bits, (N_long)exponent);
-
- /* merge in sign bit */
- BitVector_Bit_Copy(output, byte_size*8-1, flt->sign);
-
- /* get little-endian bytes */
- buf = BitVector_Block_Read(output, &len);
- if (len < byte_size)
- yasm_internal_error(
- N_("Byte length of BitVector does not match bit length"));
-
- /* copy to output */
- memcpy(ptr, buf, byte_size*sizeof(unsigned char));
-
- /* free allocated resources */
- yasm_xfree(buf);
-
- BitVector_Destroy(output);
-
- return retval;
-}
-
-/* IEEE-754 (Intel) "single precision" format:
- * 32 bits:
- * Bit 31 Bit 22 Bit 0
- * | | |
- * seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
- *
- * e = bias 127 exponent
- * s = sign bit
- * m = mantissa bits, bit 23 is an implied one bit.
- *
- * IEEE-754 (Intel) "double precision" format:
- * 64 bits:
- * bit 63 bit 51 bit 0
- * | | |
- * seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
- *
- * e = bias 1023 exponent.
- * s = sign bit.
- * m = mantissa bits. Bit 52 is an implied one bit.
- *
- * IEEE-754 (Intel) "extended precision" format:
- * 80 bits:
- * bit 79 bit 63 bit 0
- * | | |
- * seeeeeee eeeeeeee mmmmmmmm m...m m...m m...m m...m m...m
- *
- * e = bias 16383 exponent
- * m = 64 bit mantissa with NO implied bit!
- * s = sign (for mantissa)
- */
-int
-yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
- size_t size)
-{
- switch (size) {
- case 4:
- return floatnum_get_common(flt, ptr, 4, 23, 1, 8);
- case 8:
- return floatnum_get_common(flt, ptr, 8, 52, 1, 11);
- case 10:
- return floatnum_get_common(flt, ptr, 10, 64, 0, 15);
- default:
- yasm_internal_error(N_("Invalid float conversion size"));
- /*@notreached@*/
- return 1; /* never reached, but silence GCC warning */
- }
-}
-
-/* 1 if the size is valid, 0 if it isn't */
-int
-yasm_floatnum_check_size(/*@unused@*/ const yasm_floatnum *flt, size_t size)
-{
- switch (size) {
- case 4:
- case 8:
- case 10:
- return 1;
- default:
- return 0;
- }
-}
-
-void
-yasm_floatnum_print(FILE *f, const yasm_floatnum *flt)
-{
- unsigned char out[10];
- unsigned char *str;
- int i;
-
- /* Internal format */
- str = BitVector_to_Hex(flt->mantissa);
- fprintf(f, "%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str,
- flt->exponent);
- yasm_xfree(str);
-
- /* 32-bit (single precision) format */
- fprintf(f, "32-bit: %d: ", yasm_floatnum_get_sized(flt, out, 4));
- for (i=0; i<4; i++)
- fprintf(f, "%02x ", out[i]);
- fprintf(f, "\n");
-
- /* 64-bit (double precision) format */
- fprintf(f, "64-bit: %d: ", yasm_floatnum_get_sized(flt, out, 8));
- for (i=0; i<8; i++)
- fprintf(f, "%02x ", out[i]);
- fprintf(f, "\n");
-
- /* 80-bit (extended precision) format */
- fprintf(f, "80-bit: %d: ", yasm_floatnum_get_sized(flt, out, 10));
- for (i=0; i<10; i++)
- fprintf(f, "%02x ", out[i]);
- fprintf(f, "\n");
-}
+++ /dev/null
-/* $IdPath$
- * Floating point number functions header file.
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * Based on public-domain x86 assembly code by Randall Hyde (8/28/91).
- *
- * 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.
- *
- * 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.
- */
-#ifndef YASM_FLOATNUM_H
-#define YASM_FLOATNUM_H
-
-void yasm_floatnum_initialize(void);
-/* Clean up internal allocations */
-void yasm_floatnum_cleanup(void);
-
-/*@only@*/ yasm_floatnum *yasm_floatnum_new(const char *str);
-/*@only@*/ yasm_floatnum *yasm_floatnum_copy(const yasm_floatnum *flt);
-void yasm_floatnum_delete(/*@only@*/ yasm_floatnum *flt);
-
-/* calculation function: acc = acc op operand */
-void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- yasm_floatnum *operand, unsigned long lindex);
-
-/* The get functions return nonzero if flt can't fit into that size format:
- * -1 if underflow occurred, 1 if overflow occurred.
- */
-
-/* Essentially a convert to single-precision and return as 32-bit value.
- * The 32-bit value is a "standard" C value (eg, of unknown endian).
- */
-int yasm_floatnum_get_int(const yasm_floatnum *flt,
- /*@out@*/ unsigned long *ret_val);
-
-/* ptr will point to the Intel-format little-endian byte string after a
- * successful call (eg, [0] should be the first byte output to the file).
- */
-int yasm_floatnum_get_sized(const yasm_floatnum *flt,
- /*@out@*/ unsigned char *ptr, size_t size);
-
-/* Basic check to see if size is even valid for flt conversion (doesn't
- * actually check for underflow/overflow but rather checks for size=4,8,10).
- * Returns 1 if valid, 0 if not.
- */
-int yasm_floatnum_check_size(const yasm_floatnum *flt, size_t size);
-
-void yasm_floatnum_print(FILE *f, const yasm_floatnum *flt);
-
-#endif
+++ /dev/null
-/*
- * Hash Array Mapped Trie (HAMT) implementation
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * Based on the paper "Ideal Hash Tries" by Phil Bagwell [2000].
- * One algorithmic change from that described in the paper: we use the LSB's
- * of the key to index the root table and move upward in the key rather than
- * use the MSBs as described in the paper. The LSBs have more entropy.
- *
- * 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "hamt.h"
-
-typedef struct HAMTEntry {
- SLIST_ENTRY(HAMTEntry) next; /* next hash table entry */
- /*@dependent@*/ const char *str; /* string being hashed */
- /*@owned@*/ void *data; /* data pointer being stored */
-} HAMTEntry;
-
-typedef struct HAMTNode {
- unsigned long BitMapKey; /* 32 bits, bitmap or hash key */
- void *BaseValue; /* Base of HAMTNode list or value */
-} HAMTNode;
-
-struct HAMT {
- SLIST_HEAD(HAMTEntryHead, HAMTEntry) entries;
- HAMTNode *root;
- /*@exits@*/ void (*error_func) (const char *file, unsigned int line,
- const char *message);
-};
-
-/* XXX make a portable version of this. This depends on the pointer being
- * 4 or 2-byte aligned (as it uses the LSB of the pointer variable to store
- * the subtrie flag!
- */
-#define IsSubTrie(n) ((unsigned long)((n)->BaseValue) & 1)
-#define SetSubTrie(h, n, v) do { \
- if ((unsigned long)(v) & 1) \
- h->error_func(__FILE__, __LINE__, \
- N_("Subtrie is seen as subtrie before flag is set (misaligned?)")); \
- (n)->BaseValue = (void *)((unsigned long)(v) | 1); \
- } while (0)
-#define GetSubTrie(n) (HAMTNode *)((unsigned long)((n)->BaseValue)&~1UL)
-
-static unsigned long
-HashKey(const char *key)
-{
- unsigned long a=31415, b=27183, vHash;
- for (vHash=0; *key; key++, a*=b)
- vHash = a*vHash + *key;
- return vHash;
-}
-
-static unsigned long
-ReHashKey(const char *key, int Level)
-{
- unsigned long a=31415, b=27183, vHash;
- for (vHash=0; *key; key++, a*=b)
- vHash = a*vHash*(unsigned long)Level + *key;
- return vHash;
-}
-
-HAMT *
-HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
- const char *message))
-{
- /*@out@*/ HAMT *hamt = yasm_xmalloc(sizeof(HAMT));
- int i;
-
- SLIST_INIT(&hamt->entries);
- hamt->root = yasm_xmalloc(32*sizeof(HAMTNode));
-
- for (i=0; i<32; i++) {
- hamt->root[i].BitMapKey = 0;
- hamt->root[i].BaseValue = NULL;
- }
-
- hamt->error_func = error_func;
-
- return hamt;
-}
-
-static void
-HAMT_delete_trie(HAMTNode *node)
-{
- if (IsSubTrie(node)) {
- unsigned long i, Size;
-
- /* Count total number of bits in bitmap to determine size */
- BitCount(Size, node->BitMapKey);
- Size &= 0x1F; /* Clamp to <32 */
-
- for (i=0; i<Size; i++)
- HAMT_delete_trie(&(GetSubTrie(node))[i]);
- yasm_xfree(GetSubTrie(node));
- }
-}
-
-void
-HAMT_delete(HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data))
-{
- int i;
-
- /* delete entries */
- while (!SLIST_EMPTY(&hamt->entries)) {
- HAMTEntry *entry;
- entry = SLIST_FIRST(&hamt->entries);
- SLIST_REMOVE_HEAD(&hamt->entries, next);
- deletefunc(entry->data);
- yasm_xfree(entry);
- }
-
- /* delete trie */
- for (i=0; i<32; i++)
- HAMT_delete_trie(&hamt->root[i]);
-
- yasm_xfree(hamt->root);
- yasm_xfree(hamt);
-}
-
-int
-HAMT_traverse(HAMT *hamt, void *d,
- int (*func) (/*@dependent@*/ /*@null@*/ void *node,
- /*@null@*/ void *d))
-{
- HAMTEntry *entry;
- SLIST_FOREACH(entry, &hamt->entries, next)
- if (func(entry->data, d) == 0)
- return 0;
- return 1;
-}
-
-/*@-temptrans -kepttrans -mustfree@*/
-void *
-HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
- void (*deletefunc) (/*@only@*/ void *data))
-{
- HAMTNode *node, *newnodes;
- HAMTEntry *entry;
- unsigned long key, keypart, Map;
- int keypartbits = 0;
- int level = 0;
-
- key = HashKey(str);
- keypart = key & 0x1F;
- node = &hamt->root[keypart];
-
- if (!node->BaseValue) {
- node->BitMapKey = key;
- entry = yasm_xmalloc(sizeof(HAMTEntry));
- entry->str = str;
- entry->data = data;
- SLIST_INSERT_HEAD(&hamt->entries, entry, next);
- node->BaseValue = entry;
- if (IsSubTrie(node))
- hamt->error_func(__FILE__, __LINE__,
- N_("Data is seen as subtrie (misaligned?)"));
- *replace = 1;
- return data;
- }
-
- for (;;) {
- if (!(IsSubTrie(node))) {
- if (node->BitMapKey == key) {
- /*@-branchstate@*/
- if (*replace) {
- deletefunc(((HAMTEntry *)(node->BaseValue))->data);
- ((HAMTEntry *)(node->BaseValue))->str = str;
- ((HAMTEntry *)(node->BaseValue))->data = data;
- } else
- deletefunc(data);
- /*@=branchstate@*/
- return ((HAMTEntry *)(node->BaseValue))->data;
- } else {
- unsigned long key2 = node->BitMapKey;
- /* build tree downward until keys differ */
- for (;;) {
- unsigned long keypart2;
-
- /* replace node with subtrie */
- keypartbits += 5;
- if (keypartbits > 30) {
- /* Exceeded 32 bits: rehash */
- key = ReHashKey(str, level);
- key2 = ReHashKey(((HAMTEntry *)(node->BaseValue))->str,
- level);
- keypartbits = 0;
- }
- keypart = (key >> keypartbits) & 0x1F;
- keypart2 = (key2 >> keypartbits) & 0x1F;
-
- if (keypart == keypart2) {
- /* Still equal, build one-node subtrie and continue
- * downward.
- */
- newnodes = yasm_xmalloc(sizeof(HAMTNode));
- newnodes[0] = *node; /* structure copy */
- node->BitMapKey = 1<<keypart;
- SetSubTrie(hamt, node, newnodes);
- node = &newnodes[0];
- level++;
- } else {
- /* partitioned: allocate two-node subtrie */
- newnodes = yasm_xmalloc(2*sizeof(HAMTNode));
-
- entry = yasm_xmalloc(sizeof(HAMTEntry));
- entry->str = str;
- entry->data = data;
- SLIST_INSERT_HEAD(&hamt->entries, entry, next);
-
- /* Copy nodes into subtrie based on order */
- if (keypart2 < keypart) {
- newnodes[0] = *node; /* structure copy */
- newnodes[1].BitMapKey = key;
- newnodes[1].BaseValue = entry;
- } else {
- newnodes[0].BitMapKey = key;
- newnodes[0].BaseValue = entry;
- newnodes[1] = *node; /* structure copy */
- }
-
- /* Set bits in bitmap corresponding to keys */
- node->BitMapKey = (1UL<<keypart) | (1UL<<keypart2);
- SetSubTrie(hamt, node, newnodes);
- *replace = 1;
- return data;
- }
- }
- }
- }
-
- /* Subtrie: look up in bitmap */
- keypartbits += 5;
- if (keypartbits > 30) {
- /* Exceeded 32 bits of current key: rehash */
- key = ReHashKey(str, level);
- keypartbits = 0;
- }
- keypart = (key >> keypartbits) & 0x1F;
- if (!(node->BitMapKey & (1<<keypart))) {
- /* bit is 0 in bitmap -> add node to table */
- unsigned long Size;
-
- /* set bit to 1 */
- node->BitMapKey |= 1<<keypart;
-
- /* Count total number of bits in bitmap to determine new size */
- BitCount(Size, node->BitMapKey);
- Size &= 0x1F; /* Clamp to <32 */
- newnodes = yasm_xmalloc(Size*sizeof(HAMTNode));
-
- /* Count bits below to find where to insert new node at */
- BitCount(Map, node->BitMapKey & ~((~0UL)<<keypart));
- Map &= 0x1F; /* Clamp to <32 */
- /* Copy existing nodes leaving gap for new node */
- memcpy(newnodes, GetSubTrie(node), Map*sizeof(HAMTNode));
- memcpy(&newnodes[Map+1], &(GetSubTrie(node))[Map],
- (Size-Map-1)*sizeof(HAMTNode));
- /* Delete old subtrie */
- yasm_xfree(GetSubTrie(node));
- /* Set up new node */
- newnodes[Map].BitMapKey = key;
- entry = yasm_xmalloc(sizeof(HAMTEntry));
- entry->str = str;
- entry->data = data;
- SLIST_INSERT_HEAD(&hamt->entries, entry, next);
- newnodes[Map].BaseValue = entry;
- SetSubTrie(hamt, node, newnodes);
-
- *replace = 1;
- return data;
- }
-
- /* Count bits below */
- BitCount(Map, node->BitMapKey & ~((~0UL)<<keypart));
- Map &= 0x1F; /* Clamp to <32 */
-
- /* Go down a level */
- level++;
- node = &(GetSubTrie(node))[Map];
- }
-}
-/*@=temptrans =kepttrans =mustfree@*/
-
-void *
-HAMT_search(HAMT *hamt, const char *str)
-{
- HAMTNode *node;
- unsigned long key, keypart, Map;
- int keypartbits = 0;
- int level = 0;
-
- key = HashKey(str);
- keypart = key & 0x1F;
- node = &hamt->root[keypart];
-
- if (!node->BaseValue)
- return NULL;
-
- for (;;) {
- if (!(IsSubTrie(node))) {
- if (node->BitMapKey == key)
- return ((HAMTEntry *)(node->BaseValue))->data;
- else
- return NULL;
- }
-
- /* Subtree: look up in bitmap */
- keypartbits += 5;
- if (keypartbits > 30) {
- /* Exceeded 32 bits of current key: rehash */
- key = ReHashKey(str, level);
- keypartbits = 0;
- }
- keypart = (key >> keypartbits) & 0x1F;
- if (!(node->BitMapKey & (1<<keypart)))
- return NULL; /* bit is 0 in bitmap -> no match */
-
- /* Count bits below */
- BitCount(Map, node->BitMapKey & ~((~0UL)<<keypart));
- Map &= 0x1F; /* Clamp to <32 */
-
- /* Go down a level */
- level++;
- node = &(GetSubTrie(node))[Map];
- }
-}
-
+++ /dev/null
-/* $IdPath$
- * Hash Array Mapped Trie (HAMT) header file.
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_HAMT_H
-#define YASM_HAMT_H
-
-typedef struct HAMT HAMT;
-
-/* Creates new, empty, HAMT. error_func() is called when an internal error is
- * encountered--it should NOT return to the calling function.
- */
-HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file,
- unsigned int line,
- const char *message));
-
-/* Deletes HAMT and all data associated with it using deletefunc() on each data
- * item.
- */
-void HAMT_delete(/*@only@*/ HAMT *hamt,
- void (*deletefunc) (/*@only@*/ void *data));
-
-/* Inserts key into HAMT, associating it with data.
- * If the key is not present in the HAMT, inserts it, sets *replace to 1, and
- * returns the data passed in.
- * If the key is already present and *replace is 0, deletes the data passed
- * in using deletefunc() and returns the data currently associated with the
- * key.
- * If the key is already present and *replace is 1, deletes the data currently
- * associated with the key using deletefunc() and replaces it with the data
- * passed in.
- */
-/*@dependent@*/ void *HAMT_insert(HAMT *hamt, /*@dependent@*/ const char *str,
- /*@only@*/ void *data, int *replace,
- void (*deletefunc) (/*@only@*/ void *data));
-
-/* Searches for the data associated with a key in the HAMT. If the key is not
- * present, returns NULL.
- */
-/*@dependent@*/ /*@null@*/ void *HAMT_search(HAMT *hamt, const char *str);
-
-/* Traverse over all keys in HAMT, calling func() for each data item.
- * Stops early if func returns 0.
- */
-int HAMT_traverse(HAMT *hamt, /*@null@*/ void *d,
- int (*func) (/*@dependent@*/ /*@null@*/ void *node,
- /*@null@*/ void *d));
-
-#endif
+++ /dev/null
-/*
- * Integer number functions.
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include <ctype.h>
-
-#include "bitvect.h"
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-
-
-#define BITVECT_ALLOC_SIZE 80
-
-struct yasm_intnum {
- union val {
- unsigned long ul; /* integer value (for integers <=32 bits) */
- intptr bv; /* bit vector (for integers >32 bits) */
- } val;
- enum { INTNUM_UL, INTNUM_BV } type;
- unsigned char origsize; /* original (parsed) size, in bits */
-};
-
-/* static bitvect used for conversions */
-static /*@only@*/ wordptr conv_bv;
-
-
-void
-yasm_intnum_initialize(void)
-{
- conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
- BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
-}
-
-void
-yasm_intnum_cleanup(void)
-{
- BitVector_Destroy(conv_bv);
- BitVector_from_Dec_static_Shutdown();
-}
-
-yasm_intnum *
-yasm_intnum_new_dec(char *str, unsigned long lindex)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-
- intn->origsize = 0; /* no reliable way to figure this out */
-
- if (BitVector_from_Dec_static(conv_bv,
- (unsigned char *)str) == ErrCode_Ovfl)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("Numeric constant too large for internal format"));
- if (Set_Max(conv_bv) < 32) {
- intn->type = INTNUM_UL;
- intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
- } else {
- intn->type = INTNUM_BV;
- intn->val.bv = BitVector_Clone(conv_bv);
- }
-
- return intn;
-}
-
-yasm_intnum *
-yasm_intnum_new_bin(char *str, unsigned long lindex)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-
- intn->origsize = (unsigned char)strlen(str);
-
- if(intn->origsize > BITVECT_ALLOC_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("Numeric constant too large for internal format"));
-
- BitVector_from_Bin(conv_bv, (unsigned char *)str);
- if (Set_Max(conv_bv) < 32) {
- intn->type = INTNUM_UL;
- intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
- } else {
- intn->type = INTNUM_BV;
- intn->val.bv = BitVector_Clone(conv_bv);
- }
-
- return intn;
-}
-
-yasm_intnum *
-yasm_intnum_new_oct(char *str, unsigned long lindex)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-
- intn->origsize = strlen(str)*3;
-
- if(intn->origsize > BITVECT_ALLOC_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("Numeric constant too large for internal format"));
-
- BitVector_from_Oct(conv_bv, (unsigned char *)str);
- if (Set_Max(conv_bv) < 32) {
- intn->type = INTNUM_UL;
- intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
- } else {
- intn->type = INTNUM_BV;
- intn->val.bv = BitVector_Clone(conv_bv);
- }
-
- return intn;
-}
-
-yasm_intnum *
-yasm_intnum_new_hex(char *str, unsigned long lindex)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-
- intn->origsize = strlen(str)*4;
-
- if(intn->origsize > BITVECT_ALLOC_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("Numeric constant too large for internal format"));
-
- BitVector_from_Hex(conv_bv, (unsigned char *)str);
- if (Set_Max(conv_bv) < 32) {
- intn->type = INTNUM_UL;
- intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
- } else {
- intn->type = INTNUM_BV;
- intn->val.bv = BitVector_Clone(conv_bv);
- }
-
- return intn;
-}
-
-/*@-usedef -compdef -uniondef@*/
-yasm_intnum *
-yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
- size_t len = strlen(str);
-
- if (len > 4)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("character constant too large, ignoring trailing characters"));
-
- intn->val.ul = 0;
- intn->type = INTNUM_UL;
- intn->origsize = len*8;
-
- switch (len) {
- case 4:
- intn->val.ul |= (unsigned long)str[3];
- intn->val.ul <<= 8;
- /*@fallthrough@*/
- case 3:
- intn->val.ul |= (unsigned long)str[2];
- intn->val.ul <<= 8;
- /*@fallthrough@*/
- case 2:
- intn->val.ul |= (unsigned long)str[1];
- intn->val.ul <<= 8;
- /*@fallthrough@*/
- case 1:
- intn->val.ul |= (unsigned long)str[0];
- }
-
- return intn;
-}
-/*@=usedef =compdef =uniondef@*/
-
-yasm_intnum *
-yasm_intnum_new_uint(unsigned long i)
-{
- yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-
- intn->val.ul = i;
- intn->type = INTNUM_UL;
- intn->origsize = 0;
-
- return intn;
-}
-
-yasm_intnum *
-yasm_intnum_new_int(long i)
-{
- /* FIXME: Better way of handling signed numbers? */
- return yasm_intnum_new_uint((unsigned long)i);
-}
-
-yasm_intnum *
-yasm_intnum_copy(const yasm_intnum *intn)
-{
- yasm_intnum *n = yasm_xmalloc(sizeof(yasm_intnum));
-
- switch (intn->type) {
- case INTNUM_UL:
- n->val.ul = intn->val.ul;
- break;
- case INTNUM_BV:
- n->val.bv = BitVector_Clone(intn->val.bv);
- break;
- }
- n->type = intn->type;
- n->origsize = intn->origsize;
-
- return n;
-}
-
-void
-yasm_intnum_delete(yasm_intnum *intn)
-{
- if (intn->type == INTNUM_BV)
- BitVector_Destroy(intn->val.bv);
- yasm_xfree(intn);
-}
-
-/*@-nullderef -nullpass -branchstate@*/
-void
-yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
-{
- wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
- wordptr spare = (wordptr)NULL;
- boolean carry;
-
- /* upsize to bitvector op if one of two parameters is bitvector already.
- * BitVector results must be calculated through intermediate storage.
- */
- if (acc->type == INTNUM_BV || (operand && operand->type == INTNUM_BV)) {
- result = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
- spare = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-
- if (acc->type == INTNUM_BV)
- op1 = acc->val.bv;
- else {
- op1 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
- BitVector_Chunk_Store(op1, 32, 0, acc->val.ul);
- }
-
- if (operand) {
- if (operand->type == INTNUM_BV)
- op2 = acc->val.bv;
- else {
- op2 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
- BitVector_Chunk_Store(op2, 32, 0, operand->val.ul);
- }
- }
- }
-
- if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
- op != YASM_EXPR_LNOT)
- yasm_internal_error(N_("Operation needs an operand"));
-
- /* A operation does a bitvector computation if result is allocated. */
- switch (op) {
- case YASM_EXPR_ADD:
- if (result)
- BitVector_add(result, op1, op2, &carry);
- else
- acc->val.ul = acc->val.ul + operand->val.ul;
- break;
- case YASM_EXPR_SUB:
- if (result)
- BitVector_sub(result, op1, op2, &carry);
- else
- acc->val.ul = acc->val.ul - operand->val.ul;
- break;
- case YASM_EXPR_MUL:
- if (result)
- /* TODO: Make sure result size = op1+op2 */
- BitVector_Multiply(result, op1, op2);
- else
- acc->val.ul = acc->val.ul * operand->val.ul;
- break;
- case YASM_EXPR_DIV:
- if (result) {
- /* TODO: make sure op1 and op2 are unsigned */
- BitVector_Divide(result, op1, op2, spare);
- } else
- acc->val.ul = acc->val.ul / operand->val.ul;
- break;
- case YASM_EXPR_SIGNDIV:
- if (result)
- BitVector_Divide(result, op1, op2, spare);
- else
- acc->val.ul = (unsigned long)((signed long)acc->val.ul /
- (signed long)operand->val.ul);
- break;
- case YASM_EXPR_MOD:
- if (result) {
- /* TODO: make sure op1 and op2 are unsigned */
- BitVector_Divide(spare, op1, op2, result);
- } else
- acc->val.ul = acc->val.ul % operand->val.ul;
- break;
- case YASM_EXPR_SIGNMOD:
- if (result)
- BitVector_Divide(spare, op1, op2, result);
- else
- acc->val.ul = (unsigned long)((signed long)acc->val.ul %
- (signed long)operand->val.ul);
- break;
- case YASM_EXPR_NEG:
- if (result)
- BitVector_Negate(result, op1);
- else
- acc->val.ul = -(acc->val.ul);
- break;
- case YASM_EXPR_NOT:
- if (result)
- Set_Complement(result, op1);
- else
- acc->val.ul = ~(acc->val.ul);
- break;
- case YASM_EXPR_OR:
- if (result)
- Set_Union(result, op1, op2);
- else
- acc->val.ul = acc->val.ul | operand->val.ul;
- break;
- case YASM_EXPR_AND:
- if (result)
- Set_Intersection(result, op1, op2);
- else
- acc->val.ul = acc->val.ul & operand->val.ul;
- break;
- case YASM_EXPR_XOR:
- if (result)
- Set_ExclusiveOr(result, op1, op2);
- else
- acc->val.ul = acc->val.ul ^ operand->val.ul;
- break;
- case YASM_EXPR_SHL:
- if (result) {
- if (operand->type == INTNUM_UL) {
- BitVector_Copy(result, op1);
- BitVector_Move_Left(result, (N_int)operand->val.ul);
- } else /* don't even bother, just zero result */
- BitVector_Empty(result);
- } else
- acc->val.ul = acc->val.ul << operand->val.ul;
- break;
- case YASM_EXPR_SHR:
- if (result) {
- if (operand->type == INTNUM_UL) {
- BitVector_Copy(result, op1);
- BitVector_Move_Right(result, (N_int)operand->val.ul);
- } else /* don't even bother, just zero result */
- BitVector_Empty(result);
- } else
- acc->val.ul = acc->val.ul >> operand->val.ul;
- break;
- case YASM_EXPR_LOR:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, !BitVector_is_empty(op1) ||
- !BitVector_is_empty(op2));
- } else
- acc->val.ul = acc->val.ul || operand->val.ul;
- break;
- case YASM_EXPR_LAND:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, !BitVector_is_empty(op1) &&
- !BitVector_is_empty(op2));
- } else
- acc->val.ul = acc->val.ul && operand->val.ul;
- break;
- case YASM_EXPR_LNOT:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_is_empty(op1));
- } else
- acc->val.ul = !acc->val.ul;
- break;
- case YASM_EXPR_EQ:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_equal(op1, op2));
- } else
- acc->val.ul = acc->val.ul == operand->val.ul;
- break;
- case YASM_EXPR_LT:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_Lexicompare(op1, op2) < 0);
- } else
- acc->val.ul = acc->val.ul < operand->val.ul;
- break;
- case YASM_EXPR_GT:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_Lexicompare(op1, op2) > 0);
- } else
- acc->val.ul = acc->val.ul > operand->val.ul;
- break;
- case YASM_EXPR_LE:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_Lexicompare(op1, op2) <= 0);
- } else
- acc->val.ul = acc->val.ul <= operand->val.ul;
- break;
- case YASM_EXPR_GE:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, BitVector_Lexicompare(op1, op2) >= 0);
- } else
- acc->val.ul = acc->val.ul >= operand->val.ul;
- break;
- case YASM_EXPR_NE:
- if (result) {
- BitVector_Empty(result);
- BitVector_LSB(result, !BitVector_equal(op1, op2));
- } else
- acc->val.ul = acc->val.ul != operand->val.ul;
- break;
- case YASM_EXPR_IDENT:
- if (result)
- BitVector_Copy(result, op1);
- break;
- default:
- yasm_internal_error(N_("invalid operation in intnum calculation"));
- }
-
- /* If we were doing a bitvector computation... */
- if (result) {
- BitVector_Destroy(spare);
-
- if (op1 && acc->type != INTNUM_BV)
- BitVector_Destroy(op1);
- if (op2 && operand && operand->type != INTNUM_BV)
- BitVector_Destroy(op2);
-
- /* Try to fit the result into 32 bits if possible */
- if (Set_Max(result) < 32) {
- if (acc->type == INTNUM_BV) {
- BitVector_Destroy(acc->val.bv);
- acc->type = INTNUM_UL;
- }
- acc->val.ul = BitVector_Chunk_Read(result, 32, 0);
- BitVector_Destroy(result);
- } else {
- if (acc->type == INTNUM_BV) {
- BitVector_Copy(acc->val.bv, result);
- BitVector_Destroy(result);
- } else {
- acc->type = INTNUM_BV;
- acc->val.bv = result;
- }
- }
- }
-}
-/*@=nullderef =nullpass =branchstate@*/
-
-int
-yasm_intnum_is_zero(yasm_intnum *intn)
-{
- return ((intn->type == INTNUM_UL && intn->val.ul == 0) ||
- (intn->type == INTNUM_BV && BitVector_is_empty(intn->val.bv)));
-}
-
-int
-yasm_intnum_is_pos1(yasm_intnum *intn)
-{
- return ((intn->type == INTNUM_UL && intn->val.ul == 1) ||
- (intn->type == INTNUM_BV && Set_Max(intn->val.bv) == 0));
-}
-
-int
-yasm_intnum_is_neg1(yasm_intnum *intn)
-{
- return ((intn->type == INTNUM_UL && (long)intn->val.ul == -1) ||
- (intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
-}
-
-unsigned long
-yasm_intnum_get_uint(const yasm_intnum *intn)
-{
- switch (intn->type) {
- case INTNUM_UL:
- return intn->val.ul;
- case INTNUM_BV:
- return BitVector_Chunk_Read(intn->val.bv, 32, 0);
- default:
- yasm_internal_error(N_("unknown intnum type"));
- /*@notreached@*/
- return 0;
- }
-}
-
-long
-yasm_intnum_get_int(const yasm_intnum *intn)
-{
- switch (intn->type) {
- case INTNUM_UL:
- return (long)intn->val.ul;
- case INTNUM_BV:
- if (BitVector_msb_(intn->val.bv)) {
- /* it's negative: negate the bitvector to get a positive
- * number, then negate the positive number.
- */
- intptr abs_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
- long retval;
-
- BitVector_Negate(abs_bv, intn->val.bv);
- retval = -((long)BitVector_Chunk_Read(abs_bv, 32, 0));
-
- BitVector_Destroy(abs_bv);
- return retval;
- } else
- return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
- default:
- yasm_internal_error(N_("unknown intnum type"));
- /*@notreached@*/
- return 0;
- }
-}
-
-void
-yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr, size_t size)
-{
- unsigned long ul;
- unsigned char *buf;
- unsigned int len;
-
- switch (intn->type) {
- case INTNUM_UL:
- ul = intn->val.ul;
- while (size-- > 0) {
- YASM_WRITE_8(ptr, ul);
- if (ul != 0)
- ul >>= 8;
- }
- break;
- case INTNUM_BV:
- buf = BitVector_Block_Read(intn->val.bv, &len);
- if (len < (unsigned int)size)
- yasm_internal_error(N_("Invalid size specified (too large)"));
- memcpy(ptr, buf, size);
- yasm_xfree(buf);
- break;
- }
-}
-
-/* Return 1 if okay size, 0 if not */
-int
-yasm_intnum_check_size(const yasm_intnum *intn, size_t size, int is_signed)
-{
- if (is_signed) {
- long absl;
-
- switch (intn->type) {
- case INTNUM_UL:
- if (size >= 4)
- return 1;
- /* absl = absolute value of (long)intn->val.ul */
- absl = (long)intn->val.ul;
- if (absl < 0)
- absl = -absl;
-
- switch (size) {
- case 3:
- return ((absl & 0x00FFFFFF) == absl);
- case 2:
- return ((absl & 0x0000FFFF) == absl);
- case 1:
- return ((absl & 0x000000FF) == absl);
- }
- break;
- case INTNUM_BV:
- if (size >= 10)
- return 1;
- if (BitVector_msb_(intn->val.bv)) {
- /* it's negative */
- intptr abs_bv = BitVector_Create(BITVECT_ALLOC_SIZE,
- FALSE);
- int retval;
-
- BitVector_Negate(abs_bv, intn->val.bv);
- retval = Set_Max(abs_bv) < size*8;
-
- BitVector_Destroy(abs_bv);
- return retval;
- } else
- return (Set_Max(intn->val.bv) < size*8);
- }
- } else {
- switch (intn->type) {
- case INTNUM_UL:
- if (size >= 4)
- return 1;
- switch (size) {
- case 3:
- return ((intn->val.ul & 0x00FFFFFF) == intn->val.ul);
- case 2:
- return ((intn->val.ul & 0x0000FFFF) == intn->val.ul);
- case 1:
- return ((intn->val.ul & 0x000000FF) == intn->val.ul);
- }
- break;
- case INTNUM_BV:
- if (size >= 10)
- return 1;
- else
- return (Set_Max(intn->val.bv) < size*8);
- }
- }
- return 0;
-}
-
-void
-yasm_intnum_print(FILE *f, const yasm_intnum *intn)
-{
- unsigned char *s;
-
- switch (intn->type) {
- case INTNUM_UL:
- fprintf(f, "0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
- break;
- case INTNUM_BV:
- s = BitVector_to_Hex(intn->val.bv);
- fprintf(f, "0x%s/%u", (char *)s, (unsigned int)intn->origsize);
- yasm_xfree(s);
- break;
- }
-}
+++ /dev/null
-/* $IdPath$
- * Integer number functions header file.
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_INTNUM_H
-#define YASM_INTNUM_H
-
-void yasm_intnum_initialize(void);
-/* Clean up internal allocations */
-void yasm_intnum_cleanup(void);
-
-/*@only@*/ yasm_intnum *yasm_intnum_new_dec(char *str, unsigned long lindex);
-/*@only@*/ yasm_intnum *yasm_intnum_new_bin(char *str, unsigned long lindex);
-/*@only@*/ yasm_intnum *yasm_intnum_new_oct(char *str, unsigned long lindex);
-/*@only@*/ yasm_intnum *yasm_intnum_new_hex(char *str, unsigned long lindex);
-/* convert character constant to integer value, using NASM rules */
-/*@only@*/ yasm_intnum *yasm_intnum_new_charconst_nasm(const char *str,
- unsigned long lindex);
-/*@only@*/ yasm_intnum *yasm_intnum_new_uint(unsigned long i);
-/*@only@*/ yasm_intnum *yasm_intnum_new_int(long i);
-/*@only@*/ yasm_intnum *yasm_intnum_copy(const yasm_intnum *intn);
-void yasm_intnum_delete(/*@only@*/ yasm_intnum *intn);
-
-/* calculation function: acc = acc op operand */
-void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
-
-/* simple value checks (for catching identities and the like) */
-int yasm_intnum_is_zero(yasm_intnum *acc);
-int yasm_intnum_is_pos1(yasm_intnum *acc);
-int yasm_intnum_is_neg1(yasm_intnum *acc);
-
-/* The get functions truncate intn to the size specified; they don't check
- * for overflow. Use intnum_check_size() to check for overflow.
- */
-
-/* Return a 32-bit value in "standard" C format (eg, of unknown endian).
- * intnum_get_uint() treats intn as an unsigned integer (and returns as such).
- * intnum_get_int() treats intn as a signed integer (and returns as such).
- */
-unsigned long yasm_intnum_get_uint(const yasm_intnum *intn);
-long yasm_intnum_get_int(const yasm_intnum *intn);
-
-/* ptr will point to the Intel-format little-endian byte string after
- * call (eg, [0] should be the first byte output to the file).
- */
-void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
- size_t size);
-
-/* Check to see if intn will fit without overflow in size bytes.
- * If is_signed is 1, intn is treated as a signed number.
- * Returns 1 if it will, 0 if not.
- */
-int yasm_intnum_check_size(const yasm_intnum *intn, size_t size,
- int is_signed);
-
-void yasm_intnum_print(FILE *f, const yasm_intnum *intn);
-
-#endif
+++ /dev/null
-/*
- * YASM assembler line manager (for parse stage)
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "hamt.h"
-
-#include "errwarn.h"
-#include "linemgr.h"
-
-
-/* Source lines tracking */
-typedef struct {
- struct line_index_mapping *vector;
- unsigned long size;
- unsigned long allocated;
-} line_index_mapping_head;
-
-typedef struct line_index_mapping {
- /* monotonically increasing line index */
- unsigned long index;
-
- /* related info */
- /* "original" source filename */
- /*@null@*/ /*@dependent@*/ const char *filename;
- /* "original" source base line number */
- unsigned long line;
- /* "original" source line number increment (for following lines) */
- unsigned long line_inc;
-} line_index_mapping;
-
-typedef struct line_index_assoc_data_raw_head {
- /*@only@*/ void **vector;
- /*@null@*/ void (*delete_func) (/*@only@*/ void *);
- unsigned long size;
-} line_index_assoc_data_raw_head;
-
-typedef struct line_index_assoc_data {
- /*@only@*/ void *data;
- /*@null@*/ void (*delete_func) (/*@only@*/ void *);
- int type;
-} line_index_assoc_data;
-
-/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table;
-
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-static unsigned long line_index;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map;
-
-/* Associated data arrays for odd data types (those likely to have data
- * associated for every line).
- */
-static line_index_assoc_data_raw_head *line_index_assoc_data_array;
-#define MAX_LINE_INDEX_ASSOC_DATA_ARRAY 8
-
-static void
-filename_delete_one(/*@only@*/ void *d)
-{
- yasm_xfree(d);
-}
-
-static void
-yasm_std_linemgr_set(const char *filename, unsigned long line,
- unsigned long line_inc)
-{
- char *copy;
- int replace = 0;
- line_index_mapping *mapping;
-
- /* Create a new mapping in the map */
- if (line_index_map->size >= line_index_map->allocated) {
- /* allocate another size bins when full for 2x space */
- line_index_map->vector =
- yasm_xrealloc(line_index_map->vector, 2*line_index_map->allocated
- *sizeof(line_index_mapping));
- line_index_map->allocated *= 2;
- }
- mapping = &line_index_map->vector[line_index_map->size];
- line_index_map->size++;
-
- /* Fill it */
-
- /* Copy the filename (via shared storage) */
- copy = yasm__xstrdup(filename);
- /*@-aliasunique@*/
- mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
- filename_delete_one);
- /*@=aliasunique@*/
-
- mapping->index = line_index;
- mapping->line = line;
- mapping->line_inc = line_inc;
-}
-
-static void
-yasm_std_linemgr_initialize(void)
-{
- int i;
-
- filename_table = HAMT_new(yasm_internal_error_);
-
- line_index = 1;
-
- /* initialize mapping vector */
- line_index_map = yasm_xmalloc(sizeof(line_index_mapping_head));
- line_index_map->vector = yasm_xmalloc(8*sizeof(line_index_mapping));
- line_index_map->size = 0;
- line_index_map->allocated = 8;
-
- /* initialize associated data arrays */
- line_index_assoc_data_array =
- yasm_xmalloc(MAX_LINE_INDEX_ASSOC_DATA_ARRAY *
- sizeof(line_index_assoc_data_raw_head));
- for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
- line_index_assoc_data_array[i].vector = NULL;
- line_index_assoc_data_array[i].size = 0;
- }
-}
-
-static void
-yasm_std_linemgr_cleanup(void)
-{
- if (line_index_assoc_data_array) {
- int i;
- for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[i];
- if (adrh->delete_func && adrh->vector) {
- int j;
- for (j=0; j<adrh->size; j++) {
- if (adrh->vector[j])
- adrh->delete_func(adrh->vector[j]);
- }
- yasm_xfree(adrh->vector);
- }
- }
- yasm_xfree(line_index_assoc_data_array);
- line_index_assoc_data_array = NULL;
- }
-
- if (line_index_map) {
- yasm_xfree(line_index_map->vector);
- yasm_xfree(line_index_map);
- line_index_map = NULL;
- }
-
- if (filename_table) {
- HAMT_delete(filename_table, filename_delete_one);
- filename_table = NULL;
- }
-}
-
-static unsigned long
-yasm_std_linemgr_get_current(void)
-{
- return line_index;
-}
-
-static void
-yasm_std_linemgr_add_assoc_data(int type, /*@only@*/ void *data,
- /*@null@*/ void (*delete_func) (void *))
-{
- if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[type>>1];
-
- if (adrh->size == 0) {
- int i;
-
- adrh->size = 4;
- adrh->vector = yasm_xmalloc(adrh->size*sizeof(void *));
- adrh->delete_func = delete_func;
- for (i=0; i<adrh->size; i++)
- adrh->vector[i] = NULL;
- }
-
- while (line_index > adrh->size) {
- int i;
-
- /* allocate another size bins when full for 2x space */
- adrh->vector = yasm_xrealloc(adrh->vector,
- 2*adrh->size*sizeof(void *));
- for(i=adrh->size; i<adrh->size*2; i++)
- adrh->vector[i] = NULL;
- adrh->size *= 2;
- }
-
- adrh->vector[line_index-1] = data;
- if (adrh->delete_func != delete_func)
- yasm_internal_error(N_("multiple deletion functions specified"));
- } else {
- yasm_internal_error(N_("non-common data not supported yet"));
- delete_func(data);
- }
-}
-
-static unsigned long
-yasm_std_linemgr_goto_next(void)
-{
- return ++line_index;
-}
-
-static void
-yasm_std_linemgr_lookup(unsigned long lindex, const char **filename,
- unsigned long *line)
-{
- line_index_mapping *mapping;
- unsigned long vindex, step;
-
- assert(lindex <= line_index);
-
- /* Binary search through map to find highest line_index <= index */
- assert(line_index_map != NULL);
- vindex = 0;
- /* start step as the greatest power of 2 <= size */
- step = 1;
- while (step*2<=line_index_map->size)
- step*=2;
- while (step>0) {
- if (vindex+step < line_index_map->size
- && line_index_map->vector[vindex+step].index <= lindex)
- vindex += step;
- step /= 2;
- }
- mapping = &line_index_map->vector[vindex];
-
- *filename = mapping->filename;
- *line = mapping->line+mapping->line_inc*(lindex-mapping->index);
-}
-
-static /*@dependent@*/ /*@null@*/ void *
-yasm_std_linemgr_lookup_data(unsigned long lindex, int type)
-{
- if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[type>>1];
-
- if (lindex > adrh->size)
- return NULL;
- return adrh->vector[lindex-1];
- } else
- return NULL;
-}
-
-yasm_linemgr yasm_std_linemgr = {
- yasm_std_linemgr_initialize,
- yasm_std_linemgr_cleanup,
- yasm_std_linemgr_get_current,
- yasm_std_linemgr_add_assoc_data,
- yasm_std_linemgr_goto_next,
- yasm_std_linemgr_set,
- yasm_std_linemgr_lookup,
- yasm_std_linemgr_lookup_data
-};
+++ /dev/null
-/* $IdPath$
- * YASM line manager (for parse stage) header file
- *
- * Copyright (C) 2002 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.
- *
- * 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.
- */
-#ifndef YASM_LINEMGR_H
-#define YASM_LINEMGR_H
-
-/* Standard data types appropriate for use with add_assoc_data(). */
-typedef enum yasm_linemgr_std_type {
- /* Source line, a 0-terminated, allocated string. */
- YASM_LINEMGR_STD_TYPE_SOURCE = 1,
- /* User-defined types start here. Use odd numbers (low bit set) for types
- * very likely to have data associated for every line.
- */
- YASM_LINEMGR_STD_TYPE_USER = 4
-} yasm_linemgr_std_type;
-
-struct yasm_linemgr {
- /* Initialize cur_lindex and any manager internal data structures. */
- void (*initialize) (void);
-
- /* Cleans up any memory allocated. */
- void (*cleanup) (void);
-
- /* Returns the current line index. */
- unsigned long (*get_current) (void);
-
- /* Associates data with the current line index.
- * Deletes old data associated with type if present.
- * The function delete_func is used to delete the data (if non-NULL).
- * All data of a particular type needs to have the exact same deletion
- * function specified to this function on every call.
- */
- void (*add_assoc_data) (int type, /*@only@*/ void *data,
- /*@null@*/ void (*delete_func) (void *));
-
- /* Goes to the next line (increments the current line index), returns
- * the current (new) line index.
- */
- unsigned long (*goto_next) (void);
-
- /* Sets a new file/line association starting point at the current line
- * index. line_inc indicates how much the "real" line is incremented by
- * for each line index increment (0 is perfectly legal).
- */
- void (*set) (const char *filename, unsigned long line,
- unsigned long line_inc);
-
- /* Look up the associated actual file and line for a line index. */
- void (*lookup) (unsigned long lindex, /*@out@*/ const char **filename,
- /*@out@*/ unsigned long *line);
-
- /* Returns data associated with line index and type.
- * Returns NULL if no data of that type was associated with that line.
- */
- /*@dependent@*/ /*@null@*/ void * (*lookup_data) (unsigned long lindex,
- int type);
-};
-
-extern yasm_linemgr yasm_std_linemgr;
-
-#endif
+++ /dev/null
-/*
- * Program entry point, command line parsing
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "ltdl.h"
-#include "module.h"
-
-#include "bitvect.h"
-#include "file.h"
-
-#include "options.h"
-#include "linemgr.h"
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-#include "objfmt.h"
-#include "dbgfmt.h"
-#include "preproc.h"
-#include "parser.h"
-#include "optimizer.h"
-
-#include "arch.h"
-
-
-/* Extra path to search for our modules. */
-#ifndef YASM_MODULE_PATH_ENV
-# define YASM_MODULE_PATH_ENV "YASM_MODULE_PATH"
-#endif
-
-/* Preprocess-only buffer size */
-#define PREPROC_BUF_SIZE 16384
-
-/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
-static int special_options = 0;
-/*@null@*/ /*@dependent@*/ static yasm_arch *cur_arch = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_parser *cur_parser = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_preproc *cur_preproc = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_objfmt *cur_objfmt = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_optimizer *cur_optimizer = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_dbgfmt *cur_dbgfmt = NULL;
-static int preproc_only = 0;
-static int warning_error = 0; /* warnings being treated as errors */
-
-/*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode);
-static void cleanup(/*@null@*/ yasm_sectionhead *sections);
-
-/* Forward declarations: cmd line parser handlers */
-static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_parser_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_preproc_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_objfmt_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_dbgfmt_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra);
-static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra);
-
-static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/
- const char *ext, const char *def);
-static void print_error(const char *fmt, ...);
-
-static /*@exits@*/ void handle_yasm_int_error(const char *file,
- unsigned int line,
- const char *message);
-static /*@exits@*/ void handle_yasm_fatal(const char *message);
-static const char *handle_yasm_gettext(const char *msgid);
-static void print_yasm_error(const char *filename, unsigned long line,
- const char *msg);
-static void print_yasm_warning(const char *filename, unsigned long line,
- const char *msg);
-
-/* values for special_options */
-#define SPECIAL_SHOW_HELP 0x01
-#define SPECIAL_SHOW_VERSION 0x02
-
-/* command line options */
-static opt_option options[] =
-{
- { 0, "version", 0, opt_special_handler, SPECIAL_SHOW_VERSION, N_("show version text"), NULL },
- { 'h', "help", 0, opt_special_handler, SPECIAL_SHOW_HELP, N_("show help text"), NULL },
- { 'p', "parser", 1, opt_parser_handler, 0, N_("select parser"), N_("parser") },
- { 'r', "preproc", 1, opt_preproc_handler, 0, N_("select preprocessor"), N_("preproc") },
- { 'f', "oformat", 1, opt_objfmt_handler, 0, N_("select object format"), N_("format") },
- { 'g', "dformat", 1, opt_dbgfmt_handler, 0, N_("select debugging format"), N_("debug") },
- { 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("filename") },
- { 'w', NULL, 0, opt_warning_handler, 1, N_("inhibits warning messages"), NULL },
- { 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL },
- { 'e', "preproc-only", 0, preproc_only_handler, 0, N_("preprocess only (writes output to stdout by default)"), NULL },
-};
-
-/* version message */
-/*@observer@*/ static const char *version_msg[] = {
- PACKAGE " " VERSION "\n",
- N_("Copyright (c) 2001-2002 Peter Johnson and other"), " " PACKAGE " ",
- N_("developers.\n"),
- N_("This program is free software; you may redistribute it under the\n"),
- N_("terms of the GNU General Public License. Portions of this program\n"),
- N_("are licensed under the GNU Lesser General Public License or the\n"),
- N_("3-clause BSD license; see individual file comments for details.\n"),
- N_("This program has absolutely no warranty; not even for\n"),
- N_("merchantibility or fitness for a particular purpose.\n"),
- N_("Compiled on"), " " __DATE__ ".\n",
-};
-
-/* help messages */
-/*@observer@*/ static const char help_head[] = N_(
- "usage: yasm [option]* file\n"
- "Options:\n");
-/*@observer@*/ static const char help_tail[] = N_(
- "\n"
- "Files are asm sources to be assembled.\n"
- "\n"
- "Sample invocation:\n"
- " yasm -f elf -o object.o source.asm\n"
- "\n"
- "Report bugs to bug-yasm@tortall.net\n");
-
-/* main function */
-/*@-globstate -unrecog@*/
-int
-main(int argc, char *argv[])
-{
- /*@null@*/ FILE *in = NULL, *obj = NULL;
- yasm_sectionhead *sections;
- size_t i;
- int errors;
-
-#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
- setlocale(LC_MESSAGES, "");
-#endif
-#if defined(LOCALEDIR)
- bindtextdomain(PACKAGE, LOCALEDIR);
-#endif
- textdomain(PACKAGE);
-
- /* Initialize errwarn handling */
- yasm_internal_error_ = handle_yasm_int_error;
- yasm_fatal = handle_yasm_fatal;
- yasm_gettext_hook = handle_yasm_gettext;
- yasm_errwarn_initialize();
-
- /* Set libltdl malloc/free functions. */
-#ifdef WITH_DMALLOC
- lt_dlmalloc = malloc;
- lt_dlfree = free;
-#else
- lt_dlmalloc = yasm_xmalloc;
- lt_dlfree = yasm_xfree;
-#endif
-
- /* Initialize preloaded symbol lookup table. */
- LTDL_SET_PRELOADED_SYMBOLS();
-
- /* Initialize libltdl. */
- errors = lt_dlinit();
-
- /* Set up extra module search directories. */
- if (errors == 0) {
- const char *path = getenv(YASM_MODULE_PATH_ENV);
- if (path)
- errors = lt_dladdsearchdir(path);
- }
- if (errors != 0) {
- print_error(_("Module loader initialization failed"));
- return EXIT_FAILURE;
- }
-
- if (parse_cmdline(argc, argv, options, NELEMS(options), print_error))
- return EXIT_FAILURE;
-
- switch (special_options) {
- case SPECIAL_SHOW_HELP:
- /* Does gettext calls internally */
- help_msg(help_head, help_tail, options, NELEMS(options));
- return EXIT_SUCCESS;
- case SPECIAL_SHOW_VERSION:
- for (i=0; i<sizeof(version_msg)/sizeof(char *); i++)
- printf("%s", gettext(version_msg[i]));
- return EXIT_SUCCESS;
- }
-
- /* Initialize BitVector (needed for floating point). */
- if (BitVector_Boot() != ErrCode_Ok) {
- print_error(_("Could not initialize BitVector"));
- return EXIT_FAILURE;
- }
-
- if (in_filename && strcmp(in_filename, "-") != 0) {
- /* Open the input file (if not standard input) */
- in = fopen(in_filename, "rt");
- if (!in) {
- print_error(_("could not open file `%s'"), in_filename);
- yasm_xfree(in_filename);
- if (obj_filename)
- yasm_xfree(obj_filename);
- return EXIT_FAILURE;
- }
- } else {
- /* If no files were specified or filename was "-", read stdin */
- in = stdin;
- if (!in_filename)
- in_filename = yasm__xstrdup("-");
- }
-
- /* Initialize line manager */
- yasm_std_linemgr.initialize();
- yasm_std_linemgr.set(in_filename, 1, 1);
-
- /* Initialize intnum and floatnum */
- yasm_intnum_initialize();
- yasm_floatnum_initialize();
-
- /* Initialize symbol table */
- yasm_symrec_initialize();
-
- /* handle preproc-only case here */
- if (preproc_only) {
- char *preproc_buf = yasm_xmalloc(PREPROC_BUF_SIZE);
- size_t got;
-
- /* Default output to stdout if not specified */
- if (!obj_filename)
- obj = stdout;
- else {
- /* Open output (object) file */
- obj = open_obj("wt");
- if (!obj) {
- yasm_xfree(preproc_buf);
- return EXIT_FAILURE;
- }
- }
-
- /* If not already specified, default to nasm preproc. */
- if (!cur_preproc)
- cur_preproc = load_preproc("nasm");
-
- if (!cur_preproc) {
- print_error(_("Could not load default preprocessor"));
- cleanup(NULL);
- return EXIT_FAILURE;
- }
-
- /* Pre-process until done */
- cur_preproc->initialize(in, in_filename, &yasm_std_linemgr);
- while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
- fwrite(preproc_buf, got, 1, obj);
-
- if (in != stdin)
- fclose(in);
-
- if (obj != stdout)
- fclose(obj);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
- if (obj != stdout)
- remove(obj_filename);
- yasm_xfree(preproc_buf);
- cleanup(NULL);
- return EXIT_FAILURE;
- }
- yasm_xfree(preproc_buf);
- cleanup(NULL);
- return EXIT_SUCCESS;
- }
-
- /* Set x86 as the architecture (TODO: user choice) */
- cur_arch = load_arch("x86");
-
- if (!cur_arch) {
- print_error(_("Could not load default architecture"));
- return EXIT_FAILURE;
- }
-
- cur_arch->initialize();
-
- /* Set basic as the optimizer (TODO: user choice) */
- cur_optimizer = load_optimizer("basic");
-
- if (!cur_optimizer) {
- print_error(_("Could not load default optimizer"));
- return EXIT_FAILURE;
- }
-
- yasm_arch_common_initialize(cur_arch);
- yasm_expr_initialize(cur_arch);
- yasm_bc_initialize(cur_arch);
-
- /* If not already specified, default to bin as the object format. */
- if (!cur_objfmt)
- cur_objfmt = load_objfmt("bin");
-
- if (!cur_objfmt) {
- print_error(_("Could not load default object format"));
- return EXIT_FAILURE;
- }
-
- /* If not already specified, default to null as the debug format. */
- if (!cur_dbgfmt)
- cur_dbgfmt = load_dbgfmt("null");
- else {
- int matched_dbgfmt = 0;
- /* Check to see if the requested debug format is in the allowed list
- * for the active object format.
- */
- for (i=0; cur_objfmt->dbgfmt_keywords[i]; i++)
- if (yasm__strcasecmp(cur_objfmt->dbgfmt_keywords[i],
- cur_dbgfmt->keyword) == 0)
- matched_dbgfmt = 1;
- if (!matched_dbgfmt) {
- print_error(
- _("`%s' is not a valid debug format for object format `%s'"),
- cur_dbgfmt->keyword, cur_objfmt->keyword);
- if (in != stdin)
- fclose(in);
- /*cleanup(NULL);*/
- return EXIT_FAILURE;
- }
- }
-
- if (!cur_dbgfmt) {
- print_error(_("Could not load default debug format"));
- return EXIT_FAILURE;
- }
-
- /* determine the object filename if not specified */
- if (!obj_filename) {
- if (in == stdin)
- /* Default to yasm.out if no obj filename specified */
- obj_filename = yasm__xstrdup("yasm.out");
- else
- /* replace (or add) extension */
- obj_filename = replace_extension(in_filename,
- cur_objfmt->extension,
- "yasm.out");
- }
-
- /* Initialize the object format */
- if (cur_objfmt->initialize)
- cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt,
- cur_arch);
-
- /* Set NASM as the parser */
- cur_parser = load_parser("nasm");
- if (!cur_parser) {
- print_error(_("unrecognized parser `%s'"), "nasm");
- cleanup(NULL);
- return EXIT_FAILURE;
- }
-
- /* If not already specified, default to the parser's default preproc. */
- if (!cur_preproc)
- cur_preproc = load_preproc(cur_parser->default_preproc_keyword);
- else {
- int matched_preproc = 0;
- /* Check to see if the requested preprocessor is in the allowed list
- * for the active parser.
- */
- for (i=0; cur_parser->preproc_keywords[i]; i++)
- if (yasm__strcasecmp(cur_parser->preproc_keywords[i],
- cur_preproc->keyword) == 0)
- matched_preproc = 1;
- if (!matched_preproc) {
- print_error(_("`%s' is not a valid preprocessor for parser `%s'"),
- cur_preproc->keyword, cur_parser->keyword);
- if (in != stdin)
- fclose(in);
- cleanup(NULL);
- return EXIT_FAILURE;
- }
- }
-
- /* Get initial x86 BITS setting from object format */
- if (strcmp(cur_arch->keyword, "x86") == 0) {
- unsigned char *x86_mode_bits;
- x86_mode_bits = (unsigned char *)get_module_data("x86", "mode_bits");
- if (x86_mode_bits)
- *x86_mode_bits = cur_objfmt->default_x86_mode_bits;
- }
-
- /* Parse! */
- sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
- &yasm_std_linemgr, in, in_filename, 0);
-
- /* Close input file */
- if (in != stdin)
- fclose(in);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
- cleanup(sections);
- return EXIT_FAILURE;
- }
-
- yasm_symrec_parser_finalize();
- cur_optimizer->optimize(sections);
-
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
- cleanup(sections);
- return EXIT_FAILURE;
- }
-
- /* open the object file for output (if not already opened by dbg objfmt) */
- if (!obj && strcmp(cur_objfmt->keyword, "dbg") != 0) {
- obj = open_obj("wb");
- if (!obj) {
- cleanup(sections);
- return EXIT_FAILURE;
- }
- }
-
- /* Write the object file */
- cur_objfmt->output(obj?obj:stderr, sections);
-
- /* Close object file */
- if (obj)
- fclose(obj);
-
- /* If we had an error at this point, we also need to delete the output
- * object file (to make sure it's not left newer than the source).
- */
- if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
- remove(obj_filename);
- cleanup(sections);
- return EXIT_FAILURE;
- }
-
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
-
- cleanup(sections);
- return EXIT_SUCCESS;
-}
-/*@=globstate =unrecog@*/
-
-/* Open the object file. Returns 0 on failure. */
-static FILE *
-open_obj(const char *mode)
-{
- FILE *obj;
-
- assert(obj_filename != NULL);
-
- obj = fopen(obj_filename, mode);
- if (!obj)
- print_error(_("could not open file `%s'"), obj_filename);
- return obj;
-}
-
-/* Define DO_FREE to 1 to enable deallocation of all data structures.
- * Useful for detecting memory leaks, but slows down execution unnecessarily
- * (as the OS will free everything we miss here).
- */
-#define DO_FREE 1
-
-/* Cleans up all allocated structures. */
-static void
-cleanup(yasm_sectionhead *sections)
-{
- if (DO_FREE) {
- if (cur_objfmt && cur_objfmt->cleanup)
- cur_objfmt->cleanup();
- if (cur_dbgfmt && cur_dbgfmt->cleanup)
- cur_dbgfmt->cleanup();
- if (cur_preproc)
- cur_preproc->cleanup();
- if (sections)
- yasm_sections_delete(sections);
- yasm_symrec_cleanup();
- if (cur_arch)
- cur_arch->cleanup();
-
- yasm_floatnum_cleanup();
- yasm_intnum_cleanup();
-
- yasm_errwarn_cleanup();
- yasm_std_linemgr.cleanup();
-
- BitVector_Shutdown();
- }
-
- unload_modules();
-
- /* Finish with libltdl. */
- lt_dlexit();
-
- if (DO_FREE) {
- if (in_filename)
- yasm_xfree(in_filename);
- if (obj_filename)
- yasm_xfree(obj_filename);
- }
-}
-
-/*
- * Command line options handlers
- */
-int
-not_an_option_handler(char *param)
-{
- if (in_filename) {
- print_error(
- _("warning: can open only one input file, only the last file will be processed"));
- yasm_xfree(in_filename);
- }
-
- in_filename = yasm__xstrdup(param);
-
- return 0;
-}
-
-static int
-opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
-{
- if (special_options == 0)
- special_options = extra;
- return 0;
-}
-
-static int
-opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
-{
- assert(param != NULL);
- cur_parser = load_parser(param);
- if (!cur_parser) {
- print_error(_("unrecognized parser `%s'"), param);
- return 1;
- }
- return 0;
-}
-
-static int
-opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
-{
- assert(param != NULL);
- cur_preproc = load_preproc(param);
- if (!cur_preproc) {
- print_error(_("unrecognized preprocessor `%s'"), param);
- return 1;
- }
- return 0;
-}
-
-static int
-opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
-{
- assert(param != NULL);
- cur_objfmt = load_objfmt(param);
- if (!cur_objfmt) {
- print_error(_("unrecognized object format `%s'"), param);
- return 1;
- }
- return 0;
-}
-
-static int
-opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
-{
- assert(param != NULL);
- cur_dbgfmt = load_dbgfmt(param);
- if (!cur_dbgfmt) {
- print_error(_("unrecognized debugging format `%s'"), param);
- return 1;
- }
- return 0;
-}
-
-static int
-opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
- /*@unused@*/ int extra)
-{
- if (obj_filename) {
- print_error(
- _("warning: can output to only one object file, last specified used"));
- yasm_xfree(obj_filename);
- }
-
- assert(param != NULL);
- obj_filename = yasm__xstrdup(param);
-
- return 0;
-}
-
-static int
-opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
-{
- int enable = 1; /* is it disabling the warning instead of enabling? */
-
- if (extra == 1) {
- /* -w, disable warnings */
- yasm_warn_disable_all();
- return 0;
- }
-
- /* skip past 'W' */
- cmd++;
-
- /* detect no- prefix to disable the warning */
- if (cmd[0] == 'n' && cmd[1] == 'o' && cmd[2] == '-') {
- enable = 0;
- cmd += 3; /* skip past it to get to the warning name */
- }
-
- if (cmd[0] == '\0')
- /* just -W or -Wno-, so definitely not valid */
- return 1;
- else if (strcmp(cmd, "error") == 0) {
- warning_error = enable;
- } else if (strcmp(cmd, "unrecognized-char") == 0) {
- if (enable)
- yasm_warn_enable(YASM_WARN_UNREC_CHAR);
- else
- yasm_warn_disable(YASM_WARN_UNREC_CHAR);
- } else
- return 1;
-
- return 0;
-}
-
-static int
-preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param,
- /*@unused@*/ int extra)
-{
- preproc_only = 1;
- return 0;
-}
-
-/* Replace extension on a filename (or append one if none is present).
- * If output filename would be identical to input (same extension out as in),
- * returns (copy of) def.
- * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext
- * means the trailing '.' should be included.
- */
-static char *
-replace_extension(const char *orig, /*@null@*/ const char *ext,
- const char *def)
-{
- char *out, *outext;
-
- /* allocate enough space for full existing name + extension */
- out = yasm_xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1));
- strcpy(out, orig);
- outext = strrchr(out, '.');
- if (outext) {
- /* Existing extension: make sure it's not the same as the replacement
- * (as we don't want to overwrite the source file).
- */
- outext++; /* advance past '.' */
- if (ext && strcmp(outext, ext) == 0) {
- outext = NULL; /* indicate default should be used */
- print_error(
- _("file name already ends in `.%s': output will be in `%s'"),
- ext, def);
- }
- } else {
- /* No extension: make sure the output extension is not empty
- * (again, we don't want to overwrite the source file).
- */
- if (!ext)
- print_error(
- _("file name already has no extension: output will be in `%s'"),
- def);
- else {
- outext = strrchr(out, '\0'); /* point to end of the string */
- *outext++ = '.'; /* append '.' */
- }
- }
-
- /* replace extension or use default name */
- if (outext) {
- if (!ext) {
- /* Back up and replace '.' with string terminator */
- outext--;
- *outext = '\0';
- } else
- strcpy(outext, ext);
- } else
- strcpy(out, def);
-
- return out;
-}
-
-static void
-print_error(const char *fmt, ...)
-{
- va_list va;
- fprintf(stderr, "yasm: ");
- va_start(va, fmt);
- vfprintf(stderr, fmt, va);
- va_end(va);
- fputc('\n', stderr);
-}
-
-static /*@exits@*/ void
-handle_yasm_int_error(const char *file, unsigned int line, const char *message)
-{
- fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
- gettext(message));
-#ifdef HAVE_ABORT
- abort();
-#else
- exit(EXIT_FAILURE);
-#endif
-}
-
-static /*@exits@*/ void
-handle_yasm_fatal(const char *message)
-{
- fprintf(stderr, _("FATAL: %s\n"), gettext(message));
-#ifdef HAVE_ABORT
- abort();
-#else
- exit(EXIT_FAILURE);
-#endif
-}
-
-static const char *
-handle_yasm_gettext(const char *msgid)
-{
- return gettext(msgid);
-}
-
-static void
-print_yasm_error(const char *filename, unsigned long line, const char *msg)
-{
- fprintf(stderr, "%s:%lu: %s\n", filename, line, msg);
-}
-
-static void
-print_yasm_warning(const char *filename, unsigned long line, const char *msg)
-{
- fprintf(stderr, "%s:%lu: %s %s\n", filename, line, _("warning:"), msg);
-}
+++ /dev/null
-/*
- * YASM module loader
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "ltdl.h"
-
-#include "module.h"
-#include "objfmt.h"
-#include "parser.h"
-
-
-typedef struct module {
- SLIST_ENTRY(module) link;
- /*@only@*/ char *keyword; /* module keyword */
- lt_dlhandle handle; /* dlopen handle */
-} module;
-
-SLIST_HEAD(modulehead, module) modules = SLIST_HEAD_INITIALIZER(modules);
-
-/* NULL-terminated list of all possibly available object format keywords.
- * Could improve this a little by generating automatically at build-time.
- */
-/*@-nullassign@*/
-const char *objfmts[] = {
- "dbg",
- "bin",
- "coff",
- NULL
-};
-/*@=nullassign@*/
-
-/* NULL-terminated list of all possibly available parser keywords.
- * Could improve this a little by generating automatically at build-time.
- */
-/*@-nullassign@*/
-const char *parsers[] = {
- "nasm",
- NULL
-};
-/*@=nullassign@*/
-
-
-static /*@dependent@*/ /*@null@*/ module *
-load_module(const char *keyword)
-{
- module *m;
- char *name;
- lt_dlhandle handle;
-
- /* See if the module has already been loaded. */
- SLIST_FOREACH(m, &modules, link) {
- if (yasm__strcasecmp(m->keyword, keyword) == 0)
- return m;
- }
-
- /* Look for dynamic module. First build full module name from keyword. */
- name = yasm_xmalloc(5+strlen(keyword)+1);
- strcpy(name, "yasm-");
- strcat(name, keyword);
- handle = lt_dlopenext(name);
-
- if (!handle) {
- yasm_xfree(name);
- return NULL;
- }
-
- m = yasm_xmalloc(sizeof(module));
- m->keyword = name;
- strcpy(m->keyword, keyword);
- m->handle = handle;
- SLIST_INSERT_HEAD(&modules, m, link);
- return m;
-}
-
-void
-unload_modules(void)
-{
- module *m;
-
- while (!SLIST_EMPTY(&modules)) {
- m = SLIST_FIRST(&modules);
- SLIST_REMOVE_HEAD(&modules, link);
- yasm_xfree(m->keyword);
- lt_dlclose(m->handle);
- yasm_xfree(m);
- }
-}
-
-void *
-get_module_data(const char *keyword, const char *symbol)
-{
- /*@dependent@*/ module *m;
-
- /* Load module */
- m = load_module(keyword);
- if (!m)
- return NULL;
-
- /* Find and return data pointer: NULL if it doesn't exist */
- return lt_dlsym(m->handle, symbol);
-}
-
-void
-list_objfmts(void (*printfunc) (const char *name, const char *keyword))
-{
- int i;
- yasm_objfmt *of;
-
- /* Go through available list, and try to load each one */
- for (i = 0; objfmts[i]; i++) {
- of = load_objfmt(objfmts[i]);
- if (of)
- printfunc(of->name, of->keyword);
- }
-}
-
-void
-list_parsers(void (*printfunc) (const char *name, const char *keyword))
-{
- int i;
- yasm_parser *p;
-
- /* Go through available list, and try to load each one */
- for (i = 0; parsers[i]; i++) {
- p = load_parser(parsers[i]);
- if (p)
- printfunc(p->name, p->keyword);
- }
-}
+++ /dev/null
-/* $IdPath$
- * YASM module loader header file
- *
- * Copyright (C) 2002 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.
- *
- * 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.
- */
-#ifndef YASM_MODULE_H
-#define YASM_MODULE_H
-
-void unload_modules(void);
-/*@dependent@*/ /*@null@*/ void *get_module_data(const char *keyword,
- const char *symbol);
-
-#define load_arch(keyword) get_module_data(keyword, "arch")
-#define load_dbgfmt(keyword) get_module_data(keyword, "dbgfmt")
-#define load_objfmt(keyword) get_module_data(keyword, "objfmt")
-#define load_optimizer(keyword) get_module_data(keyword, "optimizer")
-#define load_parser(keyword) get_module_data(keyword, "parser")
-#define load_preproc(keyword) get_module_data(keyword, "preproc")
-
-/* Lists all available object formats. Calls printfunc with the name and
- * keyword of each available format.
- */
-void list_objfmts(void (*printfunc) (const char *name, const char *keyword));
-
-/* Lists all available parsers. Calls printfunc with the name and keyword
- * of each available parser.
- */
-void list_parsers(void (*printfunc) (const char *name, const char *keyword));
-
-#endif
+++ /dev/null
-/* $IdPath$
- * YASM object format module interface header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_OBJFMT_H
-#define YASM_OBJFMT_H
-
-/* Interface to the object format module(s) */
-struct yasm_objfmt {
- /* one-line description of the format */
- const char *name;
-
- /* keyword used to select format on the command line */
- const char *keyword;
-
- /* default output file extension (without the '.').
- * NULL means no extension, with no '.', while "" includes the '.'.
- */
- /*@null@*/ const char *extension;
-
- /* default (starting) section name */
- const char *default_section_name;
-
- /* default (starting) x86 BITS setting */
- const unsigned char default_x86_mode_bits;
-
- /* NULL-terminated list of debugging formats that are valid to use with
- * this object format. The null debugging format (null_dbgfmt) should
- * always be in this list so it's possible to have no debugging output.
- */
- const char **dbgfmt_keywords;
-
- /* Default debugging format (set even if there's only one available to
- * use).
- */
- const char *default_dbgfmt_keyword;
-
- /* Initializes object output. Must be called before any other object
- * format functions. Should NOT open the object file; the filenames are
- * provided solely for informational purposes.
- */
- void (*initialize) (const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a);
-
- /* Write out (post-optimized) sections to the object file.
- * This function may call symrec functions as necessary (including
- * symrec_traverse) to retrieve symbolic information.
- */
- void (*output) (FILE *f, yasm_sectionhead *sections);
-
- /* Cleans up anything allocated by initialize.
- * May be NULL if not needed by the object format.
- */
- void (*cleanup) (void);
-
- /* Switch object file sections. The first val of the valparams should
- * be the section name. Returns NULL if something's wrong, otherwise
- * returns the new section.
- */
- /*@observer@*/ /*@null@*/ yasm_section *
- (*sections_switch)(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
-
- /* Object format-specific data handling functions for sections.
- * May be NULL if no data is ever allocated in sections_switch().
- */
- void (*section_data_delete)(/*@only@*/ void *data);
- void (*section_data_print)(FILE *f, int indent_level, void *data);
-
- /* These functions should call symrec_set_of_data() to store data.
- * May be NULL if objfmt doesn't care about such declarations.
- */
- void (*extern_declare)(yasm_symrec *sym,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
- void (*global_declare)(yasm_symrec *sym,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
- void (*common_declare)(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
-
- /* May be NULL if symrec_set_of_data() is never called. */
- void (*symrec_data_delete)(/*@only@*/ void *data);
- void (*symrec_data_print)(FILE *f, int indent_level, void *data);
-
- /* Object format-specific directive support. Returns 1 if directive was
- * not recognized. Returns 0 if directive was recognized, even if it
- * wasn't valid.
- */
- int (*directive)(const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
-
- /* Bytecode objfmt data (BC_OBJFMT_DATA) handling functions.
- * May be NULL if no BC_OBJFMT_DATA is ever allocated by the object format.
- */
- void (*bc_objfmt_data_delete)(unsigned int type, /*@only@*/ void *data);
- void (*bc_objfmt_data_print)(FILE *f, int indent_level, unsigned int type,
- const void *data);
-};
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/objfmts/dbg/Makefile.inc \
- src/objfmts/bin/Makefile.inc \
- src/objfmts/coff/Makefile.inc
-
-include src/objfmts/dbg/Makefile.inc
-include src/objfmts/bin/Makefile.inc
-include src/objfmts/coff/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-bin.la
-
-yasm_bin_la_SOURCES = \
- src/objfmts/bin/bin-objfmt.c
-yasm_bin_la_LDFLAGS = -module -avoid-version
-yasm_bin_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-bin.la
-
-EXTRA_DIST += \
- src/objfmts/bin/tests/Makefile.inc
-
-include src/objfmts/bin/tests/Makefile.inc
+++ /dev/null
-/*
- * Flat-format binary object format
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-
-#include "expr-int.h"
-#include "bc-int.h"
-
-#include "arch.h"
-#include "objfmt.h"
-
-
-#define REGULAR_OUTBUF_SIZE 1024
-
-yasm_objfmt yasm_bin_LTX_objfmt;
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-
-static void
-bin_objfmt_initialize(/*@unused@*/ const char *in_filename,
- /*@unused@*/ const char *obj_filename,
- /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a)
-{
- cur_arch = a;
-}
-
-/* Aligns sect to either its specified alignment (in its objfmt-specific data)
- * or def_align if no alignment was specified. Uses prevsect and base to both
- * determine the new starting address (returned) and the total length of
- * prevsect after sect has been aligned.
- */
-static unsigned long
-bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect,
- unsigned long base, unsigned long def_align,
- /*@out@*/ unsigned long *prevsectlen,
- /*@out@*/ unsigned long *padamt)
-{
- /*@dependent@*/ /*@null@*/ yasm_bytecode *last;
- unsigned long start;
- /*@dependent@*/ /*@null@*/ unsigned long *alignptr;
- unsigned long align;
-
- /* Figure out the size of .text by looking at the last bytecode's offset
- * plus its length. Add the start and size together to get the new start.
- */
- last = yasm_bcs_last(yasm_section_get_bytecodes(prevsect));
- if (last)
- *prevsectlen = last->offset + last->len;
- else
- *prevsectlen = 0;
- start = base + *prevsectlen;
-
- /* Round new start up to alignment of .data section, and adjust textlen to
- * indicate padded size. Because aignment is always a power of two, we
- * can use some bit trickery to do this easily.
- */
- alignptr = yasm_section_get_of_data(sect);
- if (alignptr)
- align = *alignptr;
- else
- align = def_align; /* No alignment: use default */
-
- if (start & (align-1))
- start = (start & ~(align-1)) + align;
-
- *padamt = start - (base + *prevsectlen);
-
- return start;
-}
-
-typedef struct bin_objfmt_output_info {
- /*@dependent@*/ FILE *f;
- /*@only@*/ unsigned char *buf;
- /*@observer@*/ const yasm_section *sect;
- unsigned long start;
-} bin_objfmt_output_info;
-
-static /*@only@*/ yasm_expr *
-bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e,
- /*@unused@*/ /*@null@*/ void *d)
-{
- int i;
- /*@dependent@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
- /*@null@*/ yasm_intnum *dist;
-
- for (i=0; i<e->numterms; i++) {
- /* Transform symrecs that reference sections into
- * start expr + intnum(dist).
- */
- if (e->terms[i].type == YASM_EXPR_SYM &&
- yasm_symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
- (dist = yasm_common_calc_bc_dist(sect, NULL, precbc))) {
- const yasm_expr *start = yasm_section_get_start(sect);
- e->terms[i].type = YASM_EXPR_EXPR;
- e->terms[i].data.expn =
- yasm_expr_new(YASM_EXPR_ADD,
- yasm_expr_expr(yasm_expr_copy(start)),
- yasm_expr_int(dist), start->line);
- }
- }
-
- return e;
-}
-
-static int
-bin_objfmt_output_expr(yasm_expr **ep, unsigned char **bufp,
- unsigned long valsize,
- /*@unused@*/ unsigned long offset,
- /*@observer@*/ const yasm_section *sect,
- /*@observer@*/ const yasm_bytecode *bc, int rel,
- /*@unused@*/ /*@null@*/ void *d)
-{
- /*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
- /*@dependent@*/ /*@null@*/ const yasm_floatnum *flt;
-
- assert(info != NULL);
-
- /* For binary output, this is trivial: any expression that doesn't simplify
- * to an integer is an error (references something external).
- * Other object formats need to generate their relocation list from here!
- */
-
- *ep = yasm_expr__level_tree(*ep, 1, 1, NULL, bin_objfmt_expr_xform, NULL,
- NULL);
-
- /* Handle floating point expressions */
- flt = yasm_expr_get_floatnum(ep);
- if (flt)
- return cur_arch->floatnum_tobytes(flt, bufp, valsize, *ep);
-
- /* Handle integer expressions */
- intn = yasm_expr_get_intnum(ep, NULL);
- if (intn)
- return cur_arch->intnum_tobytes(intn, bufp, valsize, *ep, bc, rel);
-
- /* Check for complex float expressions */
- if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
- yasm__error((*ep)->line, N_("floating point expression too complex"));
- return 1;
- }
-
- /* Couldn't output, assume it contains an external reference. */
- yasm__error((*ep)->line,
- N_("binary object format does not support external references"));
- return 1;
-}
-
-static int
-bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
-{
- /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
- /*@null@*/ /*@only@*/ unsigned char *bigbuf;
- unsigned long size = REGULAR_OUTBUF_SIZE;
- unsigned long multiple;
- unsigned long i;
- int gap;
-
- assert(info != NULL);
-
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
- info, bin_objfmt_output_expr, NULL);
-
- /* Don't bother doing anything else if size ended up being 0. */
- if (size == 0) {
- if (bigbuf)
- yasm_xfree(bigbuf);
- return 0;
- }
-
- /* Warn that gaps are converted to 0 and write out the 0's. */
- if (gap) {
- unsigned long left;
- yasm__warning(YASM_WARN_GENERAL, bc->line,
- N_("uninitialized space declared in code/data section: zeroing"));
- /* Write out in chunks */
- memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
- left = multiple*size;
- while (left > REGULAR_OUTBUF_SIZE) {
- fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
- left -= REGULAR_OUTBUF_SIZE;
- }
- fwrite(info->buf, left, 1, info->f);
- } else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
- }
-
- /* If bigbuf was allocated, free it */
- if (bigbuf)
- yasm_xfree(bigbuf);
-
- return 0;
-}
-
-static void
-bin_objfmt_output(FILE *f, yasm_sectionhead *sections)
-{
- /*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect;
- /*@null@*/ yasm_expr *startexpr;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *startnum;
- unsigned long start = 0, textstart = 0, datastart = 0;
- unsigned long textlen = 0, textpad = 0, datalen = 0, datapad = 0;
- unsigned long *prevsectlenptr, *prevsectpadptr;
- unsigned long i;
- bin_objfmt_output_info info;
-
- info.f = f;
- info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
-
- text = yasm_sections_find_general(sections, ".text");
- data = yasm_sections_find_general(sections, ".data");
- bss = yasm_sections_find_general(sections, ".bss");
-
- if (!text)
- yasm_internal_error(N_("No `.text' section in bin objfmt output"));
-
- /* First determine the actual starting offsets for .data and .bss.
- * As the order in the file is .text -> .data -> .bss (not present),
- * use the last bytecode in .text (and the .text section start) to
- * determine the starting offset in .data, and likewise for .bss.
- * Also compensate properly for alignment.
- */
-
- /* Find out the start of .text */
- startexpr = yasm_expr_copy(yasm_section_get_start(text));
- assert(startexpr != NULL);
- startnum = yasm_expr_get_intnum(&startexpr, NULL);
- if (!startnum)
- yasm_internal_error(N_("Complex expr for start in bin objfmt output"));
- start = yasm_intnum_get_uint(startnum);
- yasm_expr_delete(startexpr);
- textstart = start;
-
- /* Align .data and .bss (if present) by adjusting their starts. */
- prevsect = text;
- prevsectlenptr = &textlen;
- prevsectpadptr = &textpad;
- if (data) {
- start = bin_objfmt_align_section(data, prevsect, start, 4,
- prevsectlenptr, prevsectpadptr);
- yasm_section_set_start(data, start, 0);
- datastart = start;
- prevsect = data;
- prevsectlenptr = &datalen;
- prevsectpadptr = &datapad;
- }
- if (bss) {
- start = bin_objfmt_align_section(bss, prevsect, start, 4,
- prevsectlenptr, prevsectpadptr);
- yasm_section_set_start(bss, start, 0);
- }
-
- /* Output .text first. */
- info.sect = text;
- info.start = textstart;
- yasm_bcs_traverse(yasm_section_get_bytecodes(text), &info,
- bin_objfmt_output_bytecode);
-
- /* If .data is present, output it */
- if (data) {
- /* Add padding to align .data. Just use a for loop, as this will
- * seldom be very many bytes.
- */
- for (i=0; i<textpad; i++)
- fputc(0, f);
-
- /* Output .data bytecodes */
- info.sect = data;
- info.start = datastart;
- yasm_bcs_traverse(yasm_section_get_bytecodes(data), &info,
- bin_objfmt_output_bytecode);
- }
-
- /* If .bss is present, check it for non-reserve bytecodes */
-
-
- yasm_xfree(info.buf);
-}
-
-static void
-bin_objfmt_cleanup(void)
-{
-}
-
-static /*@observer@*/ /*@null@*/ yasm_section *
-bin_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- yasm_valparam *vp;
- yasm_section *retval;
- int isnew;
- unsigned long start;
- char *sectname;
- int resonly = 0;
- unsigned long alignval = 0;
- int have_alignval = 0;
-
- if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
- /* If it's the first section output (.text) start at 0, otherwise
- * make sure the start is > 128.
- */
- sectname = vp->val;
- if (strcmp(sectname, ".text") == 0)
- start = 0;
- else if (strcmp(sectname, ".data") == 0)
- start = 200;
- else if (strcmp(sectname, ".bss") == 0) {
- start = 200;
- resonly = 1;
- } else {
- /* other section names not recognized. */
- yasm__error(lindex, N_("segment name `%s' not recognized"),
- sectname);
- return NULL;
- }
-
- /* Check for ALIGN qualifier */
- while ((vp = yasm_vps_next(vp))) {
- if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
- /*@dependent@*/ /*@null@*/ const yasm_intnum *align;
- unsigned long bitcnt;
-
- if (strcmp(sectname, ".text") == 0) {
- yasm__error(lindex,
- N_("cannot specify an alignment to the `%s' section"),
- sectname);
- return NULL;
- }
-
- align = yasm_expr_get_intnum(&vp->param, NULL);
- if (!align) {
- yasm__error(lindex,
- N_("argument to `%s' is not a power of two"),
- vp->val);
- return NULL;
- }
- alignval = yasm_intnum_get_uint(align);
-
- /* Check to see if alignval is a power of two.
- * This can be checked by seeing if only one bit is set.
- */
- BitCount(bitcnt, alignval);
- if (bitcnt > 1) {
- yasm__error(lindex,
- N_("argument to `%s' is not a power of two"),
- vp->val);
- return NULL;
- }
-
- have_alignval = 1;
- }
- }
-
- retval = yasm_sections_switch_general(headp, sectname, start, resonly,
- &isnew, lindex);
-
- if (isnew) {
- if (have_alignval) {
- unsigned long *data = yasm_xmalloc(sizeof(unsigned long));
- *data = alignval;
- yasm_section_set_of_data(retval, &yasm_bin_LTX_objfmt, data);
- }
-
- yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
- 1, lindex);
- } else if (have_alignval)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("alignment value ignored on section redeclaration"));
-
- return retval;
- } else
- return NULL;
-}
-
-static void
-bin_objfmt_section_data_delete(/*@only@*/ void *d)
-{
- yasm_xfree(d);
-}
-
-static void
-bin_objfmt_common_declare(/*@unused@*/ yasm_symrec *sym,
- /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- yasm_expr_delete(size);
- yasm__error(lindex,
- N_("binary object format does not support common variables"));
-}
-
-static int
-bin_objfmt_directive(const char *name, yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex)
-{
- yasm_section *sect;
- yasm_valparam *vp;
-
- if (yasm__strcasecmp(name, "org") == 0) {
- /*@dependent@*/ /*@null@*/ const yasm_intnum *start = NULL;
-
- /* ORG takes just a simple integer as param */
- vp = yasm_vps_first(valparams);
- if (vp->val) {
- yasm__error(lindex, N_("argument to ORG should be numeric"));
- return 0;
- } else if (vp->param)
- start = yasm_expr_get_intnum(&vp->param, NULL);
-
- if (!start) {
- yasm__error(lindex, N_("argument to ORG should be numeric"));
- return 0;
- }
-
- /* ORG changes the start of the .text section */
- sect = yasm_sections_find_general(headp, ".text");
- if (!sect)
- yasm_internal_error(
- N_("bin objfmt: .text section does not exist before ORG is called?"));
- yasm_section_set_start(sect, yasm_intnum_get_uint(start), lindex);
-
- return 0; /* directive recognized */
- } else
- return 1; /* directive unrecognized */
-}
-
-static void
-bin_objfmt_section_data_print(FILE *f, int indent_level, void *data)
-{
- fprintf(f, "%*salign=%ld\n", indent_level, "", *((unsigned long *)data));
-}
-
-
-/* Define valid debug formats to use with this object format */
-static const char *bin_objfmt_dbgfmt_keywords[] = {
- "null",
- NULL
-};
-
-/* Define objfmt structure -- see objfmt.h for details */
-yasm_objfmt yasm_bin_LTX_objfmt = {
- "Flat format binary",
- "bin",
- NULL,
- ".text",
- 16,
- bin_objfmt_dbgfmt_keywords,
- "null",
- bin_objfmt_initialize,
- bin_objfmt_output,
- bin_objfmt_cleanup,
- bin_objfmt_sections_switch,
- bin_objfmt_section_data_delete,
- bin_objfmt_section_data_print,
- NULL /*bin_objfmt_extern_declare*/,
- NULL /*bin_objfmt_global_declare*/,
- bin_objfmt_common_declare,
- NULL /*bin_objfmt_symrec_data_delete*/,
- NULL /*bin_objfmt_symrec_data_print*/,
- bin_objfmt_directive,
- NULL /*bin_objfmt_bc_objfmt_data_delete*/,
- NULL /*bin_objfmt_bc_objfmt_data_print*/
-};
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- src/objfmts/bin/tests/bin_test.sh
-
-EXTRA_DIST += \
- src/objfmts/bin/tests/bin_test.sh \
- src/objfmts/bin/tests/abs.asm \
- src/objfmts/bin/tests/abs.hex \
- src/objfmts/bin/tests/abs.errwarn \
- src/objfmts/bin/tests/bintest.asm \
- src/objfmts/bin/tests/bintest.hex \
- src/objfmts/bin/tests/bintest.errwarn \
- src/objfmts/bin/tests/float-err.asm \
- src/objfmts/bin/tests/float-err.errwarn \
- src/objfmts/bin/tests/float.asm \
- src/objfmts/bin/tests/float.hex \
- src/objfmts/bin/tests/float.errwarn \
- src/objfmts/bin/tests/integer-warn.asm \
- src/objfmts/bin/tests/integer-warn.hex \
- src/objfmts/bin/tests/integer-warn.errwarn \
- src/objfmts/bin/tests/integer.asm \
- src/objfmts/bin/tests/integer.hex \
- src/objfmts/bin/tests/integer.errwarn \
- src/objfmts/bin/tests/reserve.asm \
- src/objfmts/bin/tests/reserve.hex \
- src/objfmts/bin/tests/reserve.errwarn \
- src/objfmts/bin/tests/reserve-err.asm \
- src/objfmts/bin/tests/reserve-err.errwarn
+++ /dev/null
-[absolute 0f0000000h]
-foo: resb 1
-[section .data]
-bar dd foo
-baz db (foo>>24)
+++ /dev/null
-00
-00
-00
-f0
-f0
+++ /dev/null
-#! /bin/sh
-# $IdPath$
-${srcdir}/out_test.sh bin_test src/objfmts/bin/tests "bin objfmt" "-f bin" ""
-exit $?
+++ /dev/null
-; test source file for assembling to binary files
-; build with:
-; yasm -f bin -o bintest.com bintest.asm
-
-; When run (as a DOS .COM file), this program should print
-; hello, world
-; on two successive lines, then exit cleanly.
-
-; This file should test the following:
-; [1] Define a text-section symbol
-; [2] Define a data-section symbol
-; [3] Define a BSS-section symbol
-; [4] Define a NASM local label
-; [5] Reference a NASM local label
-; [6] Reference a text-section symbol in the text section
-; [7] Reference a data-section symbol in the text section
-; [8] Reference a BSS-section symbol in the text section
-; [9] Reference a text-section symbol in the data section
-; [10] Reference a data-section symbol in the data section
-; [11] Reference a BSS-section symbol in the data section
-
-[BITS 16]
-[ORG 0x100]
-
-[SECTION .text]
-
- jmp start ; [6]
-
-endX mov ax,0x4c00 ; [1]
- int 0x21
-
-start mov byte [bss_sym],',' ; [1] [8]
- mov bx,[bssptr] ; [7]
- mov al,[bx]
- mov bx,[dataptr] ; [7]
- mov [bx],al
- mov cx,2
-.loop mov dx,datasym ; [1] [4] [7]
- mov ah,9
- push cx
- int 0x21
- pop cx
- loop .loop ; [5] [6]
- mov bx,[textptr] ; [7]
- jmp bx
-
-[SECTION .data]
-
-datasym db 'hello world', 13, 10, '$' ; [2]
-bssptr dw bss_sym ; [2] [11]
-dataptr dw datasym+5 ; [2] [10]
-textptr dw endX ; [2] [9]
-
-[SECTION .bss]
-
-bss_sym resb 1 ; [3]
+++ /dev/null
-eb
-05
-b8
-00
-4c
-cd
-21
-c6
-06
-44
-01
-2c
-8b
-1e
-3b
-01
-8a
-07
-8b
-1e
-3d
-01
-88
-07
-b9
-02
-00
-ba
-2c
-01
-b4
-09
-51
-cd
-21
-59
-e2
-f5
-8b
-1e
-3f
-01
-ff
-e3
-68
-65
-6c
-6c
-6f
-20
-20
-77
-6f
-72
-6c
-64
-0d
-0a
-24
-44
-01
-31
-01
-02
-01
+++ /dev/null
-; Tests illegal float handling
-db 1.2
-dw 3.14
-dd 5.12e100000
-dq 3.141592653589793e-158105
-dt 5653894745.318293470142875104710284019245e-1999
-
-db -1.5
-dw -5593824513450897123075109385109385019324871093470134710984.34981
-dd -47102940.46710358135703124751034875109875103294510984019324
-dq -45102571092751092341095.5827509174509178450917845019e15555
-dt -1.e-100000
+++ /dev/null
--:2: invalid floating point constant size
--:3: invalid floating point constant size
--:4: overflow in floating point expression
--:5: underflow in floating point expression
--:8: invalid floating point constant size
--:9: invalid floating point constant size
--:11: overflow in floating point expression
--:12: underflow in floating point expression
+++ /dev/null
-; Tests float handling
-dd 5.12
-dq 3.141592653589793
-dt 5653894745.318293470142875104710284019245e335
-
-dd -47102940.467103581
-dq -45102571092751092341095.5827509174509178450917845019
-dt -1.e-1000
+++ /dev/null
-0a
-d7
-a3
-40
-18
-2d
-44
-54
-fb
-21
-09
-40
-75
-4e
-ef
-f1
-30
-25
-6e
-97
-78
-44
-f7
-ae
-33
-cc
-4d
-63
-8a
-d2
-07
-1a
-a3
-c4
-67
-14
-9e
-a8
-88
-91
-8a
-86
-05
-b3
+++ /dev/null
-; Tests warnings with integer constant handling (for output, not parsing)
-db 0x51a
-dw 0x3875bc
-dd 0x35783134affff
-dq 0xABCDEF012345678989abb
-dt 0xa907bc890d0e907f0134afb8adee
+++ /dev/null
--:5: warning: Numeric constant too large for internal format
--:6: warning: Numeric constant too large for internal format
+++ /dev/null
-1a
-bc
-75
-ff
-ff
-4a
-13
-bb
-9a
-98
-78
-56
-34
-12
-f0
-ee
-ad
-b8
-af
-34
-01
-7f
-90
-0e
-0d
+++ /dev/null
-; Tests integer constant handling (for output, not parsing)
-
-db 0x51
-dw 0x3875
-dd 0x35783134
-dq 0xABCDEF0123456789
-dt 0xa907bc890d0e907f0134
-
+++ /dev/null
-51
-75
-38
-34
-31
-78
-35
-89
-67
-45
-23
-01
-ef
-cd
-ab
-34
-01
-7f
-90
-0e
-0d
-89
-bc
-07
-a9
+++ /dev/null
-; Test res* family errors
-a:
-resb -5
-resw 1.2
-resd -1.2
-resq 0xffffffff
-rest a
-
-[section .bss]
-resb -5
-resw 1.2
-resd -1.2
-resq 0xffffffff
-rest a
-
+++ /dev/null
--:4: expression must not contain floating point value
--:5: expression must not contain floating point value
--:7: attempt to reserve non-constant quantity of space
--:11: expression must not contain floating point value
--:12: expression must not contain floating point value
--:14: attempt to reserve non-constant quantity of space
+++ /dev/null
-; Test res* family
-resb 5
-resw 10
-resd 50
-resq 1
-rest 0
-
-[section .bss]
-resb 1
-resw 5
-resd 10
-resq 40
-rest 4
-
+++ /dev/null
--:2: warning: uninitialized space declared in code/data section: zeroing
--:3: warning: uninitialized space declared in code/data section: zeroing
--:4: warning: uninitialized space declared in code/data section: zeroing
--:5: warning: uninitialized space declared in code/data section: zeroing
+++ /dev/null
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-coff.la
-
-yasm_coff_la_SOURCES = \
- src/objfmts/coff/coff-objfmt.c
-yasm_coff_la_LDFLAGS = -module -avoid-version
-yasm_coff_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-coff.la
-
-EXTRA_DIST += \
- src/objfmts/coff/tests/Makefile.inc
-
-include src/objfmts/coff/tests/Makefile.inc
+++ /dev/null
-/*
- * COFF (DJGPP) object format
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-
-#include "expr-int.h"
-#include "bc-int.h"
-
-#include "arch.h"
-#include "objfmt.h"
-
-
-#define REGULAR_OUTBUF_SIZE 1024
-
-/* Defining this to 0 sets all section VMA's to 0 rather than as the same as
- * the LMA. According to the DJGPP COFF Spec, this should be set to 1
- * (VMA=LMA), and indeed DJGPP's GCC output shows VMA=LMA. However, NASM
- * outputs VMA=0 (as if this was 0), and GNU objdump output looks a lot nicer
- * with VMA=0. Who's right? This is #defined as changing this setting affects
- * several places in the code.
- */
-#define COFF_SET_VMA 1
-
-#define COFF_I386MAGIC 0x14C
-
-#define COFF_F_LNNO 0x0004 /* line number info NOT present */
-#define COFF_F_LSYMS 0x0008 /* local symbols NOT present */
-#define COFF_F_AR32WR 0x0100 /* 32-bit little endian file */
-
-typedef STAILQ_HEAD(coff_reloc_head, coff_reloc) coff_reloc_head;
-
-typedef struct coff_reloc {
- STAILQ_ENTRY(coff_reloc) link; /* internal link, not in file */
- unsigned long addr; /* address of relocation */
- yasm_symrec *sym; /* relocated symbol */
- enum {
- COFF_RELOC_ADDR32 = 6, /* 32-bit absolute reference */
- COFF_RELOC_REL32 = 20 /* 32-bit relative reference */
- } type; /* type of relocation */
-} coff_reloc;
-
-typedef enum coff_section_data_flags {
- COFF_STYP_TEXT = 0x0020,
- COFF_STYP_DATA = 0x0040,
- COFF_STYP_BSS = 0x0080
-} coff_section_data_flags;
-
-typedef struct coff_section_data {
- /*@dependent@*/ yasm_symrec *sym; /* symbol created for this section */
- unsigned int scnum; /* section number (1=first section) */
- coff_section_data_flags flags;
- unsigned long addr; /* starting memory address (first section -> 0) */
- unsigned long scnptr; /* file ptr to raw data */
- unsigned long size; /* size of raw data (section data) in bytes */
- unsigned long relptr; /* file ptr to relocation */
- unsigned long nreloc; /* number of relocation entries >64k -> error */
- /*@owned@*/ coff_reloc_head relocs;
-} coff_section_data;
-
-typedef enum coff_symrec_sclass {
- COFF_SCL_EFCN = 0xff, /* physical end of function */
- COFF_SCL_NULL = 0,
- COFF_SCL_AUTO = 1, /* automatic variable */
- COFF_SCL_EXT = 2, /* external symbol */
- COFF_SCL_STAT = 3, /* static */
- COFF_SCL_REG = 4, /* register variable */
- COFF_SCL_EXTDEF = 5, /* external definition */
- COFF_SCL_LABEL = 6, /* label */
- COFF_SCL_ULABEL = 7, /* undefined label */
- COFF_SCL_MOS = 8, /* member of structure */
- COFF_SCL_ARG = 9, /* function argument */
- COFF_SCL_STRTAG = 10, /* structure tag */
- COFF_SCL_MOU = 11, /* member of union */
- COFF_SCL_UNTAG = 12, /* union tag */
- COFF_SCL_TPDEF = 13, /* type definition */
- COFF_SCL_USTATIC = 14, /* undefined static */
- COFF_SCL_ENTAG = 15, /* enumeration tag */
- COFF_SCL_MOE = 16, /* member of enumeration */
- COFF_SCL_REGPARM = 17, /* register parameter */
- COFF_SCL_FIELD = 18, /* bit field */
- COFF_SCL_AUTOARG = 19, /* auto argument */
- COFF_SCL_LASTENT = 20, /* dummy entry (end of block) */
- COFF_SCL_BLOCK = 100, /* ".bb" or ".eb" */
- COFF_SCL_FCN = 101, /* ".bf" or ".ef" */
- COFF_SCL_EOS = 102, /* end of structure */
- COFF_SCL_FILE = 103, /* file name */
- COFF_SCL_LINE = 104, /* line # reformatted as symbol table entry */
- COFF_SCL_ALIAS = 105, /* duplicate tag */
- COFF_SCL_HIDDEN = 106 /* ext symbol in dmert public lib */
-} coff_symrec_sclass;
-
-typedef struct coff_symrec_data {
- unsigned long index; /* assigned COFF symbol table index */
- coff_symrec_sclass sclass; /* storage class */
- /*@owned@*/ /*@null@*/ yasm_expr *size; /* size if COMMON declaration */
-} coff_symrec_data;
-
-typedef union coff_symtab_auxent {
- /* no data needed for section symbol auxent, all info avail from sym */
- /*@owned@*/ char *fname; /* filename aux entry */
-} coff_symtab_auxent;
-
-typedef enum coff_symtab_auxtype {
- COFF_SYMTAB_AUX_NONE = 0,
- COFF_SYMTAB_AUX_SECT,
- COFF_SYMTAB_AUX_FILE
-} coff_symtab_auxtype;
-
-typedef struct coff_symtab_entry {
- STAILQ_ENTRY(coff_symtab_entry) link;
- /*@dependent@*/ yasm_symrec *sym;
- int numaux; /* number of auxiliary entries */
- coff_symtab_auxtype auxtype; /* type of aux entries */
- coff_symtab_auxent aux[1]; /* actually may be any size (including 0) */
-} coff_symtab_entry;
-typedef STAILQ_HEAD(coff_symtab_head, coff_symtab_entry) coff_symtab_head;
-
-typedef struct coff_objfmt_output_info {
- /*@dependent@*/ FILE *f;
- /*@only@*/ unsigned char *buf;
- yasm_section *sect;
- /*@dependent@*/ coff_section_data *csd;
- unsigned long addr; /* start of next section */
-} coff_objfmt_output_info;
-
-static unsigned int coff_objfmt_parse_scnum; /* sect numbering in parser */
-static coff_symtab_head coff_symtab; /* symbol table of indexed syms */
-
-yasm_objfmt yasm_coff_LTX_objfmt;
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-
-static /*@dependent@*/ coff_symtab_entry *
-coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass,
- /*@only@*/ /*@null@*/ yasm_expr *size, int numaux,
- coff_symtab_auxtype auxtype)
-{
- /*@null@*/ /*@dependent@*/ coff_symrec_data *sym_data_prev;
- coff_symrec_data *sym_data;
- coff_symtab_entry *entry;
-
- if (STAILQ_EMPTY(&coff_symtab))
- yasm_internal_error(N_("empty COFF symbol table"));
- entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link);
- sym_data_prev = yasm_symrec_get_of_data(entry->sym);
- assert(sym_data_prev != NULL);
-
- sym_data = yasm_xmalloc(sizeof(coff_symrec_data));
- sym_data->index = sym_data_prev->index + entry->numaux + 1;
- sym_data->sclass = sclass;
- sym_data->size = size;
- yasm_symrec_set_of_data(sym, &yasm_coff_LTX_objfmt, sym_data);
-
- entry = yasm_xmalloc(sizeof(coff_symtab_entry) +
- (numaux-1)*sizeof(coff_symtab_auxent));
- entry->sym = sym;
- entry->numaux = numaux;
- entry->auxtype = auxtype;
- STAILQ_INSERT_TAIL(&coff_symtab, entry, link);
-
- return entry;
-}
-
-static void
-coff_objfmt_initialize(const char *in_filename,
- /*@unused@*/ const char *obj_filename,
- /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a)
-{
- yasm_symrec *filesym;
- coff_symrec_data *data;
- coff_symtab_entry *entry;
-
- cur_arch = a;
-
- coff_objfmt_parse_scnum = 1; /* section numbering starts at 1 */
- STAILQ_INIT(&coff_symtab);
-
- data = yasm_xmalloc(sizeof(coff_symrec_data));
- data->index = 0;
- data->sclass = COFF_SCL_FILE;
- data->size = NULL;
- filesym = yasm_symrec_define_label(".file", NULL, NULL, 0, 0);
- yasm_symrec_set_of_data(filesym, &yasm_coff_LTX_objfmt, data);
-
- entry = yasm_xmalloc(sizeof(coff_symtab_entry));
- entry->sym = filesym;
- entry->numaux = 1;
- entry->auxtype = COFF_SYMTAB_AUX_FILE;
- entry->aux[0].fname = yasm__xstrdup(in_filename);
- STAILQ_INSERT_TAIL(&coff_symtab, entry, link);
-}
-
-static int
-coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
-{
- /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
- /*@dependent@*/ /*@null@*/ coff_section_data *csd;
- /*@null@*/ yasm_bytecode *last;
-
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
- assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
- assert(csd != NULL);
-
- csd->addr = info->addr;
- last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
- if (last)
- info->addr += last->offset + last->len;
-
- return 0;
-}
-
-static int
-coff_objfmt_output_expr(yasm_expr **ep, unsigned char **bufp,
- unsigned long valsize, unsigned long offset,
- /*@observer@*/ const yasm_section *sect,
- /*@observer@*/ const yasm_bytecode *bc, int rel,
- /*@unused@*/ /*@null@*/ void *d)
-{
- /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
- /*@dependent@*/ /*@null@*/ const yasm_floatnum *flt;
- /*@dependent@*/ /*@null@*/ yasm_symrec *sym;
- /*@dependent@*/ yasm_section *label_sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *label_precbc;
-
- assert(info != NULL);
-
- *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
-
- /* Handle floating point expressions */
- flt = yasm_expr_get_floatnum(ep);
- if (flt)
- return cur_arch->floatnum_tobytes(flt, bufp, valsize, *ep);
-
- /* Handle integer expressions, with relocation if necessary */
- sym = yasm_expr_extract_symrec(ep, yasm_common_calc_bc_dist);
- if (sym) {
- coff_reloc *reloc;
- yasm_sym_vis vis;
-
- if (valsize != 4) {
- yasm__error((*ep)->line, N_("coff: invalid relocation size"));
- return 1;
- }
-
- reloc = yasm_xmalloc(sizeof(coff_reloc));
- reloc->addr = bc->offset + offset;
- if (COFF_SET_VMA)
- reloc->addr += info->addr;
- reloc->sym = sym;
- vis = yasm_symrec_get_visibility(sym);
- if (vis & YASM_SYM_COMMON) {
- /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
-
- /* COMMON symbols have their length added in */
- csymd = yasm_symrec_get_of_data(sym);
- assert(csymd != NULL);
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_expr(yasm_expr_copy(csymd->size)),
- csymd->size->line);
- *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
- } else if (!(vis & YASM_SYM_EXTERN)) {
- /* Local symbols need relocation to their section's start */
- if (yasm_symrec_get_label(sym, &label_sect, &label_precbc)) {
- /*@null@*/ coff_section_data *label_csd;
- label_csd = yasm_section_get_of_data(label_sect);
- assert(label_csd != NULL);
- reloc->sym = label_csd->sym;
- if (COFF_SET_VMA)
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_int(yasm_intnum_new_uint(label_csd->addr)),
- (*ep)->line);
- }
- }
-
- if (rel) {
- reloc->type = COFF_RELOC_REL32;
- /* Need to reference to start of section, so add $$ in. */
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_sym(yasm_symrec_define_label("$$", info->sect, NULL,
- 0, (*ep)->line)),
- (*ep)->line);
- *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
- } else
- reloc->type = COFF_RELOC_ADDR32;
- info->csd->nreloc++;
- STAILQ_INSERT_TAIL(&info->csd->relocs, reloc, link);
- }
- intn = yasm_expr_get_intnum(ep, NULL);
- if (intn)
- return cur_arch->intnum_tobytes(intn, bufp, valsize, *ep, bc, rel);
-
- /* Check for complex float expressions */
- if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
- yasm__error((*ep)->line, N_("floating point expression too complex"));
- return 1;
- }
-
- yasm__error((*ep)->line, N_("coff: relocation too complex"));
- return 1;
-}
-
-static int
-coff_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
-{
- /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
- /*@null@*/ /*@only@*/ unsigned char *bigbuf;
- unsigned long size = REGULAR_OUTBUF_SIZE;
- unsigned long multiple;
- unsigned long i;
- int gap;
-
- assert(info != NULL);
-
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
- info, coff_objfmt_output_expr, NULL);
-
- /* Don't bother doing anything else if size ended up being 0. */
- if (size == 0) {
- if (bigbuf)
- yasm_xfree(bigbuf);
- return 0;
- }
-
- info->csd->size += size;
-
- /* Warn that gaps are converted to 0 and write out the 0's. */
- if (gap) {
- unsigned long left;
- yasm__warning(YASM_WARN_GENERAL, bc->line,
- N_("uninitialized space declared in code/data section: zeroing"));
- /* Write out in chunks */
- memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
- left = multiple*size;
- while (left > REGULAR_OUTBUF_SIZE) {
- fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
- left -= REGULAR_OUTBUF_SIZE;
- }
- fwrite(info->buf, left, 1, info->f);
- } else {
- /* Output multiple copies of buf (or bigbuf if non-NULL) to file */
- for (i=0; i<multiple; i++)
- fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
- }
-
- /* If bigbuf was allocated, free it */
- if (bigbuf)
- yasm_xfree(bigbuf);
-
- return 0;
-}
-
-static int
-coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
-{
- /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
- /*@dependent@*/ /*@null@*/ coff_section_data *csd;
- long pos;
- coff_reloc *reloc;
-
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
- assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
- assert(csd != NULL);
-
- csd->addr = info->addr;
-
- if (csd->flags == COFF_STYP_BSS) {
- /*@null@*/ yasm_bytecode *last =
- yasm_bcs_last(yasm_section_get_bytecodes(sect));
-
- /* Don't output BSS sections.
- * TODO: Check for non-reserve bytecodes?
- */
- pos = 0; /* position = 0 because it's not in the file */
- if (last)
- csd->size = last->offset + last->len;
- } else {
- pos = ftell(info->f);
- if (pos == -1) {
- yasm__error(0, N_("could not get file position on output file"));
- return 1;
- }
-
- info->sect = sect;
- info->csd = csd;
- yasm_bcs_traverse(yasm_section_get_bytecodes(sect), info,
- coff_objfmt_output_bytecode);
- }
-
- /* Empty? Go on to next section */
- if (csd->size == 0)
- return 0;
-
- info->addr += csd->size;
- csd->scnptr = (unsigned long)pos;
-
- /* No relocations to output? Go on to next section */
- if (csd->nreloc == 0)
- return 0;
-
- pos = ftell(info->f);
- if (pos == -1) {
- yasm__error(0, N_("could not get file position on output file"));
- return 1;
- }
- csd->relptr = (unsigned long)pos;
-
- STAILQ_FOREACH(reloc, &csd->relocs, link) {
- unsigned char *localbuf = info->buf;
- /*@null@*/ coff_symrec_data *csymd;
-
- csymd = yasm_symrec_get_of_data(reloc->sym);
- if (!csymd)
- yasm_internal_error(
- N_("coff: no symbol data for relocated symbol"));
-
- YASM_WRITE_32_L(localbuf, reloc->addr); /* address of relocation */
- YASM_WRITE_32_L(localbuf, csymd->index); /* relocated symbol */
- YASM_WRITE_16_L(localbuf, reloc->type); /* type of relocation */
- fwrite(info->buf, 10, 1, info->f);
- }
-
- return 0;
-}
-
-static int
-coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
-{
- /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
- /*@dependent@*/ /*@null@*/ coff_section_data *csd;
- unsigned char *localbuf;
-
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
- assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
- assert(csd != NULL);
-
- localbuf = info->buf;
- strncpy((char *)localbuf, yasm_section_get_name(sect), 8);/* section name */
- localbuf += 8;
- YASM_WRITE_32_L(localbuf, csd->addr); /* physical address */
- if (COFF_SET_VMA)
- YASM_WRITE_32_L(localbuf, csd->addr); /* virtual address */
- else
- YASM_WRITE_32_L(localbuf, 0); /* virtual address */
- YASM_WRITE_32_L(localbuf, csd->size); /* section size */
- YASM_WRITE_32_L(localbuf, csd->scnptr); /* file ptr to data */
- YASM_WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */
- YASM_WRITE_32_L(localbuf, 0); /* file ptr to line nums */
- if (csd->nreloc >= 64*1024) {
- yasm__warning(YASM_WARN_GENERAL, 0,
- N_("too many relocations in section `%s'"),
- yasm_section_get_name(sect));
- YASM_WRITE_16_L(localbuf, 0xFFFF); /* max out */
- } else
- YASM_WRITE_16_L(localbuf, csd->nreloc); /* num of relocation entries */
- YASM_WRITE_16_L(localbuf, 0); /* num of line number entries */
- YASM_WRITE_32_L(localbuf, csd->flags); /* flags */
- fwrite(info->buf, 40, 1, info->f);
-
- return 0;
-}
-
-static void
-coff_objfmt_output(FILE *f, yasm_sectionhead *sections)
-{
- coff_objfmt_output_info info;
- unsigned char *localbuf;
- long pos;
- unsigned long symtab_pos;
- unsigned long symtab_count = 0;
- unsigned long strtab_offset = 4;
- coff_symtab_entry *entry;
-
- info.f = f;
- info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
-
- /* Allocate space for headers by seeking forward */
- if (fseek(f, 20+40*(coff_objfmt_parse_scnum-1), SEEK_SET) < 0) {
- yasm__error(0, N_("could not seek on output file"));
- return;
- }
-
- /* Section data/relocs */
- if (COFF_SET_VMA) {
- /* If we're setting the VMA, we need to do a first section pass to
- * determine each section's addr value before actually outputting
- * relocations, as a relocation's section address is added into the
- * addends in the generated code.
- */
- info.addr = 0;
- if (yasm_sections_traverse(sections, &info,
- coff_objfmt_set_section_addr))
- return;
- }
- info.addr = 0;
- if (yasm_sections_traverse(sections, &info, coff_objfmt_output_section))
- return;
-
- /* Symbol table */
- pos = ftell(f);
- if (pos == -1) {
- yasm__error(0, N_("could not get file position on output file"));
- return;
- }
- symtab_pos = (unsigned long)pos;
- STAILQ_FOREACH(entry, &coff_symtab, link) {
- const char *name = yasm_symrec_get_name(entry->sym);
- size_t len = strlen(name);
- int aux;
- /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
- unsigned long value = 0;
- unsigned int scnum = 0xfffe; /* -2 = debugging symbol */
- /*@dependent@*/ /*@null@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
- unsigned long scnlen = 0; /* for sect auxent */
- unsigned long nreloc = 0; /* for sect auxent */
-
- /* Get symrec's of_data (needed for storage class) */
- csymd = yasm_symrec_get_of_data(entry->sym);
- if (!csymd)
- yasm_internal_error(N_("coff: expected sym data to be present"));
-
- /* Look at symrec for value/scnum/etc. */
- if (yasm_symrec_get_label(entry->sym, §, &precbc)) {
- /* it's a label: get value and offset.
- * If there is not a section, leave as debugging symbol.
- */
- if (sect) {
- /*@dependent@*/ /*@null@*/ coff_section_data *csectd;
- csectd = yasm_section_get_of_data(sect);
- scnum = csectd->scnum;
- scnlen = csectd->size;
- nreloc = csectd->nreloc;
- if (precbc)
- value = precbc->offset + precbc->len;
- if (COFF_SET_VMA)
- value += csectd->addr;
- }
- } else {
- yasm_sym_vis vis = yasm_symrec_get_visibility(entry->sym);
- if (vis & YASM_SYM_COMMON) {
- const yasm_intnum *intn;
- intn = yasm_expr_get_intnum(&csymd->size,
- yasm_common_calc_bc_dist);
- if (!intn)
- yasm__error(csymd->size->line,
- N_("COMMON data size not an integer expression"));
- else
- value = yasm_intnum_get_uint(intn);
- scnum = 0;
- }
- if (vis & YASM_SYM_EXTERN)
- scnum = 0;
- }
-
- localbuf = info.buf;
- if (len > 8) {
- YASM_WRITE_32_L(localbuf, 0); /* "zeros" field */
- YASM_WRITE_32_L(localbuf, strtab_offset); /* string table offset */
- strtab_offset += len+1;
- } else {
- /* <8 chars, so no string table entry needed */
- strncpy((char *)localbuf, name, 8);
- localbuf += 8;
- }
- YASM_WRITE_32_L(localbuf, value); /* value */
- YASM_WRITE_16_L(localbuf, scnum); /* section number */
- YASM_WRITE_16_L(localbuf, 0); /* type is always zero (for now) */
- YASM_WRITE_8(localbuf, csymd->sclass); /* storage class */
- YASM_WRITE_8(localbuf, entry->numaux); /* number of aux entries */
- fwrite(info.buf, 18, 1, f);
- for (aux=0; aux<entry->numaux; aux++) {
- localbuf = info.buf;
- memset(localbuf, 0, 18);
- switch (entry->auxtype) {
- case COFF_SYMTAB_AUX_NONE:
- break;
- case COFF_SYMTAB_AUX_SECT:
- YASM_WRITE_32_L(localbuf, scnlen); /* section length */
- YASM_WRITE_16_L(localbuf, nreloc); /* number relocs */
- YASM_WRITE_16_L(localbuf, 0); /* number line nums */
- break;
- case COFF_SYMTAB_AUX_FILE:
- len = strlen(entry->aux[0].fname);
- if (len > 14) {
- YASM_WRITE_32_L(localbuf, 0);
- YASM_WRITE_32_L(localbuf, strtab_offset);
- strtab_offset += len+1;
- } else
- strncpy((char *)localbuf, entry->aux[0].fname, 14);
- break;
- default:
- yasm_internal_error(
- N_("coff: unrecognized aux symtab type"));
- }
- fwrite(info.buf, 18, 1, f);
- symtab_count++;
- }
- symtab_count++;
- }
-
- /* String table */
- yasm_fwrite_32_l(strtab_offset, f); /* first four bytes are total length */
- STAILQ_FOREACH(entry, &coff_symtab, link) {
- const char *name = yasm_symrec_get_name(entry->sym);
- size_t len = strlen(name);
- int aux;
-
- if (len > 8)
- fwrite(name, len+1, 1, f);
- for (aux=0; aux<entry->numaux; aux++) {
- switch (entry->auxtype) {
- case COFF_SYMTAB_AUX_FILE:
- len = strlen(entry->aux[0].fname);
- if (len > 14)
- fwrite(entry->aux[0].fname, len+1, 1, f);
- break;
- default:
- break;
- }
- }
- }
-
- /* Write headers */
- if (fseek(f, 0, SEEK_SET) < 0) {
- yasm__error(0, N_("could not seek on output file"));
- return;
- }
-
- localbuf = info.buf;
- YASM_WRITE_16_L(localbuf, COFF_I386MAGIC); /* magic number */
- YASM_WRITE_16_L(localbuf, coff_objfmt_parse_scnum-1);/* number of sects */
- YASM_WRITE_32_L(localbuf, 0); /* time/date stamp */
- YASM_WRITE_32_L(localbuf, symtab_pos); /* file ptr to symtab */
- YASM_WRITE_32_L(localbuf, symtab_count); /* number of symtabs */
- YASM_WRITE_16_L(localbuf, 0); /* size of optional header (none) */
- YASM_WRITE_16_L(localbuf, COFF_F_AR32WR|COFF_F_LNNO|COFF_F_LSYMS); /* flags */
- fwrite(info.buf, 20, 1, f);
-
- yasm_sections_traverse(sections, &info, coff_objfmt_output_secthead);
-
- yasm_xfree(info.buf);
-}
-
-static void
-coff_objfmt_cleanup(void)
-{
- coff_symtab_entry *entry1, *entry2;
-
- /* Delete local symbol table */
- entry1 = STAILQ_FIRST(&coff_symtab);
- while (entry1 != NULL) {
- entry2 = STAILQ_NEXT(entry1, link);
- if (entry1->numaux == 1 && entry1->auxtype == COFF_SYMTAB_AUX_FILE)
- yasm_xfree(entry1->aux[0].fname);
- yasm_xfree(entry1);
- entry1 = entry2;
- }
-}
-
-static /*@observer@*/ /*@null@*/ yasm_section *
-coff_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- yasm_valparam *vp = yasm_vps_first(valparams);
- yasm_section *retval;
- int isnew;
- coff_section_data_flags flags;
- int flags_override = 0;
- char *sectname;
- int resonly = 0;
-
- if (!vp || vp->param || !vp->val)
- return NULL;
-
- sectname = vp->val;
- if (strlen(sectname) > 8) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("COFF section names limited to 8 characters: truncating"));
- sectname[8] = '\0';
- }
-
- if (strcmp(sectname, ".data") == 0)
- flags = COFF_STYP_DATA;
- else if (strcmp(sectname, ".bss") == 0) {
- flags = COFF_STYP_BSS;
- resonly = 1;
- } else
- flags = COFF_STYP_TEXT;
-
- while ((vp = yasm_vps_next(vp))) {
- if (yasm__strcasecmp(vp->val, "code") == 0 ||
- yasm__strcasecmp(vp->val, "text") == 0) {
- flags = COFF_STYP_TEXT;
- flags_override = 1;
- } else if (yasm__strcasecmp(vp->val, "data") == 0) {
- flags = COFF_STYP_DATA;
- flags_override = 1;
- } else if (yasm__strcasecmp(vp->val, "bss") == 0) {
- flags = COFF_STYP_BSS;
- flags_override = 1;
- resonly = 1;
- }
- }
-
- retval = yasm_sections_switch_general(headp, sectname, 0, resonly, &isnew,
- lindex);
-
- if (isnew) {
- coff_section_data *data;
- yasm_symrec *sym;
-
- data = yasm_xmalloc(sizeof(coff_section_data));
- data->scnum = coff_objfmt_parse_scnum++;
- data->flags = flags;
- data->addr = 0;
- data->scnptr = 0;
- data->size = 0;
- data->relptr = 0;
- data->nreloc = 0;
- STAILQ_INIT(&data->relocs);
- yasm_section_set_of_data(retval, &yasm_coff_LTX_objfmt, data);
-
- sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
- 1, lindex);
- coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1,
- COFF_SYMTAB_AUX_SECT);
- data->sym = sym;
- } else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, lindex,
- N_("section flags ignored on section redeclaration"));
- return retval;
-}
-
-static void
-coff_objfmt_section_data_delete(/*@only@*/ void *data)
-{
- coff_section_data *csd = (coff_section_data *)data;
- coff_reloc *r1, *r2;
- r1 = STAILQ_FIRST(&csd->relocs);
- while (r1 != NULL) {
- r2 = STAILQ_NEXT(r1, link);
- yasm_xfree(r1);
- r1 = r2;
- }
- yasm_xfree(data);
-}
-
-static void
-coff_objfmt_section_data_print(FILE *f, int indent_level, void *data)
-{
- coff_section_data *csd = (coff_section_data *)data;
- coff_reloc *reloc;
- unsigned long relocnum = 0;
-
- fprintf(f, "%*ssym=\n", indent_level, "");
- yasm_symrec_print(f, indent_level+1, csd->sym);
- fprintf(f, "%*sscnum=%d\n", indent_level, "", csd->scnum);
- fprintf(f, "%*sflags=", indent_level, "");
- switch (csd->flags) {
- case COFF_STYP_TEXT:
- fprintf(f, "TEXT");
- break;
- case COFF_STYP_DATA:
- fprintf(f, "DATA");
- break;
- case COFF_STYP_BSS:
- fprintf(f, "BSS");
- break;
- default:
- fprintf(f, "UNKNOWN");
- break;
- }
- fprintf(f, "\n%*saddr=0x%lx\n", indent_level, "", csd->addr);
- fprintf(f, "%*sscnptr=0x%lx\n", indent_level, "", csd->scnptr);
- fprintf(f, "%*ssize=%ld\n", indent_level, "", csd->size);
- fprintf(f, "%*srelptr=0x%lx\n", indent_level, "", csd->relptr);
- fprintf(f, "%*snreloc=%ld\n", indent_level, "", csd->nreloc);
- fprintf(f, "%*srelocs:\n", indent_level, "");
- STAILQ_FOREACH(reloc, &csd->relocs, link) {
- fprintf(f, "%*sReloc %lu:\n", indent_level+1, "", relocnum++);
- fprintf(f, "%*ssym=\n", indent_level+2, "");
- yasm_symrec_print(f, indent_level+3, reloc->sym);
- fprintf(f, "%*stype=", indent_level+2, "");
- switch (reloc->type) {
- case COFF_RELOC_ADDR32:
- printf("Addr32\n");
- break;
- case COFF_RELOC_REL32:
- printf("Rel32\n");
- break;
- }
- }
-}
-
-static void
-coff_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/
- /*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
-{
- coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0,
- COFF_SYMTAB_AUX_NONE);
-}
-
-static void
-coff_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
-{
- coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0,
- COFF_SYMTAB_AUX_NONE);
-}
-
-static void
-coff_objfmt_symrec_data_delete(/*@only@*/ void *data)
-{
- coff_symrec_data *csymd = (coff_symrec_data *)data;
- if (csymd->size)
- yasm_expr_delete(csymd->size);
- yasm_xfree(data);
-}
-
-static void
-coff_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
-{
- coff_symrec_data *csd = (coff_symrec_data *)data;
-
- fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", csd->index);
- fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass);
- fprintf(f, "%*ssize=", indent_level, "");
- if (csd->size)
- yasm_expr_print(f, csd->size);
- else
- fprintf(f, "nil");
- fprintf(f, "\n");
-}
-
-static int
-coff_objfmt_directive(/*@unused@*/ const char *name,
- /*@unused@*/ yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- /*@unused@*/ unsigned long lindex)
-{
- return 1; /* no objfmt directives */
-}
-
-
-/* Define valid debug formats to use with this object format */
-static const char *coff_objfmt_dbgfmt_keywords[] = {
- "null",
- NULL
-};
-
-/* Define objfmt structure -- see objfmt.h for details */
-yasm_objfmt yasm_coff_LTX_objfmt = {
- "COFF (DJGPP)",
- "coff",
- "o",
- ".text",
- 32,
- coff_objfmt_dbgfmt_keywords,
- "null",
- coff_objfmt_initialize,
- coff_objfmt_output,
- coff_objfmt_cleanup,
- coff_objfmt_sections_switch,
- coff_objfmt_section_data_delete,
- coff_objfmt_section_data_print,
- coff_objfmt_extglob_declare,
- coff_objfmt_extglob_declare,
- coff_objfmt_common_declare,
- coff_objfmt_symrec_data_delete,
- coff_objfmt_symrec_data_print,
- coff_objfmt_directive,
- NULL /*coff_objfmt_bc_objfmt_data_delete*/,
- NULL /*coff_objfmt_bc_objfmt_data_print*/
-};
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- src/objfmts/coff/tests/coff_test.sh
-
-EXTRA_DIST += \
- src/objfmts/coff/tests/coff_test.sh \
- src/objfmts/coff/tests/cofftest.c \
- src/objfmts/coff/tests/cofftest.asm \
- src/objfmts/coff/tests/cofftest.hex \
- src/objfmts/coff/tests/cofftest.errwarn
+++ /dev/null
-#! /bin/sh
-# $IdPath$
-${srcdir}/out_test.sh coff_test src/objfmts/coff/tests "coff objfmt" "-f coff" ".o"
-exit $?
+++ /dev/null
-; test source file for assembling to COFF
-; build with (under DJGPP, for example):
-; yasm -f coff cofftest.asm
-; gcc -o cofftest cofftest.c cofftest.o
-
-; This file should test the following:
-; [1] Define and export a global text-section symbol
-; [2] Define and export a global data-section symbol
-; [3] Define and export a global BSS-section symbol
-; [4] Define a non-global text-section symbol
-; [5] Define a non-global data-section symbol
-; [6] Define a non-global BSS-section symbol
-; [7] Define a COMMON symbol
-; [8] Define a NASM local label
-; [9] Reference a NASM local label
-; [10] Import an external symbol
-; [11] Make a PC-relative call to an external symbol
-; [12] Reference a text-section symbol in the text section
-; [13] Reference a data-section symbol in the text section
-; [14] Reference a BSS-section symbol in the text section
-; [15] Reference a text-section symbol in the data section
-; [16] Reference a data-section symbol in the data section
-; [17] Reference a BSS-section symbol in the data section
-
-[BITS 32]
-[GLOBAL _lrotate] ; [1]
-[GLOBAL _greet] ; [1]
-[GLOBAL _asmstr] ; [2]
-[GLOBAL _textptr] ; [2]
-[GLOBAL _selfptr] ; [2]
-[GLOBAL _integer] ; [3]
-[EXTERN _printf] ; [10]
-[COMMON _commvar 4] ; [7]
-
-[SECTION .text]
-
-; prototype: long lrotate(long x, int num);
-_lrotate: ; [1]
- push ebp
- mov ebp,esp
- mov eax,[ebp+8]
- mov ecx,[ebp+12]
-.label rol eax,1 ; [4] [8]
- loop .label ; [9] [12]
- mov esp,ebp
- pop ebp
- ret
-
-; prototype: void greet(void);
-_greet mov eax,[_integer] ; [14]
- inc eax
- mov [localint],eax ; [14]
- push dword [_commvar]
- mov eax,[localptr] ; [13]
- push dword [eax]
- push dword [_integer] ; [1] [14]
- push dword _printfstr ; [13]
- call _printf ; [11]
- add esp,16
- ret
-
-[SECTION .data]
-
-; a string
-_asmstr db 'hello, world', 0 ; [2]
-
-; a string for Printf
-_printfstr db "integer==%d, localint==%d, commvar=%d"
- db 10, 0
-
-; some pointers
-localptr dd localint ; [5] [17]
-_textptr dd _greet ; [15]
-_selfptr dd _selfptr ; [16]
-
-[SECTION .bss]
-
-; an integer
-_integer resd 1 ; [3]
-
-; a local integer
-localint resd 1 ; [6]
+++ /dev/null
-/*
- * test source file for assembling to COFF
- * build with (under DJGPP, for example):
- * yasm -f coff cofftest.asm
- * gcc -o cofftest cofftest.c cofftest.o
- */
-
-#include <stdio.h>
-
-extern int lrotate(long, int);
-extern void greet(void);
-extern char asmstr[];
-extern void *selfptr;
-extern void *textptr;
-extern int integer, commvar;
-
-int main(void) {
-
- printf("Testing lrotate: should get 0x00400000, 0x00000001\n");
- printf("lrotate(0x00040000, 4) = 0x%08lx\n", lrotate(0x40000,4));
- printf("lrotate(0x00040000, 14) = 0x%08lx\n", lrotate(0x40000,14));
-
- printf("This string should read `hello, world': `%s'\n", asmstr);
-
- printf("The integers here should be 1234, 1235 and 4321:\n");
- integer = 1234;
- commvar = 4321;
- greet();
-
- printf("These pointers should be equal: %p and %p\n",
- &greet, textptr);
-
- printf("So should these: %p and %p\n", selfptr, &selfptr);
-}
+++ /dev/null
-4c
-01
-03
-00
-00
-00
-00
-00
-70
-01
-00
-00
-10
-00
-00
-00
-00
-00
-0c
-01
-2e
-74
-65
-78
-74
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-40
-00
-00
-00
-8c
-00
-00
-00
-cc
-00
-00
-00
-00
-00
-00
-00
-07
-00
-00
-00
-20
-00
-00
-00
-2e
-64
-61
-74
-61
-00
-00
-00
-40
-00
-00
-00
-40
-00
-00
-00
-40
-00
-00
-00
-12
-01
-00
-00
-52
-01
-00
-00
-00
-00
-00
-00
-03
-00
-00
-00
-40
-00
-00
-00
-2e
-62
-73
-73
-00
-00
-00
-00
-80
-00
-00
-00
-80
-00
-00
-00
-08
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-80
-00
-00
-00
-55
-89
-e5
-8b
-45
-08
-8b
-4d
-0c
-d1
-c0
-e2
-fc
-89
-ec
-5d
-c3
-a1
-80
-00
-00
-00
-40
-a3
-84
-00
-00
-00
-ff
-35
-04
-00
-00
-00
-a1
-74
-00
-00
-00
-ff
-30
-ff
-35
-80
-00
-00
-00
-68
-4d
-00
-00
-00
-e8
-c7
-ff
-ff
-ff
-81
-c4
-10
-00
-00
-00
-c3
-12
-00
-00
-00
-0e
-00
-00
-00
-06
-00
-18
-00
-00
-00
-0e
-00
-00
-00
-06
-00
-1e
-00
-00
-00
-0b
-00
-00
-00
-06
-00
-23
-00
-00
-00
-0c
-00
-00
-00
-06
-00
-2b
-00
-00
-00
-0e
-00
-00
-00
-06
-00
-30
-00
-00
-00
-0c
-00
-00
-00
-06
-00
-35
-00
-00
-00
-0a
-00
-00
-00
-14
-00
-68
-65
-6c
-6c
-6f
-2c
-20
-77
-6f
-72
-6c
-64
-00
-69
-6e
-74
-65
-67
-65
-72
-3d
-3d
-25
-64
-2c
-20
-6c
-6f
-63
-61
-6c
-69
-6e
-74
-3d
-3d
-25
-64
-2c
-20
-63
-6f
-6d
-6d
-76
-61
-72
-3d
-25
-64
-0a
-00
-84
-00
-00
-00
-11
-00
-00
-00
-7c
-00
-00
-00
-74
-00
-00
-00
-0e
-00
-00
-00
-06
-00
-78
-00
-00
-00
-02
-00
-00
-00
-06
-00
-7c
-00
-00
-00
-0c
-00
-00
-00
-06
-00
-2e
-66
-69
-6c
-65
-00
-00
-00
-00
-00
-00
-00
-fe
-ff
-00
-00
-67
-01
-2d
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-2e
-74
-65
-78
-74
-00
-00
-00
-00
-00
-00
-00
-01
-00
-00
-00
-03
-01
-40
-00
-00
-00
-07
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-5f
-6c
-72
-6f
-74
-61
-74
-65
-00
-00
-00
-00
-01
-00
-00
-00
-02
-00
-5f
-67
-72
-65
-65
-74
-00
-00
-11
-00
-00
-00
-01
-00
-00
-00
-02
-00
-5f
-61
-73
-6d
-73
-74
-72
-00
-40
-00
-00
-00
-02
-00
-00
-00
-02
-00
-5f
-74
-65
-78
-74
-70
-74
-72
-78
-00
-00
-00
-02
-00
-00
-00
-02
-00
-5f
-73
-65
-6c
-66
-70
-74
-72
-7c
-00
-00
-00
-02
-00
-00
-00
-02
-00
-5f
-69
-6e
-74
-65
-67
-65
-72
-80
-00
-00
-00
-03
-00
-00
-00
-02
-00
-5f
-70
-72
-69
-6e
-74
-66
-00
-00
-00
-00
-00
-00
-00
-00
-00
-02
-00
-5f
-63
-6f
-6d
-6d
-76
-61
-72
-04
-00
-00
-00
-00
-00
-00
-00
-02
-00
-2e
-64
-61
-74
-61
-00
-00
-00
-40
-00
-00
-00
-02
-00
-00
-00
-03
-01
-40
-00
-00
-00
-03
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-2e
-62
-73
-73
-00
-00
-00
-00
-80
-00
-00
-00
-03
-00
-00
-00
-03
-01
-08
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-00
-04
-00
-00
-00
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-dbg.la
-
-yasm_dbg_la_SOURCES = \
- src/objfmts/dbg/dbg-objfmt.c
-yasm_dbg_la_LDFLAGS = -module -avoid-version
-yasm_dbg_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-dbg.la
+++ /dev/null
-/*
- * Debugging object format (used to debug object format module interface)
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "arch.h"
-#include "section.h"
-#include "objfmt.h"
-#include "dbgfmt.h"
-
-
-yasm_objfmt yasm_dbg_LTX_objfmt;
-
-/* Output file for debugging-type formats. This is so that functions that are
- * called before the object file is usually opened can still write data out to
- * it (whereas for "normal" formats the object file is not opened until later
- * in the assembly process). Opening the file early is done in initialize().
- *
- * Note that the functions here write to dbg_objfmt_file. This is NOT legal
- * for other object formats to do--only the output() function can write to a
- * file, and only the file it's passed in its f parameter!
- */
-static FILE *dbg_objfmt_file;
-
-
-static void
-dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a)
-{
- dbg_objfmt_file = fopen(obj_filename, "wt");
- if (!dbg_objfmt_file) {
- fprintf(stderr, N_("could not open file `%s'"), obj_filename);
- return;
- }
- fprintf(dbg_objfmt_file,
- "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch)\n",
- in_filename, obj_filename, df->keyword, a->keyword);
-}
-
-static void
-dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_sectionhead *sections)
-{
- fprintf(dbg_objfmt_file, "output(f, sections->\n");
- yasm_sections_print(dbg_objfmt_file, 1, sections);
- fprintf(dbg_objfmt_file, ")\n");
- fprintf(dbg_objfmt_file, " Symbol Table:\n");
- yasm_symrec_print_all(dbg_objfmt_file, 1);
-}
-
-static void
-dbg_objfmt_cleanup(void)
-{
- fprintf(dbg_objfmt_file, "cleanup()\n");
-}
-
-static /*@observer@*/ /*@null@*/ yasm_section *
-dbg_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- yasm_valparam *vp;
- yasm_section *retval;
- int isnew;
-
- fprintf(dbg_objfmt_file, "sections_switch(headp, ");
- yasm_vps_print(dbg_objfmt_file, valparams);
- fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), returning ", lindex);
-
- if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
- retval = yasm_sections_switch_general(headp, vp->val, 200, 0, &isnew,
- lindex);
- if (isnew) {
- fprintf(dbg_objfmt_file, "(new) ");
- yasm_symrec_define_label(vp->val, retval, (yasm_bytecode *)NULL, 1,
- lindex);
- }
- fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val);
- return retval;
- } else {
- fprintf(dbg_objfmt_file, "NULL\n");
- return NULL;
- }
-}
-
-static void
-dbg_objfmt_section_data_delete(/*@only@*/ void *data)
-{
- fprintf(dbg_objfmt_file, "section_data_delete(%p)\n", data);
- yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_section_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
-{
- if (data)
- fprintf(f, "%*s%p\n", indent_level, "", data);
- else
- fprintf(f, "%*s(none)\n", indent_level, "");
-}
-
-static void
-dbg_objfmt_extern_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ",
- yasm_symrec_get_name(sym));
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
-}
-
-static void
-dbg_objfmt_global_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- fprintf(dbg_objfmt_file, "global_declare(\"%s\", ",
- yasm_symrec_get_name(sym));
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
-}
-
-static void
-dbg_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
-{
- assert(dbg_objfmt_file != NULL);
- fprintf(dbg_objfmt_file, "common_declare(\"%s\", ",
- yasm_symrec_get_name(sym));
- yasm_expr_print(dbg_objfmt_file, size);
- fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=", lindex);
- yasm_expr_print(dbg_objfmt_file, size);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, size);
- fprintf(dbg_objfmt_file, "\n");
-}
-
-static void
-dbg_objfmt_symrec_data_delete(/*@only@*/ void *data)
-{
- fprintf(dbg_objfmt_file, "symrec_data_delete(");
- if (data) {
- yasm_expr_print(dbg_objfmt_file, data);
- yasm_expr_delete(data);
- }
- fprintf(dbg_objfmt_file, ")\n");
-}
-
-static void
-dbg_objfmt_symrec_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
-{
- if (data) {
- fprintf(f, "%*sSize=", indent_level, "");
- yasm_expr_print(f, data);
- fprintf(f, "\n");
- } else {
- fprintf(f, "%*s(none)\n", indent_level, "");
- }
-}
-
-static int
-dbg_objfmt_directive(const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- unsigned long lindex)
-{
- fprintf(dbg_objfmt_file, "directive(\"%s\", ", name);
- yasm_vps_print(dbg_objfmt_file, valparams);
- fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", lindex);
- return 0; /* dbg format "recognizes" all directives */
-}
-
-static void
-dbg_objfmt_bc_objfmt_data_delete(unsigned int type, /*@only@*/ void *data)
-{
- fprintf(dbg_objfmt_file, "symrec_data_delete(%u, %p)\n", type, data);
- yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_bc_objfmt_data_print(FILE *f, int indent_level, unsigned int type,
- const void *data)
-{
- fprintf(f, "%*sType=%u\n", indent_level, "", type);
- fprintf(f, "%*sData=%p\n", indent_level, "", data);
-}
-
-
-/* Define valid debug formats to use with this object format */
-static const char *dbg_objfmt_dbgfmt_keywords[] = {
- "null",
- NULL
-};
-
-/* Define objfmt structure -- see objfmt.h for details */
-yasm_objfmt yasm_dbg_LTX_objfmt = {
- "Trace of all info passed to object format module",
- "dbg",
- "dbg",
- ".text",
- 32,
- dbg_objfmt_dbgfmt_keywords,
- "null",
- dbg_objfmt_initialize,
- dbg_objfmt_output,
- dbg_objfmt_cleanup,
- dbg_objfmt_sections_switch,
- dbg_objfmt_section_data_delete,
- dbg_objfmt_section_data_print,
- dbg_objfmt_extern_declare,
- dbg_objfmt_global_declare,
- dbg_objfmt_common_declare,
- dbg_objfmt_symrec_data_delete,
- dbg_objfmt_symrec_data_print,
- dbg_objfmt_directive,
- dbg_objfmt_bc_objfmt_data_delete,
- dbg_objfmt_bc_objfmt_data_print
-};
+++ /dev/null
-/*-
- * Copyright (c) 1996-1998 John D. Polstra.
- * All rights reserved.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 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.
- *
- * $FreeBSD: src/sys/sys/elf32.h,v 1.7 1999/08/28 00:51:41 peterr Exp $
- */
-
-#ifndef YASM_ELF32_H
-#define YASM_ELF32_H 1
-
-#include "elf_common.h"
-
-/*
- * ELF definitions common to all 32-bit architectures.
- */
-
-typedef unsigned long Elf32_Addr;
-typedef unsigned short Elf32_Half;
-typedef unsigned long Elf32_Off;
-typedef signed long Elf32_Sword;
-typedef unsigned long Elf32_Word;
-typedef unsigned long Elf32_Size;
-
-/*
- * ELF header.
- */
-
-typedef struct {
- unsigned char e_ident[EI_NIDENT]; /* File identification. */
- Elf32_Half e_type; /* File type. */
- Elf32_Half e_machine; /* Machine architecture. */
- Elf32_Word e_version; /* ELF format version. */
- Elf32_Addr e_entry; /* Entry point. */
- Elf32_Off e_phoff; /* Program header file offset. */
- Elf32_Off e_shoff; /* Section header file offset. */
- Elf32_Word e_flags; /* Architecture-specific flags. */
- Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
- Elf32_Half e_phentsize; /* Size of program header entry. */
- Elf32_Half e_phnum; /* Number of program header entries. */
- Elf32_Half e_shentsize; /* Size of section header entry. */
- Elf32_Half e_shnum; /* Number of section header entries. */
- Elf32_Half e_shstrndx; /* Section name strings section. */
-} Elf32_Ehdr;
-
-/*
- * Section header.
- */
-
-typedef struct {
- Elf32_Word sh_name; /* Section name (index into the
- section header string table). */
- Elf32_Word sh_type; /* Section type. */
- Elf32_Word sh_flags; /* Section flags. */
- Elf32_Addr sh_addr; /* Address in memory image. */
- Elf32_Off sh_offset; /* Offset in file. */
- Elf32_Size sh_size; /* Size in bytes. */
- Elf32_Word sh_link; /* Index of a related section. */
- Elf32_Word sh_info; /* Depends on section type. */
- Elf32_Size sh_addralign; /* Alignment in bytes. */
- Elf32_Size sh_entsize; /* Size of each entry in section. */
-} Elf32_Shdr;
-
-/*
- * Program header.
- */
-
-typedef struct {
- Elf32_Word p_type; /* Entry type. */
- Elf32_Off p_offset; /* File offset of contents. */
- Elf32_Addr p_vaddr; /* Virtual address in memory image. */
- Elf32_Addr p_paddr; /* Physical address (not used). */
- Elf32_Size p_filesz; /* Size of contents in file. */
- Elf32_Size p_memsz; /* Size of contents in memory. */
- Elf32_Word p_flags; /* Access permission flags. */
- Elf32_Size p_align; /* Alignment in memory and file. */
-} Elf32_Phdr;
-
-/*
- * Dynamic structure. The ".dynamic" section contains an array of them.
- */
-
-typedef struct {
- Elf32_Sword d_tag; /* Entry type. */
- union {
- Elf32_Size d_val; /* Integer value. */
- Elf32_Addr d_ptr; /* Address value. */
- } d_un;
-} Elf32_Dyn;
-
-/*
- * Relocation entries.
- */
-
-/* Relocations that don't need an addend field. */
-typedef struct {
- Elf32_Addr r_offset; /* Location to be relocated. */
- Elf32_Word r_info; /* Relocation type and symbol index. */
-} Elf32_Rel;
-
-/* Relocations that need an addend field. */
-typedef struct {
- Elf32_Addr r_offset; /* Location to be relocated. */
- Elf32_Word r_info; /* Relocation type and symbol index. */
- Elf32_Sword r_addend; /* Addend. */
-} Elf32_Rela;
-
-/* Macros for accessing the fields of r_info. */
-#define ELF32_R_SYM(info) ((info) >> 8)
-#define ELF32_R_TYPE(info) ((unsigned char)(info))
-
-/* Macro for constructing r_info from field values. */
-#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
-
-/*
- * Symbol table entries.
- */
-
-typedef struct {
- Elf32_Word st_name; /* String table index of name. */
- Elf32_Addr st_value; /* Symbol value. */
- Elf32_Size st_size; /* Size of associated object. */
- unsigned char st_info; /* Type and binding information. */
- unsigned char st_other; /* Reserved (not used). */
- Elf32_Half st_shndx; /* Section index of symbol. */
-} Elf32_Sym;
-
-/* Macros for accessing the fields of st_info. */
-#define ELF32_ST_BIND(info) ((info) >> 4)
-#define ELF32_ST_TYPE(info) ((info) & 0xf)
-
-/* Macro for constructing st_info from field values. */
-#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
-
-#endif /* !YASM_ELF32_H */
+++ /dev/null
-/*-
- * Copyright (c) 1998 John D. Polstra.
- * All rights reserved.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 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.
- *
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.5.2.3 2001/02/28 02:30:46 obrien Exp $
- */
-
-#ifndef YASM_ELF_COMMON_H
-#define YASM_ELF_COMMON_H 1
-
-/*
- * ELF definitions that are independent of architecture or word size.
- */
-
-/*
- * Note header. The ".note" section contains an array of notes. Each
- * begins with this header, aligned to a word boundary. Immediately
- * following the note header is n_namesz bytes of name, padded to the
- * next word boundary. Then comes n_descsz bytes of descriptor, again
- * padded to a word boundary. The values of n_namesz and n_descsz do
- * not include the padding.
- */
-
-typedef struct {
- unsigned long n_namesz; /* Length of name. */
- unsigned long n_descsz; /* Length of descriptor. */
- unsigned long n_type; /* Type of this note. */
-} Elf_Note;
-
-/* Indexes into the e_ident array. Keep synced with
- http://www.sco.com/developer/gabi/ch4.eheader.html */
-#define EI_MAG0 0 /* Magic number, byte 0. */
-#define EI_MAG1 1 /* Magic number, byte 1. */
-#define EI_MAG2 2 /* Magic number, byte 2. */
-#define EI_MAG3 3 /* Magic number, byte 3. */
-#define EI_CLASS 4 /* Class of machine. */
-#define EI_DATA 5 /* Data format. */
-#define EI_VERSION 6 /* ELF format version. */
-#define EI_OSABI 7 /* Operating system / ABI identification */
-#define EI_ABIVERSION 8 /* ABI version */
-#define OLD_EI_BRAND 8 /* Start of architecture identification. */
-#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
-#define EI_NIDENT 16 /* Size of e_ident array. */
-
-/* Values for the magic number bytes. */
-#define ELFMAG0 0x7f
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-
-/* Values for e_ident[EI_VERSION] and e_version. */
-#define EV_NONE 0
-#define EV_CURRENT 1
-
-/* Values for e_ident[EI_CLASS]. */
-#define ELFCLASSNONE 0 /* Unknown class. */
-#define ELFCLASS32 1 /* 32-bit architecture. */
-#define ELFCLASS64 2 /* 64-bit architecture. */
-
-/* Values for e_ident[EI_DATA]. */
-#define ELFDATANONE 0 /* Unknown data format. */
-#define ELFDATA2LSB 1 /* 2's complement little-endian. */
-#define ELFDATA2MSB 2 /* 2's complement big-endian. */
-
-/* Values for e_ident[EI_OSABI]. */
-#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
-#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */
-#define ELFOSABI_HPUX 1 /* HP-UX operating system */
-#define ELFOSABI_NETBSD 2 /* NetBSD */
-#define ELFOSABI_LINUX 3 /* GNU/Linux */
-#define ELFOSABI_HURD 4 /* GNU/Hurd */
-#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
-#define ELFOSABI_SOLARIS 6 /* Solaris */
-#define ELFOSABI_MONTEREY 7 /* Monterey */
-#define ELFOSABI_IRIX 8 /* IRIX */
-#define ELFOSABI_FREEBSD 9 /* FreeBSD */
-#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
-#define ELFOSABI_MODESTO 11 /* Novell Modesto */
-#define ELFOSABI_OPENBSD 12 /* OpenBSD */
-#define ELFOSABI_ARM 97 /* ARM */
-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
-
-/* e_ident */
-#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
- (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
- (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
- (ehdr).e_ident[EI_MAG3] == ELFMAG3)
-
-/* Values for e_type. */
-#define ET_NONE 0 /* Unknown type. */
-#define ET_REL 1 /* Relocatable. */
-#define ET_EXEC 2 /* Executable. */
-#define ET_DYN 3 /* Shared object. */
-#define ET_CORE 4 /* Core file. */
-
-/* Values for e_machine. */
-#define EM_NONE 0 /* Unknown machine. */
-#define EM_M32 1 /* AT&T WE32100. */
-#define EM_SPARC 2 /* Sun SPARC. */
-#define EM_386 3 /* Intel i386. */
-#define EM_68K 4 /* Motorola 68000. */
-#define EM_88K 5 /* Motorola 88000. */
-#define EM_486 6 /* Intel i486. */
-#define EM_860 7 /* Intel i860. */
-#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
-
-/* Extensions. This list is not complete. */
-#define EM_S370 9 /* IBM System/370 */
-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ /* Depreciated */
-#define EM_PARISC 15 /* HPPA */
-#define EM_SPARC32PLUS 18 /* SPARC v8plus */
-#define EM_PPC 20 /* PowerPC 32-bit */
-#define EM_PPC64 21 /* PowerPC 64-bit */
-#define EM_ARM 40 /* ARM */
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-#define EM_IA_64 50 /* Intel IA-46 Processor */
-#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
-#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI */
-
-/* Special section indexes. */
-#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
-#define SHN_LORESERVE 0xff00 /* First of reserved range. */
-#define SHN_LOPROC 0xff00 /* First processor-specific. */
-#define SHN_HIPROC 0xff1f /* Last processor-specific. */
-#define SHN_ABS 0xfff1 /* Absolute values. */
-#define SHN_COMMON 0xfff2 /* Common data. */
-#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
-
-/* sh_type */
-#define SHT_NULL 0 /* inactive */
-#define SHT_PROGBITS 1 /* program defined information */
-#define SHT_SYMTAB 2 /* symbol table section */
-#define SHT_STRTAB 3 /* string table section */
-#define SHT_RELA 4 /* relocation section with addends*/
-#define SHT_HASH 5 /* symbol hash table section */
-#define SHT_DYNAMIC 6 /* dynamic section */
-#define SHT_NOTE 7 /* note section */
-#define SHT_NOBITS 8 /* no space section */
-#define SHT_REL 9 /* relation section without addends */
-#define SHT_SHLIB 10 /* reserved - purpose unknown */
-#define SHT_DYNSYM 11 /* dynamic symbol table section */
-#define SHT_LOPROC 0x70000000 /* reserved range for processor */
-#define SHT_HIPROC 0x7fffffff /* specific section header types */
-#define SHT_LOUSER 0x80000000 /* reserved range for application */
-#define SHT_HIUSER 0xffffffff /* specific indexes */
-
-/* Flags for sh_flags. */
-#define SHF_WRITE 0x1 /* Section contains writable data. */
-#define SHF_ALLOC 0x2 /* Section occupies memory. */
-#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
-#define SHF_MASKPROC 0xf0000000 /* Reserved for processor-specific. */
-
-/* Values for p_type. */
-#define PT_NULL 0 /* Unused entry. */
-#define PT_LOAD 1 /* Loadable segment. */
-#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
-#define PT_INTERP 3 /* Pathname of interpreter. */
-#define PT_NOTE 4 /* Auxiliary information. */
-#define PT_SHLIB 5 /* Reserved (not used). */
-#define PT_PHDR 6 /* Location of program header itself. */
-
-#define PT_COUNT 7 /* Number of defined p_type values. */
-
-#define PT_LOPROC 0x70000000 /* First processor-specific type. */
-#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
-
-/* Values for p_flags. */
-#define PF_X 0x1 /* Executable. */
-#define PF_W 0x2 /* Writable. */
-#define PF_R 0x4 /* Readable. */
-
-/* Values for d_tag. */
-#define DT_NULL 0 /* Terminating entry. */
-#define DT_NEEDED 1 /* String table offset of a needed shared
- library. */
-#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
-#define DT_PLTGOT 3 /* Processor-dependent address. */
-#define DT_HASH 4 /* Address of symbol hash table. */
-#define DT_STRTAB 5 /* Address of string table. */
-#define DT_SYMTAB 6 /* Address of symbol table. */
-#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
-#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
-#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
-#define DT_STRSZ 10 /* Size of string table. */
-#define DT_SYMENT 11 /* Size of each symbol table entry. */
-#define DT_INIT 12 /* Address of initialization function. */
-#define DT_FINI 13 /* Address of finalization function. */
-#define DT_SONAME 14 /* String table offset of shared object
- name. */
-#define DT_RPATH 15 /* String table offset of library path. */
-#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. */
-#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
-#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
-#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
-#define DT_PLTREL 20 /* Type of relocation used for PLT. */
-#define DT_DEBUG 21 /* Reserved (not used). */
-#define DT_TEXTREL 22 /* Indicates there may be relocations in
- non-writable segments. */
-#define DT_JMPREL 23 /* Address of PLT relocations. */
-
-#define DT_COUNT 24 /* Number of defined d_tag values. */
-
-/* Values for n_type. Used in core files. */
-#define NT_PRSTATUS 1 /* Process status. */
-#define NT_FPREGSET 2 /* Floating point registers. */
-#define NT_PRPSINFO 3 /* Process state info. */
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-#define STB_LOCAL 0 /* Local symbol */
-#define STB_GLOBAL 1 /* Global symbol */
-#define STB_WEAK 2 /* like global - lower precedence */
-#define STB_LOPROC 13 /* reserved range for processor */
-#define STB_HIPROC 15 /* specific symbol bindings */
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-#define STT_NOTYPE 0 /* Unspecified type. */
-#define STT_OBJECT 1 /* Data object. */
-#define STT_FUNC 2 /* Function. */
-#define STT_SECTION 3 /* Section. */
-#define STT_FILE 4 /* Source file. */
-#define STT_LOPROC 13 /* reserved range for processor */
-#define STT_HIPROC 15 /* specific symbol types */
-
-/* Special symbol table indexes. */
-#define STN_UNDEF 0 /* Undefined symbol index. */
-
-#endif /* !YASM_ELF_COMMON_H */
+++ /dev/null
-/* $IdPath$
- * YASM optimizer module interface header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_OPTIMIZER_H
-#define YASM_OPTIMIZER_H
-
-/* Interface to the optimizer module(s) */
-struct yasm_optimizer {
- /* one-line description of the optimizer */
- const char *name;
-
- /* keyword used to select optimizer on the command line */
- const char *keyword;
-
- /* Main entrance point for the optimizer.
- *
- * This function takes the unoptimized linked list of sections and
- * optimizes it. If successful, the sections are ready for output to an
- * object file. (A failure is indicated by calling ErrorAt() from within
- * this function).
- */
- void (*optimize) (yasm_sectionhead *sections);
-};
-
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/optimizers/basic/Makefile.inc
-
-include src/optimizers/basic/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-basic.la
-
-yasm_basic_la_SOURCES = \
- src/optimizers/basic/basic-optimizer.c
-yasm_basic_la_LDFLAGS = -module -avoid-version
-yasm_basic_la_LIBADD = libyasm.la
-yasm_LDADD += -dlpreopen yasm-basic.la
+++ /dev/null
-/*
- * Basic optimizer (equivalent to the NASM 2-pass 'no optimizer' design)
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-
-#include "bc-int.h"
-
-#include "optimizer.h"
-
-
-#define SECTFLAG_NONE 0UL
-#define SECTFLAG_INPROGRESS (1UL<<0)
-#define SECTFLAG_DONE (1UL<<1)
-
-#define BCFLAG_NONE 0UL
-#define BCFLAG_INPROGRESS (1UL<<0)
-#define BCFLAG_DONE (1UL<<1)
-
-
-static int basic_optimize_section_1(yasm_section *sect,
- /*@unused@*/ /*@null@*/ void *d);
-
-static /*@null@*/ yasm_intnum *
-basic_optimize_calc_bc_dist_1(yasm_section *sect,
- /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2)
-{
- unsigned int dist;
- yasm_intnum *intn;
-
- if (yasm_section_get_opt_flags(sect) == SECTFLAG_NONE) {
- /* Section not started. Optimize it (recursively). */
- basic_optimize_section_1(sect, NULL);
- }
-
- /* If a section is done, the following will always succeed. If it's in-
- * progress, this will fail if the bytecode comes AFTER the current one.
- */
- if (precbc2) {
- if (precbc2->opt_flags == BCFLAG_DONE) {
- dist = precbc2->offset + precbc2->len;
- if (precbc1) {
- if (precbc1->opt_flags == BCFLAG_DONE) {
- if (dist < precbc1->offset + precbc1->len) {
- intn = yasm_intnum_new_uint(precbc1->offset +
- precbc1->len - dist);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
- return intn;
- }
- dist -= precbc1->offset + precbc1->len;
- } else {
- return NULL;
- }
- }
- return yasm_intnum_new_uint(dist);
- } else {
- return NULL;
- }
- } else {
- if (precbc1) {
- if (precbc1->opt_flags == BCFLAG_DONE) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
- return intn;
- } else {
- return NULL;
- }
- } else {
- return yasm_intnum_new_uint(0);
- }
- }
-}
-
-typedef struct basic_optimize_data {
- /*@observer@*/ yasm_bytecode *precbc;
- /*@observer@*/ const yasm_section *sect;
- int saw_unknown;
-} basic_optimize_data;
-
-static int
-basic_optimize_bytecode_1(/*@observer@*/ yasm_bytecode *bc, void *d)
-{
- basic_optimize_data *data = (basic_optimize_data *)d;
- yasm_bc_resolve_flags bcr_retval;
-
- /* Don't even bother if we're in-progress or done. */
- if (bc->opt_flags == BCFLAG_INPROGRESS)
- return 1;
- if (bc->opt_flags == BCFLAG_DONE)
- return 0;
-
- bc->opt_flags = BCFLAG_INPROGRESS;
-
- if (!data->precbc)
- bc->offset = 0;
- else
- bc->offset = data->precbc->offset + data->precbc->len;
- data->precbc = bc;
-
- /* We're doing just a single pass, so essentially ignore whether the size
- * is minimum or not, and just check for indeterminate length (indicative
- * of circular reference).
- */
- bcr_retval = yasm_bc_resolve(bc, 0, data->sect,
- basic_optimize_calc_bc_dist_1);
- if (bcr_retval & YASM_BC_RESOLVE_UNKNOWN_LEN) {
- if (!(bcr_retval & YASM_BC_RESOLVE_ERROR))
- yasm__error(bc->line, N_("circular reference detected."));
- data->saw_unknown = -1;
- return 0;
- }
-
- bc->opt_flags = BCFLAG_DONE;
-
- return 0;
-}
-
-static int
-basic_optimize_section_1(yasm_section *sect, /*@null@*/ void *d)
-{
- /*@null@*/ int *saw_unknown = (int *)d;
- basic_optimize_data data;
- unsigned long flags;
- int retval;
-
- data.precbc = NULL;
- data.sect = sect;
- data.saw_unknown = 0;
-
- /* Don't even bother if we're in-progress or done. */
- flags = yasm_section_get_opt_flags(sect);
- if (flags == SECTFLAG_INPROGRESS)
- return 1;
- if (flags == SECTFLAG_DONE)
- return 0;
-
- yasm_section_set_opt_flags(sect, SECTFLAG_INPROGRESS);
-
- retval = yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
- basic_optimize_bytecode_1);
- if (retval != 0)
- return retval;
-
- if (data.saw_unknown != 0 && saw_unknown)
- *saw_unknown = data.saw_unknown;
-
- yasm_section_set_opt_flags(sect, SECTFLAG_DONE);
-
- return 0;
-}
-
-static int
-basic_optimize_bytecode_2(/*@observer@*/ yasm_bytecode *bc, /*@null@*/ void *d)
-{
- basic_optimize_data *data = (basic_optimize_data *)d;
-
- assert(data != NULL);
-
- if (bc->opt_flags != BCFLAG_DONE)
- yasm_internal_error(N_("Optimizer pass 1 missed a bytecode!"));
-
- if (!data->precbc)
- bc->offset = 0;
- else
- bc->offset = data->precbc->offset + data->precbc->len;
- data->precbc = bc;
-
- if (yasm_bc_resolve(bc, 1, data->sect, yasm_common_calc_bc_dist) < 0)
- return -1;
- return 0;
-}
-
-static int
-basic_optimize_section_2(yasm_section *sect, /*@unused@*/ /*@null@*/ void *d)
-{
- basic_optimize_data data;
-
- data.precbc = NULL;
- data.sect = sect;
-
- if (yasm_section_get_opt_flags(sect) != SECTFLAG_DONE)
- yasm_internal_error(N_("Optimizer pass 1 missed a section!"));
-
- return yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
- basic_optimize_bytecode_2);
-}
-
-static void
-basic_optimize(yasm_sectionhead *sections)
-{
- int saw_unknown = 0;
-
- /* Optimization process: (essentially NASM's pass 1)
- * Determine the size of all bytecodes.
- * Forward references are /not/ resolved (only backward references are
- * computed and sized).
- * Check "critical" expressions (must be computable on the first pass,
- * i.e. depend only on symbols before it).
- * Differences from NASM:
- * - right-hand side of EQU is /not/ a critical expr (as the entire file
- * has already been parsed, we know all their values at this point).
- * - not strictly top->bottom scanning; we scan through a section and
- * hop to other sections as necessary.
- */
- if (yasm_sections_traverse(sections, &saw_unknown,
- basic_optimize_section_1) < 0 ||
- saw_unknown != 0)
- return;
-
- /* Check completion of all sections and save bytecode changes */
- yasm_sections_traverse(sections, NULL, basic_optimize_section_2);
-}
-
-/* Define optimizer structure -- see optimizer.h for details */
-yasm_optimizer yasm_basic_LTX_optimizer = {
- "Only the most basic optimizations",
- "basic",
- basic_optimize
-};
+++ /dev/null
-/*
- * Generic Options Support Header File
- *
- * Copyright (c) 2001 Stanislav Karchebny <berk@madfire.net>
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "options.h"
-#include "errwarn.h"
-
-
-#ifdef __DEBUG__
-#define DEBUG(x) fprintf ## x ;
-#else
-#define DEBUG(x)
-#endif
-
-
-/* Options Parser */
-int
-parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts,
- void (*print_error) (const char *fmt, ...))
-{
- int errors = 0;
- size_t i;
- int got_it;
-
- DEBUG((stderr, "parse_cmdline: entered\n"));
-
- fail:
- while (--argc) {
- argv++;
-
- if (argv[0][0] == '-') { /* opt */
- got_it = 0;
- if (argv[0][1] == '-') { /* lopt */
- for (i = 0; i < nopts; i++) {
- if (options[i].lopt &&
- strncmp(&argv[0][2], options[i].lopt,
- strlen(options[i].lopt)) == 0) {
- char *param;
-
- if (options[i].takes_param) {
- param = strchr(&argv[0][2], '=');
- if (!param) {
- print_error(
- _("option `--%s' needs an argument!"),
- options[i].lopt);
- errors++;
- goto fail;
- } else {
- *param = '\0';
- param++;
- }
- } else
- param = NULL;
-
- if (!options[i].
- handler(&argv[0][2], param, options[i].extra))
- got_it = 1;
- break;
- }
- }
- if (!got_it) {
- print_error(_("unrecognized option `%s'"), argv[0]);
- errors++;
- }
- } else { /* sopt */
-
- for (i = 0; i < nopts; i++) {
- if (argv[0][1] == options[i].sopt) {
- char *cmd = &argv[0][1];
- char *param;
-
- if (options[i].takes_param) {
- param = argv[1];
- if (argv[0][2] != '\0')
- param = &argv[0][2];
- else if (param == NULL || *param == '-') {
- print_error(
- _("option `-%c' needs an argument!"),
- options[i].sopt);
- errors++;
- goto fail;
- } else {
- argc--;
- argv++;
- }
- } else
- param = NULL;
-
- if (!options[i].handler(cmd, param, options[i].extra))
- got_it = 1;
- break;
- }
- }
- if (!got_it) {
- print_error(_("unrecognized option `%s'"), argv[0]);
- errors++;
- }
- }
- } else { /* not an option, then it should be a file or something */
-
- if (not_an_option_handler(argv[0]))
- errors++;
- }
- }
-
- DEBUG((stderr, "parse_cmdline: finished\n"));
- return errors;
-}
-
-void
-help_msg(const char *msg, const char *tail, opt_option *options, size_t nopts)
-{
- char optbuf[100], optopt[100];
- size_t i;
-
- printf("%s", gettext(msg));
-
- for (i = 0; i < nopts; i++) {
- optbuf[0] = 0;
- optopt[0] = 0;
-
- if (options[i].takes_param) {
- if (options[i].sopt) {
- sprintf(optbuf, "-%c <%s>", options[i].sopt,
- options[i].param_desc ? options[i].
- param_desc : _("param"));
- }
- if (options[i].sopt && options[i].lopt)
- strcat(optbuf, ", ");
- if (options[i].lopt) {
- sprintf(optopt, "--%s <%s>", options[i].lopt,
- options[i].param_desc ? options[i].
- param_desc : _("param"));
- strcat(optbuf, optopt);
- }
- } else {
- if (options[i].sopt) {
- sprintf(optbuf, "-%c", options[i].sopt);
- }
- if (options[i].sopt && options[i].lopt)
- strcat(optbuf, ", ");
- if (options[i].lopt) {
- sprintf(optopt, "--%s", options[i].lopt);
- strcat(optbuf, optopt);
- }
- }
-
- printf(" %-24s %s\n", optbuf, gettext(options[i].description));
- }
-
- printf("%s", gettext(tail));
-}
+++ /dev/null
-/* $IdPath$
- * Generic Options Support Header File
- *
- * Copyright (c) 2001 Stanislav Karchebny <berk@madfire.net>
- *
- * 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.
- *
- * 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.
- */
-#ifndef YASM_OPTIONS_H
-#define YASM_OPTIONS_H
-
-/* an option structure
- * operate on either -sopt, --lopt, -sopt <val> or --lopt=<val>
- */
-typedef struct opt_option_s
-{
- /* short option letter if present, 0 otherwise */
- char sopt;
-
- /* long option name if present, NULL otherwise */
- /*@null@*/ const char *lopt;
-
- /* !=0 if option requires parameter, 0 if not */
- int takes_param;
-
- int (*handler) (char *cmd, /*@null@*/ char *param, int extra);
- int extra; /* extra value for handler */
-
- /* description to use in help_msg() */
- /*@observer@*/ const char *description;
-
- /* optional description for the param taken (NULL if not present) */
- /* (short - will be printed after option sopt/lopt) */
- /*@observer@*/ /*@null@*/ const char *param_desc;
-} opt_option;
-
-/* handle everything that is not an option */
-int not_an_option_handler(char *param);
-
-/* parse command line calling handlers when appropriate
- * argc, argv - pass directly from main(argc,argv)
- * options - array of options
- * nopts - options count
- */
-int parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts,
- void (*print_error) (const char *fmt, ...));
-
-/* display help message msg followed by list of options in options and followed
- * by tail
- */
-void help_msg(const char *msg, const char *tail, opt_option *options,
- size_t nopts);
-
-#endif
+++ /dev/null
-/* $IdPath$
- * Parser module interface header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_PARSER_H
-#define YASM_PARSER_H
-
-/* Interface to the parser module(s) -- the "front end" of the assembler */
-struct yasm_parser {
- /* one-line description of the parser */
- const char *name;
-
- /* keyword used to select parser on the command line */
- const char *keyword;
-
- /* NULL-terminated list of preprocessors that are valid to use with this
- * parser. The raw preprocessor (raw_preproc) should always be in this
- * list so it's always possible to have no preprocessing done.
- */
- const char **preproc_keywords;
-
- /* Default preprocessor. */
- const char *default_preproc_keyword;
-
- /* Main entrance point for the parser.
- *
- * The parser needs access to both the object format module (for format-
- * specific directives and segment names), and the preprocessor.
- *
- * This function also takes the FILE * to the initial starting file and
- * the input filename.
- *
- * save_input is nonzero if the parser needs to save the original lines of
- * source in the input file into the linemgr via linemgr->add_assoc_data().
- *
- * This function returns the starting section of a linked list of sections
- * (whatever was in the file).
- */
- yasm_sectionhead *(*do_parse)
- (yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of, yasm_linemgr *lm,
- FILE *f, const char *in_filename, int save_input);
-};
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/parsers/nasm/Makefile.inc
-
-include src/parsers/nasm/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-#lib_LTLIBRARIES += yasm-nasm.la
-
-yasm_nasm_la_SOURCES += \
- src/parsers/nasm/nasm-parser.h \
- src/parsers/nasm/nasm-parser.c \
- src/parsers/nasm/nasm-defs.h \
- src/parsers/nasm/nasm-bison.y \
- nasm-bison.h \
- nasm-token.c
-#yasm_nasm_la_LDFLAGS = -module -avoid-version
-#yasm_nasm_la_LIBADD = libyasm.la
-#yasm_LDADD += -dlpreopen yasm-nasm.la
-
-nasm-token.c: $(srcdir)/src/parsers/nasm/nasm-token.re re2c$(EXEEXT) $(srcdir)/tools/re2c/cleanup.pl
- $(top_builddir)/re2c$(EXEEXT) -b $(srcdir)/src/parsers/nasm/nasm-token.re | $(PERL) $(srcdir)/tools/re2c/cleanup.pl | sed "/^#l/ s,re2c-out\.c,$@," > $@
-
-BUILT_SOURCES += \
- nasm-bison.c \
- nasm-bison.h \
- nasm-token.c
-
-CLEANFILES += \
- nasm-bison.c \
- nasm-bison.h \
- nasm-token.c
-
-EXTRA_DIST += \
- src/parsers/nasm/tests/Makefile.inc \
- src/parsers/nasm/nasm-token.re
-
-include src/parsers/nasm/tests/Makefile.inc
+++ /dev/null
-/*
- * NASM-compatible bison parser
- *
- * Copyright (C) 2001 Peter Johnson, Michael Urman
- *
- * 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.
- *
- * 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("$IdPath$");
-
-#ifdef STDC_HEADERS
-# include <math.h>
-#endif
-
-#include "bitvect.h"
-
-#include "linemgr.h"
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "expr-int.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-#include "objfmt.h"
-
-#include "arch.h"
-
-#include "src/parsers/nasm/nasm-parser.h"
-#include "src/parsers/nasm/nasm-defs.h"
-
-
-static void nasm_parser_error(const char *);
-static void nasm_parser_directive
- (const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams);
-static int fix_directive_symrec(/*@null@*/ yasm_expr__item *ei,
- /*@null@*/ void *d);
-
-static /*@null@*/ yasm_bytecode *nasm_parser_prev_bc = (yasm_bytecode *)NULL;
-static yasm_bytecode *nasm_parser_temp_bc;
-
-/* additional data declarations (dynamically generated) */
-/* @DATADECLS@ */
-
-/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
-%}
-
-%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_datavalhead datahead;
- yasm_dataval *data;
- yasm_bytecode *bc;
- yasm_valparamhead dir_valparams;
- yasm_valparam *dir_valparam;
- struct {
- yasm_insn_operandhead operands;
- int num_operands;
- } insn_operands;
- yasm_insn_operand *insn_operand;
-}
-
-%token <intn> INTNUM
-%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING FILENAME
-%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
-%token <int_info> DECLARE_DATA
-%token <int_info> RESERVE_SPACE
-%token INCBIN EQU TIMES
-%token SEG WRT NOSPLIT
-%token <arch_data> INSN PREFIX REG SEGREG TARGETMOD
-%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
-%token <str_val> ID LOCAL_ID SPECIAL_ID
-%token LINE
-
-%type <bc> line lineexp exp instr
-
-%type <ea> memaddr
-%type <exp> dvexpr expr direxpr
-%type <sym> explabel
-%type <str_val> label_id label_id_equ
-%type <data> dataval
-%type <datahead> datavals
-%type <dir_valparams> directive_valparams
-%type <dir_valparam> directive_valparam
-%type <insn_operands> operands
-%type <insn_operand> operand
-
-%left '|'
-%left '^'
-%left '&'
-%left LEFT_OP RIGHT_OP
-%left '-' '+'
-%left '*' '/' SIGNDIV '%' SIGNMOD
-%nonassoc UNARYOP
-%nonassoc SEG WRT
-%left ':'
-
-%%
-input: /* empty */
- | input line {
- nasm_parser_temp_bc =
- yasm_bcs_append(yasm_section_get_bytecodes(nasm_parser_cur_section),
- $2);
- if (nasm_parser_temp_bc)
- nasm_parser_prev_bc = nasm_parser_temp_bc;
- nasm_parser_linemgr->goto_next();
- }
-;
-
-line: '\n' { $$ = (yasm_bytecode *)NULL; }
- | lineexp '\n'
- | LINE INTNUM '+' INTNUM FILENAME '\n' {
- /* %line indicates the line number of the *next* line, so subtract out
- * the increment when setting the line number.
- */
- nasm_parser_linemgr->set($5, yasm_intnum_get_uint($2)
- - yasm_intnum_get_uint($4),
- yasm_intnum_get_uint($4));
- yasm_intnum_delete($2);
- yasm_intnum_delete($4);
- yasm_xfree($5);
- $$ = (yasm_bytecode *)NULL;
- }
- | '[' { nasm_parser_set_directive_state(); } directive ']' '\n' {
- $$ = (yasm_bytecode *)NULL;
- }
- | error '\n' {
- yasm__error(cur_lindex,
- N_("label or instruction expected at start of line"));
- $$ = (yasm_bytecode *)NULL;
- yyerrok;
- }
-;
-
-lineexp: exp
- | TIMES expr exp { $$ = $3; yasm_bc_set_multiple($$, $2); }
- | label { $$ = (yasm_bytecode *)NULL; }
- | label exp { $$ = $2; }
- | label TIMES expr exp { $$ = $4; yasm_bc_set_multiple($$, $3); }
- | label_id_equ EQU expr {
- yasm_symrec_define_equ($1, $3, cur_lindex);
- yasm_xfree($1);
- $$ = (yasm_bytecode *)NULL;
- }
-;
-
-exp: instr
- | DECLARE_DATA datavals {
- $$ = yasm_bc_new_data(&$2, $1, cur_lindex);
- }
- | RESERVE_SPACE expr {
- $$ = yasm_bc_new_reserve($2, $1, cur_lindex);
- }
- | INCBIN STRING {
- $$ = yasm_bc_new_incbin($2, NULL, NULL, cur_lindex);
- }
- | INCBIN STRING ',' expr {
- $$ = yasm_bc_new_incbin($2, $4, NULL, cur_lindex);
- }
- | INCBIN STRING ',' expr ',' expr {
- $$ = yasm_bc_new_incbin($2, $4, $6, cur_lindex);
- }
-;
-
-instr: INSN {
- $$ = nasm_parser_arch->parse.new_insn($1, 0, NULL,
- nasm_parser_cur_section,
- nasm_parser_prev_bc, cur_lindex);
- }
- | INSN operands {
- $$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands,
- &$2.operands,
- nasm_parser_cur_section,
- nasm_parser_prev_bc, cur_lindex);
- yasm_ops_delete(&$2.operands, 0);
- }
- | INSN error {
- yasm__error(cur_lindex, N_("expression syntax error"));
- $$ = NULL;
- }
- | PREFIX instr {
- $$ = $2;
- nasm_parser_arch->parse.handle_prefix($$, $1, cur_lindex);
- }
- | SEGREG instr {
- $$ = $2;
- nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], cur_lindex);
- }
-;
-
-datavals: dataval {
- yasm_dvs_initialize(&$$);
- yasm_dvs_append(&$$, $1);
- }
- | datavals ',' dataval { yasm_dvs_append(&$1, $3); $$ = $1; }
-;
-
-dataval: dvexpr { $$ = yasm_dv_new_expr($1); }
- | STRING { $$ = yasm_dv_new_string($1); }
- | error {
- yasm__error(cur_lindex, N_("expression syntax error"));
- $$ = (yasm_dataval *)NULL;
- }
-;
-
-label: label_id {
- yasm_symrec_define_label($1, nasm_parser_cur_section,
- nasm_parser_prev_bc, 1, cur_lindex);
- yasm_xfree($1);
- }
- | label_id ':' {
- yasm_symrec_define_label($1, nasm_parser_cur_section,
- nasm_parser_prev_bc, 1, cur_lindex);
- yasm_xfree($1);
- }
-;
-
-label_id: ID {
- $$ = $1;
- if (nasm_parser_locallabel_base)
- yasm_xfree(nasm_parser_locallabel_base);
- nasm_parser_locallabel_base_len = strlen($1);
- nasm_parser_locallabel_base =
- yasm_xmalloc(nasm_parser_locallabel_base_len+1);
- strcpy(nasm_parser_locallabel_base, $1);
- }
- | SPECIAL_ID
- | LOCAL_ID
-;
-
-label_id_equ: ID
- | SPECIAL_ID
- | LOCAL_ID
-;
-
-/* directives */
-directive: DIRECTIVE_NAME directive_val {
- yasm_xfree($1);
- }
- | DIRECTIVE_NAME error {
- yasm__error(cur_lindex, N_("invalid arguments to [%s]"), $1);
- yasm_xfree($1);
- }
-;
-
- /* $<str_val>0 is the DIRECTIVE_NAME */
- /* After : is (optional) object-format specific extension */
-directive_val: directive_valparams {
- nasm_parser_directive($<str_val>0, &$1, NULL);
- }
- | directive_valparams ':' directive_valparams {
- nasm_parser_directive($<str_val>0, &$1, &$3);
- }
-;
-
-directive_valparams: directive_valparam {
- yasm_vps_initialize(&$$);
- yasm_vps_append(&$$, $1);
- }
- | directive_valparams directive_valparam {
- yasm_vps_append(&$1, $2);
- $$ = $1;
- }
- | directive_valparams ',' directive_valparam {
- yasm_vps_append(&$1, $3);
- $$ = $1;
- }
-;
-
-directive_valparam: direxpr {
- /* If direxpr is just an ID, put it in val and delete the expr.
- * Otherwise, we need to go through the expr and replace the current
- * (local) symrecs with the use of global ones.
- */
- const /*@null@*/ yasm_symrec *vp_symrec;
- if ((vp_symrec = yasm_expr_get_symrec(&$1, 0))) {
- yasm_vp_new($$, yasm__xstrdup(yasm_symrec_get_name(vp_symrec)),
- NULL);
- yasm_expr_delete($1);
- } else {
- yasm_expr__traverse_leaves_in($1, NULL, fix_directive_symrec);
- yasm_vp_new($$, NULL, $1);
- }
- }
- | STRING { yasm_vp_new($$, $1, NULL); }
- | ID '=' direxpr {
- yasm_expr__traverse_leaves_in($3, NULL, fix_directive_symrec);
- yasm_vp_new($$, $1, $3);
- }
-;
-
-/* memory addresses */
-memaddr: expr {
- $$ = nasm_parser_arch->parse.ea_new_expr($1);
- }
- | SEGREG ':' memaddr {
- $$ = $3;
- nasm_parser_arch->parse.handle_seg_override($$, $1[0], cur_lindex);
- }
- | BYTE memaddr { $$ = $2; yasm_ea_set_len($$, 1); }
- | WORD memaddr { $$ = $2; yasm_ea_set_len($$, 2); }
- | DWORD memaddr { $$ = $2; yasm_ea_set_len($$, 4); }
- | QWORD memaddr { $$ = $2; yasm_ea_set_len($$, 8); }
- | NOSPLIT memaddr { $$ = $2; yasm_ea_set_nosplit($$, 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;
- }
-;
-
-operand: '[' memaddr ']' { $$ = yasm_operand_new_mem($2); }
- | expr { $$ = yasm_operand_new_imm($1); }
- | SEGREG { $$ = yasm_operand_new_segreg($1[0]); }
- | BYTE operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 1)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 1;
- }
- | WORD operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 2)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 2;
- }
- | DWORD operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 4)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 4;
- }
- | QWORD operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 8)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 8;
- }
- | TWORD operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 10)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 10;
- }
- | DQWORD operand {
- $$ = $2;
- if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 16)
- yasm__error(cur_lindex, N_("cannot override register size"));
- else
- $$->size = 16;
- }
- | TARGETMOD operand { $$ = $2; $$->targetmod = $1[0]; }
-;
-
-/* expression trees */
-
-/* expr w/o FLTNUM and unary + and -, for use in directives */
-direxpr: INTNUM { $$ = p_expr_new_ident(yasm_expr_int($1)); }
- | ID {
- $$ = p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_define_label($1, NULL, NULL, 0, cur_lindex)));
- yasm_xfree($1);
- }
- | direxpr '|' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
- | direxpr '^' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_XOR, $3); }
- | direxpr '&' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_AND, $3); }
- | direxpr LEFT_OP direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_SHL, $3); }
- | direxpr RIGHT_OP direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_SHR, $3); }
- | direxpr '+' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_ADD, $3); }
- | direxpr '-' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_SUB, $3); }
- | direxpr '*' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_MUL, $3); }
- | direxpr '/' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_DIV, $3); }
- | direxpr SIGNDIV direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNDIV, $3); }
- | direxpr '%' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_MOD, $3); }
- | direxpr SIGNMOD direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNMOD, $3); }
- /*| '!' expr { $$ = p_expr_new_branch(YASM_EXPR_LNOT, $2); }*/
- | '~' direxpr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NOT, $2); }
- | '(' direxpr ')' { $$ = $2; }
-;
-
-dvexpr: 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)); }
- /*| dvexpr '||' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_LOR, $3); }*/
- | dvexpr '|' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
- | dvexpr '^' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_XOR, $3); }
- /*| dvexpr '&&' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_LAND, $3); }*/
- | dvexpr '&' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_AND, $3); }
- /*| dvexpr '==' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_EQUALS, $3); }*/
- /*| dvexpr '>' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_GT, $3); }*/
- /*| dvexpr '<' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_GT, $3); }*/
- /*| dvexpr '>=' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_GE, $3); }*/
- /*| dvexpr '<=' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_GE, $3); }*/
- /*| dvexpr '!=' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_NE, $3); }*/
- | dvexpr LEFT_OP dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_SHL, $3); }
- | dvexpr RIGHT_OP dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_SHR, $3); }
- | dvexpr '+' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_ADD, $3); }
- | dvexpr '-' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_SUB, $3); }
- | dvexpr '*' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_MUL, $3); }
- | dvexpr '/' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_DIV, $3); }
- | dvexpr SIGNDIV dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNDIV, $3); }
- | dvexpr '%' dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_MOD, $3); }
- | dvexpr SIGNMOD dvexpr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNMOD, $3); }
- | '+' dvexpr %prec UNARYOP { $$ = $2; }
- | '-' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NEG, $2); }
- /*| '!' dvexpr { $$ = p_expr_new_branch(YASM_EXPR_LNOT, $2); }*/
- | '~' dvexpr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NOT, $2); }
- | SEG dvexpr { $$ = p_expr_new_branch(YASM_EXPR_SEG, $2); }
- | WRT dvexpr { $$ = p_expr_new_branch(YASM_EXPR_WRT, $2); }
- | '(' dvexpr ')' { $$ = $2; }
-;
-
-/* Expressions for operands and memory expressions.
- * We don't attempt to check memory expressions for validity here.
- * Essentially the same as expr_no_string above but adds REG and STRING.
- */
-expr: INTNUM { $$ = p_expr_new_ident(yasm_expr_int($1)); }
- | FLTNUM { $$ = p_expr_new_ident(yasm_expr_float($1)); }
- | REG { $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
- | STRING {
- $$ = p_expr_new_ident(yasm_expr_int(
- yasm_intnum_new_charconst_nasm($1, cur_lindex)));
- yasm_xfree($1);
- }
- | explabel { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
- /*| expr '||' expr { $$ = p_expr_new_tree($1, YASM_EXPR_LOR, $3); }*/
- | 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_LAND, $3); }*/
- | expr '&' expr { $$ = p_expr_new_tree($1, YASM_EXPR_AND, $3); }
- /*| expr '==' expr { $$ = p_expr_new_tree($1, YASM_EXPR_EQUALS, $3); }*/
- /*| expr '>' expr { $$ = p_expr_new_tree($1, YASM_EXPR_GT, $3); }*/
- /*| expr '<' expr { $$ = p_expr_new_tree($1, YASM_EXPR_GT, $3); }*/
- /*| expr '>=' expr { $$ = p_expr_new_tree($1, YASM_EXPR_GE, $3); }*/
- /*| expr '<=' expr { $$ = p_expr_new_tree($1, YASM_EXPR_GE, $3); }*/
- /*| expr '!=' expr { $$ = p_expr_new_tree($1, YASM_EXPR_NE, $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 SIGNDIV expr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNDIV, $3); }
- | expr '%' expr { $$ = p_expr_new_tree($1, YASM_EXPR_MOD, $3); }
- | expr SIGNMOD expr { $$ = p_expr_new_tree($1, YASM_EXPR_SIGNMOD, $3); }
- | '+' expr %prec UNARYOP { $$ = $2; }
- | '-' expr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NEG, $2); }
- /*| '!' expr { $$ = p_expr_new_branch(YASM_EXPR_LNOT, $2); }*/
- | '~' expr %prec UNARYOP { $$ = p_expr_new_branch(YASM_EXPR_NOT, $2); }
- | SEG expr { $$ = p_expr_new_branch(YASM_EXPR_SEG, $2); }
- | WRT expr { $$ = p_expr_new_branch(YASM_EXPR_WRT, $2); }
- | expr ':' expr { $$ = p_expr_new_tree($1, YASM_EXPR_SEGOFF, $3); }
- | '(' expr ')' { $$ = $2; }
-;
-
-explabel: ID {
- $$ = yasm_symrec_use($1, cur_lindex);
- yasm_xfree($1);
- }
- | SPECIAL_ID {
- $$ = yasm_symrec_use($1, cur_lindex);
- yasm_xfree($1);
- }
- | LOCAL_ID {
- $$ = yasm_symrec_use($1, cur_lindex);
- yasm_xfree($1);
- }
- | '$' {
- /* "$" references the current assembly position */
- $$ = yasm_symrec_define_label("$", nasm_parser_cur_section,
- nasm_parser_prev_bc, 0, cur_lindex);
- }
- | START_SECTION_ID {
- /* "$$" references the start of the current section */
- $$ = yasm_symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
- cur_lindex);
- }
-;
-
-%%
-/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
-
-static int
-fix_directive_symrec(yasm_expr__item *ei, /*@unused@*/ void *d)
-{
- if (!ei || ei->type != YASM_EXPR_SYM)
- return 0;
-
- /* FIXME: Delete current symrec */
- ei->data.sym =
- yasm_symrec_use(yasm_symrec_get_name(ei->data.sym), cur_lindex);
-
- return 0;
-}
-
-static void
-nasm_parser_directive(const char *name, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams)
-{
- yasm_valparam *vp, *vp2;
- yasm_symrec *sym;
- unsigned long lindex = cur_lindex;
-
- /* Handle (mostly) output-format independent directives here */
- if (yasm__strcasecmp(name, "extern") == 0) {
- vp = yasm_vps_first(valparams);
- if (vp->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_EXTERN, lindex);
- if (nasm_parser_objfmt->extern_declare)
- nasm_parser_objfmt->extern_declare(sym, objext_valparams,
- lindex);
- } else
- yasm__error(lindex, N_("invalid argument to [%s]"), "EXTERN");
- } else if (yasm__strcasecmp(name, "global") == 0) {
- vp = yasm_vps_first(valparams);
- if (vp->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_GLOBAL, lindex);
- if (nasm_parser_objfmt->global_declare)
- nasm_parser_objfmt->global_declare(sym, objext_valparams,
- lindex);
- } else
- yasm__error(lindex, N_("invalid argument to [%s]"), "GLOBAL");
- } else if (yasm__strcasecmp(name, "common") == 0) {
- vp = yasm_vps_first(valparams);
- if (vp->val) {
- vp2 = yasm_vps_next(vp);
- if (!vp2 || (!vp2->val && !vp2->param))
- yasm__error(lindex, N_("no size specified in %s declaration"),
- "COMMON");
- else {
- if (vp2->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
- lindex);
- if (nasm_parser_objfmt->common_declare)
- nasm_parser_objfmt->common_declare(sym,
- p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_use(vp2->val, lindex))),
- objext_valparams, lindex);
- } else if (vp2->param) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
- lindex);
- if (nasm_parser_objfmt->common_declare)
- nasm_parser_objfmt->common_declare(sym, vp2->param,
- objext_valparams,
- lindex);
- vp2->param = NULL;
- }
- }
- } else
- yasm__error(lindex, N_("invalid argument to [%s]"), "COMMON");
- } else if (yasm__strcasecmp(name, "section") == 0 ||
- yasm__strcasecmp(name, "segment") == 0) {
- yasm_section *new_section =
- nasm_parser_objfmt->sections_switch(&nasm_parser_sections,
- valparams, objext_valparams,
- lindex);
- if (new_section) {
- nasm_parser_cur_section = new_section;
- nasm_parser_prev_bc =
- yasm_bcs_last(yasm_section_get_bytecodes(new_section));
- } else
- yasm__error(lindex, N_("invalid argument to [%s]"), "SECTION");
- } else if (yasm__strcasecmp(name, "absolute") == 0) {
- /* it can be just an ID or a complete expression, so handle both. */
- vp = yasm_vps_first(valparams);
- if (vp->val)
- nasm_parser_cur_section =
- yasm_sections_switch_absolute(&nasm_parser_sections,
- p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_use(vp->val, lindex))));
- else if (vp->param) {
- nasm_parser_cur_section =
- yasm_sections_switch_absolute(&nasm_parser_sections,
- vp->param);
- vp->param = NULL;
- }
- nasm_parser_prev_bc = (yasm_bytecode *)NULL;
- } else if (yasm__strcasecmp(name, "cpu") == 0) {
- yasm_vps_foreach(vp, valparams) {
- if (vp->val)
- nasm_parser_arch->parse.switch_cpu(vp->val, lindex);
- else if (vp->param) {
- const yasm_intnum *intcpu;
- intcpu = yasm_expr_get_intnum(&vp->param, NULL);
- if (!intcpu)
- yasm__error(lindex, N_("invalid argument to [%s]"), "CPU");
- else {
- char strcpu[16];
- sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
- nasm_parser_arch->parse.switch_cpu(strcpu, lindex);
- }
- }
- }
- } else if (!nasm_parser_arch->parse.directive(name, valparams,
- objext_valparams,
- &nasm_parser_sections,
- lindex)) {
- ;
- } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
- &nasm_parser_sections, lindex)) {
- yasm__error(lindex, N_("unrecognized directive [%s]"), name);
- }
-
- yasm_vps_delete(valparams);
- if (objext_valparams)
- yasm_vps_delete(objext_valparams);
-}
-
-static void
-nasm_parser_error(const char *s)
-{
- yasm__parser_error(cur_lindex, s);
-}
-
+++ /dev/null
-/* $IdPath$
- * Variable name redefinitions for NASM-compatible parser
- *
- * Copyright (C) 2001 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.
- *
- * 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 nasm_parser__create_buffer
-#define yy_delete_buffer nasm_parser__delete_buffer
-#define yy_init_buffer nasm_parser__init_buffer
-#define yy_load_buffer_state nasm_parser__load_buffer_state
-#define yy_switch_to_buffer nasm_parser__switch_to_buffer
-#define yyact nasm_parser_act
-#define yyback nasm_parser_back
-#define yybgin nasm_parser_bgin
-#define yychar nasm_parser_char
-#define yychk nasm_parser_chk
-#define yycrank nasm_parser_crank
-#define yydebug nasm_parser_debug
-#define yydef nasm_parser_def
-#define yyerrflag nasm_parser_errflag
-#define yyerror nasm_parser_error
-#define yyestate nasm_parser_estate
-#define yyexca nasm_parser_exca
-#define yyextra nasm_parser_extra
-#define yyfnd nasm_parser_fnd
-#define yyin nasm_parser_in
-#define yyinput nasm_parser_input
-#define yyleng nasm_parser_leng
-#define yylex nasm_parser_lex
-#define yylineno nasm_parser_lineno
-#define yylook nasm_parser_look
-#define yylsp nasm_parser_lsp
-#define yylstate nasm_parser_lstate
-#define yylval nasm_parser_lval
-#define yymatch nasm_parser_match
-#define yymorfg nasm_parser_morfg
-#define yynerrs nasm_parser_nerrs
-#define yyolsp nasm_parser_olsp
-#define yyout nasm_parser_out
-#define yyoutput nasm_parser_output
-#define yypact nasm_parser_pact
-#define yyparse nasm_parser_parse
-#define yypgo nasm_parser_pgo
-#define yyprevious nasm_parser_previous
-#define yyps nasm_parser_ps
-#define yypv nasm_parser_pv
-#define yyr1 nasm_parser_r1
-#define yyr2 nasm_parser_r2
-#define yyreds nasm_parser_reds
-#define yyrestart nasm_parser_restart
-#define yys nasm_parser_s
-#define yysbuf nasm_parser_sbuf
-#define yysptr nasm_parser_sptr
-#define yystate nasm_parser_state
-#define yysvec nasm_parser_svec
-#define yytchar nasm_parser_tchar
-#define yytext nasm_parser_text
-#define yytmp nasm_parser_tmp
-#define yytoks nasm_parser_toks
-#define yytop nasm_parser_top
-#define yyunput nasm_parser_unput
-#define yyv nasm_parser_v
-#define yyval nasm_parser_val
-#define yyvstop nasm_parser_vstop
-/*#define yywrap nasm_parser_wrap*/
+++ /dev/null
-/*
- * NASM-compatible parser
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-
-#include "section.h"
-#include "objfmt.h"
-#include "preproc.h"
-#include "parser.h"
-
-#include "nasm-parser.h"
-
-
-FILE *nasm_parser_in = NULL;
-size_t (*nasm_parser_input) (char *buf, size_t max_size);
-
-yasm_sectionhead nasm_parser_sections;
-/*@dependent@*/ yasm_section *nasm_parser_cur_section;
-
-/* last "base" label for local (.) labels */
-char *nasm_parser_locallabel_base = (char *)NULL;
-size_t nasm_parser_locallabel_base_len = 0;
-
-/*@dependent@*/ yasm_arch *nasm_parser_arch;
-/*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-/*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
-
-int nasm_parser_save_input;
-
-static /*@dependent@*/ yasm_sectionhead *
-nasm_parser_do_parse(yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of,
- yasm_linemgr *lm, FILE *f, const char *in_filename,
- int save_input)
- /*@globals killed nasm_parser_locallabel_base @*/
-{
- pp->initialize(f, in_filename, lm);
- nasm_parser_in = f;
- nasm_parser_input = pp->input;
- nasm_parser_arch = a;
- nasm_parser_objfmt = of;
- nasm_parser_linemgr = lm;
- nasm_parser_save_input = save_input;
-
- /* Initialize section list */
- nasm_parser_cur_section =
- yasm_sections_initialize(&nasm_parser_sections, of);
-
- /* yacc debugging, needs YYDEBUG set in bison.y.in to work */
- /* nasm_parser_debug = 1; */
-
- nasm_parser_parse();
-
- nasm_parser_cleanup();
-
- /* Free locallabel base if necessary */
- if (nasm_parser_locallabel_base)
- yasm_xfree(nasm_parser_locallabel_base);
-
- return &nasm_parser_sections;
-}
-
-/* Define valid preprocessors to use with this parser */
-static const char *nasm_parser_preproc_keywords[] = {
- "raw",
- NULL
-};
-
-/* Define parser structure -- see parser.h for details */
-yasm_parser yasm_nasm_LTX_parser = {
- "NASM-compatible parser",
- "nasm",
- nasm_parser_preproc_keywords,
- "raw",
- nasm_parser_do_parse
-};
+++ /dev/null
-/* $IdPath$
- * NASM-compatible parser header file
- *
- * Copyright (C) 2002 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.
- *
- * 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.
- */
-#ifndef YASM_NASM_PARSER_H
-#define YASM_NASM_PARSER_H
-
-int nasm_parser_parse(void);
-void nasm_parser_cleanup(void);
-int nasm_parser_lex(void);
-void nasm_parser_set_directive_state(void);
-
-extern FILE *nasm_parser_in;
-extern int nasm_parser_debug;
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
-
-extern yasm_sectionhead nasm_parser_sections;
-extern /*@dependent@*/ yasm_section *nasm_parser_cur_section;
-
-extern char *nasm_parser_locallabel_base;
-extern size_t nasm_parser_locallabel_base_len;
-
-extern /*@dependent@*/ yasm_arch *nasm_parser_arch;
-extern /*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-extern /*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
-
-extern int nasm_parser_save_input;
-
-#define cur_lindex (nasm_parser_linemgr->get_current())
-
-#define p_expr_new_tree(l,o,r) yasm_expr_new_tree(l,o,r,cur_lindex)
-#define p_expr_new_branch(o,r) yasm_expr_new_branch(o,r,cur_lindex)
-#define p_expr_new_ident(r) yasm_expr_new_ident(r,cur_lindex)
-
-#endif
+++ /dev/null
-/*
- * NASM-compatible re2c lexer
- *
- * Copyright (C) 2001 Peter Johnson
- *
- * Portions based on re2c's example code.
- *
- * 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.
- *
- * 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("$IdPath$");
-
-#include "bitvect.h"
-
-#include "linemgr.h"
-#include "errwarn.h"
-#include "intnum.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-
-#include "arch.h"
-
-#include "src/parsers/nasm/nasm-parser.h"
-#include "src/parsers/nasm/nasm-defs.h"
-#include "nasm-bison.h"
-
-
-#define BSIZE 8192
-
-#define YYCTYPE char
-#define YYCURSOR cursor
-#define YYLIMIT s.lim
-#define YYMARKER s.ptr
-#define YYFILL(n) {cursor = fill(cursor);}
-
-#define RETURN(i) {s.cur = cursor; return i;}
-
-#define SCANINIT() { \
- s.tchar = cursor - s.pos; \
- s.tline = s.cline; \
- s.tok = cursor; \
- }
-
-#define TOKLEN (cursor-s.tok)
-
-typedef struct Scanner {
- YYCTYPE *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
- unsigned int tchar, tline, cline;
-} Scanner;
-
-#define MAX_SAVED_LINE_LEN 80
-static char cur_line[MAX_SAVED_LINE_LEN];
-
-static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 };
-
-static YYCTYPE *
-fill(YYCTYPE *cursor)
-{
- int first = 0;
- if(!s.eof){
- size_t cnt = s.tok - s.bot;
- if(cnt){
- memcpy(s.bot, s.tok, s.lim - s.tok);
- s.tok = s.bot;
- s.ptr -= cnt;
- cursor -= cnt;
- s.pos -= cnt;
- s.lim -= cnt;
- }
- if (!s.bot)
- first = 1;
- if((s.top - s.lim) < BSIZE){
- char *buf = yasm_xmalloc((s.lim - s.bot) + BSIZE);
- memcpy(buf, s.tok, s.lim - s.tok);
- s.tok = buf;
- s.ptr = &buf[s.ptr - s.bot];
- cursor = &buf[cursor - s.bot];
- s.pos = &buf[s.pos - s.bot];
- s.lim = &buf[s.lim - s.bot];
- s.top = &s.lim[BSIZE];
- if (s.bot)
- yasm_xfree(s.bot);
- s.bot = buf;
- }
- if((cnt = nasm_parser_input(s.lim, BSIZE)) == 0){
- s.eof = &s.lim[cnt]; *s.eof++ = '\n';
- }
- s.lim += cnt;
- if (first && nasm_parser_save_input) {
- int i;
- /* save next line into cur_line */
- for (i=0; i<79 && &s.tok[i] < s.lim && s.tok[i] != '\n'; i++)
- cur_line[i] = s.tok[i];
- cur_line[i] = '\0';
- }
- }
- return cursor;
-}
-
-static void
-delete_line(/*@only@*/ void *data)
-{
- yasm_xfree(data);
-}
-
-static YYCTYPE *
-save_line(YYCTYPE *cursor)
-{
- int i = 0;
-
- /* save previous line using assoc_data */
- nasm_parser_linemgr->add_assoc_data(YASM_LINEMGR_STD_TYPE_SOURCE,
- yasm__xstrdup(cur_line), delete_line);
- /* save next line into cur_line */
- if ((YYLIMIT - YYCURSOR) < 80)
- YYFILL(80);
- for (i=0; i<79 && &cursor[i] < s.lim && cursor[i] != '\n'; i++)
- cur_line[i] = cursor[i];
- cur_line[i] = '\0';
- return cursor;
-}
-
-void
-nasm_parser_cleanup(void)
-{
- if (s.bot)
- yasm_xfree(s.bot);
-}
-
-/* starting size of string buffer */
-#define STRBUF_ALLOC_SIZE 128
-
-/* string buffer used when parsing strings/character constants */
-static char *strbuf = (char *)NULL;
-
-/* length of strbuf (including terminating NULL character) */
-static size_t strbuf_size = 0;
-
-static int linechg_numcount;
-
-/*!re2c
- any = [\000-\377];
- digit = [0-9];
- iletter = [a-zA-Z];
- bindigit = [01];
- octdigit = [0-7];
- hexdigit = [0-9a-fA-F];
- ws = [ \t\r];
- quot = ["'];
- A = [aA];
- B = [bB];
- C = [cC];
- D = [dD];
- E = [eE];
- F = [fF];
- G = [gG];
- H = [hH];
- I = [iI];
- J = [jJ];
- K = [kK];
- L = [lL];
- M = [mM];
- N = [nN];
- O = [oO];
- P = [pP];
- Q = [qQ];
- R = [rR];
- S = [sS];
- T = [tT];
- U = [uU];
- V = [vV];
- W = [wW];
- X = [xX];
- Y = [yY];
- Z = [zZ];
-*/
-
-static enum {
- INITIAL,
- DIRECTIVE,
- DIRECTIVE2,
- LINECHG,
- LINECHG2
-} state = INITIAL;
-
-void
-nasm_parser_set_directive_state(void)
-{
- state = DIRECTIVE;
-}
-
-int
-nasm_parser_lex(void)
-{
- YYCTYPE *cursor = s.cur;
- YYCTYPE endch;
- size_t count, len;
- YYCTYPE savech;
- yasm_arch_check_id_retval check_id_ret;
-
- /* Catch EOF */
- if (s.eof && cursor == s.eof)
- return 0;
-
- /* Jump to proper "exclusive" states */
- switch (state) {
- case DIRECTIVE:
- goto directive;
- case LINECHG:
- goto linechg;
- case LINECHG2:
- goto linechg2;
- default:
- break;
- }
-
-scan:
- SCANINIT();
-
- /*!re2c
- /* standard decimal integer */
- digit+ {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
- RETURN(INTNUM);
- }
- /* 10010011b - binary number */
-
- bindigit+ "b" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
- yylval.intn = yasm_intnum_new_bin(s.tok, cur_lindex);
- RETURN(INTNUM);
- }
-
- /* 777q - octal number */
- octdigit+ "q" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
- yylval.intn = yasm_intnum_new_oct(s.tok, cur_lindex);
- RETURN(INTNUM);
- }
-
- /* 0AAh form of hexidecimal number */
- digit hexdigit* "h" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
- yylval.intn = yasm_intnum_new_hex(s.tok, cur_lindex);
- RETURN(INTNUM);
- }
-
- /* $0AA and 0xAA forms of hexidecimal number */
- (("$" digit) | "0x") hexdigit+ {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- if (s.tok[1] == 'x')
- /* skip 0 and x */
- yylval.intn = yasm_intnum_new_hex(s.tok+2, cur_lindex);
- else
- /* don't skip 0 */
- yylval.intn = yasm_intnum_new_hex(s.tok+1, cur_lindex);
- s.tok[TOKLEN] = savech;
- RETURN(INTNUM);
- }
-
- /* floating point value */
- digit+ "." digit* (E [-+]? digit+)? {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.flt = yasm_floatnum_new(s.tok);
- s.tok[TOKLEN] = savech;
- RETURN(FLTNUM);
- }
-
- /* string/character constant values */
- quot {
- endch = s.tok[0];
- goto stringconst;
- }
-
- /* %line linenum+lineinc filename */
- "%line" {
- state = LINECHG;
- linechg_numcount = 0;
- RETURN(LINE);
- }
-
- /* size specifiers */
- B Y T E { yylval.int_info = 1; RETURN(BYTE); }
- W O R D { yylval.int_info = 2; RETURN(WORD); }
- D W O R D { yylval.int_info = 4; RETURN(DWORD); }
- Q W O R D { yylval.int_info = 8; RETURN(QWORD); }
- T W O R D { yylval.int_info = 10; RETURN(TWORD); }
- D Q W O R D { yylval.int_info = 16; RETURN(DQWORD); }
-
- /* pseudo-instructions */
- D B { yylval.int_info = 1; RETURN(DECLARE_DATA); }
- D W { yylval.int_info = 2; RETURN(DECLARE_DATA); }
- D D { yylval.int_info = 4; RETURN(DECLARE_DATA); }
- D Q { yylval.int_info = 8; RETURN(DECLARE_DATA); }
- D T { yylval.int_info = 10; RETURN(DECLARE_DATA); }
-
- R E S B { yylval.int_info = 1; RETURN(RESERVE_SPACE); }
- R E S W { yylval.int_info = 2; RETURN(RESERVE_SPACE); }
- R E S D { yylval.int_info = 4; RETURN(RESERVE_SPACE); }
- R E S Q { yylval.int_info = 8; RETURN(RESERVE_SPACE); }
- R E S T { yylval.int_info = 10; RETURN(RESERVE_SPACE); }
-
- I N C B I N { RETURN(INCBIN); }
-
- E Q U { RETURN(EQU); }
-
- T I M E S { RETURN(TIMES); }
-
- S E G { RETURN(SEG); }
- W R T { RETURN(WRT); }
-
- N O S P L I T { RETURN(NOSPLIT); }
-
- /* operators */
- "<<" { RETURN(LEFT_OP); }
- ">>" { RETURN(RIGHT_OP); }
- "//" { RETURN(SIGNDIV); }
- "%%" { RETURN(SIGNMOD); }
- "$$" { RETURN(START_SECTION_ID); }
- [-+|^*&/%~$():=,\[] { RETURN(s.tok[0]); }
-
- /* handle ] separately for directives */
- "]" {
- if (state == DIRECTIVE2)
- state = INITIAL;
- RETURN(s.tok[0]);
- }
-
- /* special non-local ..@label and labels like ..start */
- ".." [a-zA-Z0-9_$#@~.?]+ {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(SPECIAL_ID);
- }
-
- /* local label (.label) */
- "." [a-zA-Z0-9_$#@~?][a-zA-Z0-9_$#@~.?]* {
- /* override local labels in directive state */
- if (state == DIRECTIVE2) {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(ID);
- } else if (!nasm_parser_locallabel_base) {
- yasm__warning(YASM_WARN_GENERAL, cur_lindex,
- N_("no non-local label before `%s'"), s.tok[0]);
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- } else {
- len = TOKLEN + nasm_parser_locallabel_base_len;
- yylval.str_val = yasm_xmalloc(len + 1);
- strcpy(yylval.str_val, nasm_parser_locallabel_base);
- strncat(yylval.str_val, s.tok, TOKLEN);
- yylval.str_val[len] = '\0';
- }
-
- RETURN(LOCAL_ID);
- }
-
- /* forced identifier */
- "$" [a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(ID);
- }
-
- /* identifier that may be a register, instruction, etc. */
- [a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- check_id_ret = nasm_parser_arch->parse.check_identifier(
- yylval.arch_data, s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
- switch (check_id_ret) {
- case YASM_ARCH_CHECK_ID_NONE:
- /* Just an identifier, return as such. */
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(ID);
- case YASM_ARCH_CHECK_ID_INSN:
- RETURN(INSN);
- case YASM_ARCH_CHECK_ID_PREFIX:
- RETURN(PREFIX);
- case YASM_ARCH_CHECK_ID_REG:
- RETURN(REG);
- case YASM_ARCH_CHECK_ID_SEGREG:
- RETURN(SEGREG);
- case YASM_ARCH_CHECK_ID_TARGETMOD:
- RETURN(TARGETMOD);
- default:
- yasm__warning(YASM_WARN_GENERAL, cur_lindex,
- N_("Arch feature not supported, treating as identifier"));
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(ID);
- }
- }
-
- ";" (any \ [\n])* { goto scan; }
-
- ws+ { goto scan; }
-
- "\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
- }
-
- any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
- N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
- goto scan;
- }
- */
-
- /* %line linenum+lineinc filename */
-linechg:
- SCANINIT();
-
- /*!re2c
- digit+ {
- linechg_numcount++;
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
- RETURN(INTNUM);
- }
-
- "\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
- }
-
- "+" {
- RETURN(s.tok[0]);
- }
-
- ws+ {
- if (linechg_numcount == 2) {
- state = LINECHG2;
- goto linechg2;
- }
- goto linechg;
- }
-
- any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
- N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
- goto linechg;
- }
- */
-
-linechg2:
- SCANINIT();
-
- /*!re2c
- "\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
- }
-
- "\r" { }
-
- (any \ [\r\n])+ {
- state = LINECHG;
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(FILENAME);
- }
- */
-
- /* directive: [name value] */
-directive:
- SCANINIT();
-
- /*!re2c
- [\]\n] {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
- }
-
- iletter+ {
- state = DIRECTIVE2;
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- RETURN(DIRECTIVE_NAME);
- }
-
- any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
- N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
- goto directive;
- }
- */
-
- /* string/character constant values */
-stringconst:
- strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE);
- strbuf_size = STRBUF_ALLOC_SIZE;
- count = 0;
-
-stringconst_scan:
- SCANINIT();
-
- /*!re2c
- "\n" {
- if (cursor == s.eof)
- yasm__error(cur_lindex,
- N_("unexpected end of file in string"));
- else
- yasm__error(cur_lindex, N_("unterminated string"));
- strbuf[count] = '\0';
- yylval.str_val = strbuf;
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- RETURN(STRING);
- }
-
- any {
- if (s.tok[0] == endch) {
- strbuf[count] = '\0';
- yylval.str_val = strbuf;
- RETURN(STRING);
- }
-
- strbuf[count++] = s.tok[0];
- if (count >= strbuf_size) {
- strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
- strbuf_size += STRBUF_ALLOC_SIZE;
- }
-
- goto stringconst_scan;
- }
- */
-}
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- src/parsers/nasm/tests/nasm_test.sh
-
-EXTRA_DIST += \
- src/parsers/nasm/tests/nasm_test.sh \
- src/parsers/nasm/tests/equlocal.asm \
- src/parsers/nasm/tests/equlocal.errwarn \
- src/parsers/nasm/tests/equlocal.hex \
- src/parsers/nasm/tests/newsect.asm \
- src/parsers/nasm/tests/newsect.errwarn \
- src/parsers/nasm/tests/newsect.hex
+++ /dev/null
-blah
-.local equ 5
-blah2
-db blah.local
-.local
-nonlocal equ 6
-je .local
+++ /dev/null
-05
-74
-fe
+++ /dev/null
-#! /bin/sh
-# $IdPath$
-${srcdir}/out_test.sh nasm_test src/parsers/nasm/tests "nasm-compat parser" "-f bin" ""
-exit $?
+++ /dev/null
-[absolute 0]
-mytype:
-.long resd 1
-mytype_size:
-[section .text]
-lbl:
-..@6.strucstart:
-times mytype.long-($-..@6.strucstart) db 0
-dd 'ABCD'
-times mytype_size-($-..@6.strucstart) db 0
+++ /dev/null
-41
-42
-43
-44
+++ /dev/null
-/* $IdPath$
- * YASM preprocessor module interface header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_PREPROC_H
-#define YASM_PREPROC_H
-
-/* Interface to the preprocesor module(s) */
-struct yasm_preproc {
- /* one-line description of the preprocessor */
- const char *name;
-
- /* keyword used to select preprocessor on the command line */
- const char *keyword;
-
- /* Initializes preprocessor.
- *
- * The preprocessor needs access to the object format module to find out
- * any output format specific macros.
- *
- * This function also takes the FILE * to the initial starting file and
- * the filename.
- */
- void (*initialize) (FILE *f, const char *in_filename, yasm_linemgr *lm);
-
- /* Cleans up any allocated memory. */
- void (*cleanup) (void);
-
- /* Gets more preprocessed source code (up to max_size bytes) into buf.
- * Note that more than a single line may be returned in buf. */
- size_t (*input) (/*@out@*/ char *buf, size_t max_size);
-};
-
-#endif
+++ /dev/null
-# $IdPath$
-
-EXTRA_DIST += \
- src/preprocs/nasm/Makefile.inc \
- src/preprocs/raw/Makefile.inc \
- src/preprocs/yapp/Makefile.inc
-
-include src/preprocs/nasm/Makefile.inc
-include src/preprocs/raw/Makefile.inc
-include src/preprocs/yapp/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-#lib_LTLIBRARIES += yasm-nasm.la
-
-yasm_nasm_la_SOURCES += \
- src/preprocs/nasm/nasm-preproc.c \
- src/preprocs/nasm/nasm-pp.h \
- src/preprocs/nasm/nasm-pp.c \
- src/preprocs/nasm/nasm.h \
- src/preprocs/nasm/nasmlib.h \
- src/preprocs/nasm/nasmlib.c \
- src/preprocs/nasm/nasm-eval.h \
- src/preprocs/nasm/nasm-eval.c
-
-$(top_srcdir)/src/preprocs/nasm/nasm-pp.c: nasm-macros.c
-
-nasm-macros.c: $(top_srcdir)/src/preprocs/nasm/macros.pl $(top_srcdir)/src/preprocs/nasm/standard.mac
- $(PERL) $(top_srcdir)/src/preprocs/nasm/macros.pl $(top_srcdir)/src/preprocs/nasm/standard.mac
-
-BUILT_SOURCES += nasm-macros.c
-CLEANFILES += nasm-macros.c
-
-EXTRA_DIST += src/preprocs/nasm/macros.pl \
- src/preprocs/nasm/standard.mac
-
-#yasm_nasm_la_LDFLAGS = -module -avoid-version
-#yasm_nasm_la_LIBADD = libyasm.la
-#yasm_LDADD += -dlopen yasm-nasm.la
+++ /dev/null
-#!/usr/bin/perl -w
-#
-# macros.pl produce macros.c from standard.mac
-#
-# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-# Julian Hall. All rights reserved. The software is
-# redistributable under the licence given in the file "Licence"
-# distributed in the NASM archive.
-
-use strict;
-
-my $fname;
-my $line = 0;
-my $index = 0;
-my $tasm_count;
-
-undef $tasm_count;
-
-open(OUTPUT,">nasm-macros.c") or die "unable to open nasm-macros.c\n";
-
-print OUTPUT "/* This file auto-generated from standard.mac by macros.pl" .
-" - don't edit it */\n\n#include <stddef.h>\n\nstatic const char *stdmac[] = {\n";
-
-foreach $fname ( @ARGV ) {
- open(INPUT,$fname) or die "unable to open $fname\n";
- while (<INPUT>) {
- $line++;
- chomp;
- if (m/^\s*\*END\*TASM\*MACROS\*\s*$/) {
- $tasm_count = $index;
- } elsif (m/^\s*((\s*([^\"\';\s]+|\"[^\"]*\"|\'[^\']*\'))*)\s*(;.*)?$/) {
- $_ = $1;
- s/\\/\\\\/g;
- s/"/\\"/g;
- if (length > 0) {
- print OUTPUT " \"$_\",\n";
- $index++;
- }
- } else {
- die "$fname:$line: error unterminated quote";
- }
- }
- close(INPUT);
-}
-print OUTPUT " NULL\n};\n";
-$tasm_count = $index unless ( defined($tasm_count) );
-print OUTPUT "#define TASM_MACRO_COUNT $tasm_count\n";
-close(OUTPUT);
+++ /dev/null
-/* eval.c expression evaluator for the Netwide Assembler
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- *
- * initial version 27/iii/95 by Simon Tatham
- */
-#include "util.h"
-#include <ctype.h>
-
-#include "nasm.h"
-#include "nasmlib.h"
-#include "nasm-eval.h"
-/*#include "labels.h"*/
-
-#define TEMPEXPRS_DELTA 128
-#define TEMPEXPR_DELTA 8
-
-static scanner scan; /* Address of scanner routine */
-static efunc error; /* Address of error reporting routine */
-static lfunc labelfunc; /* Address of label routine */
-
-static struct ofmt *outfmt; /* Structure of addresses of output routines */
-
-static nasm_expr **tempexprs = NULL;
-static int ntempexprs;
-static int tempexprs_size = 0;
-
-static nasm_expr *tempexpr;
-static int ntempexpr;
-static int tempexpr_size;
-
-static struct tokenval *tokval; /* The current token */
-static int i; /* The t_type of tokval */
-
-static void *scpriv;
-static loc_t *location; /* Pointer to current line's segment,offset */
-static int *opflags;
-
-static struct eval_hints *hint;
-
-static int in_abs_seg = 0; /* ABSOLUTE segment flag */
-static long abs_seg = 0; /* ABSOLUTE segment */
-static long abs_offset = 0; /* ABSOLUTE segment offset */
-
-/*
- * Unimportant cleanup is done to avoid confusing people who are trying
- * to debug real memory leaks
- */
-void nasm_eval_cleanup(void)
-{
- while (ntempexprs)
- nasm_free (tempexprs[--ntempexprs]);
- nasm_free (tempexprs);
-}
-
-/*
- * Construct a temporary expression.
- */
-static void begintemp(void)
-{
- tempexpr = NULL;
- tempexpr_size = ntempexpr = 0;
-}
-
-static void addtotemp(long type, long value)
-{
- while (ntempexpr >= tempexpr_size) {
- tempexpr_size += TEMPEXPR_DELTA;
- tempexpr = nasm_realloc(tempexpr,
- tempexpr_size*sizeof(*tempexpr));
- }
- tempexpr[ntempexpr].type = type;
- tempexpr[ntempexpr++].value = value;
-}
-
-static nasm_expr *finishtemp(void)
-{
- addtotemp (0L, 0L); /* terminate */
- while (ntempexprs >= tempexprs_size) {
- tempexprs_size += TEMPEXPRS_DELTA;
- tempexprs = nasm_realloc(tempexprs,
- tempexprs_size*sizeof(*tempexprs));
- }
- return tempexprs[ntempexprs++] = tempexpr;
-}
-
-/*
- * Add two vector datatypes. We have some bizarre behaviour on far-
- * absolute segment types: we preserve them during addition _only_
- * if one of the segments is a truly pure scalar.
- */
-static nasm_expr *add_vectors(nasm_expr *p, nasm_expr *q)
-{
- int preserve;
-
- preserve = nasm_is_really_simple(p) || nasm_is_really_simple(q);
-
- begintemp();
-
- while (p->type && q->type &&
- p->type < EXPR_SEGBASE+SEG_ABS &&
- q->type < EXPR_SEGBASE+SEG_ABS)
- {
- int lasttype;
-
- if (p->type > q->type) {
- addtotemp(q->type, q->value);
- lasttype = q++->type;
- } else if (p->type < q->type) {
- addtotemp(p->type, p->value);
- lasttype = p++->type;
- } else { /* *p and *q have same type */
- long sum = p->value + q->value;
- if (sum)
- addtotemp(p->type, sum);
- lasttype = p->type;
- p++, q++;
- }
- if (lasttype == EXPR_UNKNOWN) {
- return finishtemp();
- }
- }
- while (p->type &&
- (preserve || p->type < EXPR_SEGBASE+SEG_ABS))
- {
- addtotemp(p->type, p->value);
- p++;
- }
- while (q->type &&
- (preserve || q->type < EXPR_SEGBASE+SEG_ABS))
- {
- addtotemp(q->type, q->value);
- q++;
- }
-
- return finishtemp();
-}
-
-/*
- * Multiply a vector by a scalar. Strip far-absolute segment part
- * if present.
- *
- * Explicit treatment of UNKNOWN is not required in this routine,
- * since it will silently do the Right Thing anyway.
- *
- * If `affect_hints' is set, we also change the hint type to
- * NOTBASE if a MAKEBASE hint points at a register being
- * multiplied. This allows [eax*1+ebx] to hint EBX rather than EAX
- * as the base register.
- */
-static nasm_expr *scalar_mult(nasm_expr *vect, long scalar, int affect_hints)
-{
- nasm_expr *p = vect;
-
- while (p->type && p->type < EXPR_SEGBASE+SEG_ABS) {
- p->value = scalar * (p->value);
- if (hint && hint->type == EAH_MAKEBASE &&
- p->type == hint->base && affect_hints)
- hint->type = EAH_NOTBASE;
- p++;
- }
- p->type = 0;
-
- return vect;
-}
-
-static nasm_expr *scalarvect (long scalar)
-{
- begintemp();
- addtotemp(EXPR_SIMPLE, scalar);
- return finishtemp();
-}
-
-static nasm_expr *unknown_expr (void)
-{
- begintemp();
- addtotemp(EXPR_UNKNOWN, 1L);
- return finishtemp();
-}
-
-/*
- * The SEG operator: calculate the segment part of a relocatable
- * value. Return NULL, as usual, if an error occurs. Report the
- * error too.
- */
-static nasm_expr *segment_part (nasm_expr *e)
-{
- long seg;
-
- if (nasm_is_unknown(e))
- return unknown_expr();
-
- if (!nasm_is_reloc(e)) {
- error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value");
- return NULL;
- }
-
- seg = nasm_reloc_seg(e);
- if (seg == NO_SEG) {
- error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value");
- return NULL;
- } else if (seg & SEG_ABS) {
- return scalarvect(seg & ~SEG_ABS);
- } else if (seg & 1) {
- error(ERR_NONFATAL, "SEG applied to something which"
- " is already a segment base");
- return NULL;
- }
- else {
- long base = outfmt->segbase(seg+1);
-
- begintemp();
- addtotemp((base == NO_SEG ? EXPR_UNKNOWN : EXPR_SEGBASE+base), 1L);
- return finishtemp();
- }
-}
-
-/*
- * Recursive-descent parser. Called with a single boolean operand,
- * which is TRUE if the evaluation is critical (i.e. unresolved
- * symbols are an error condition). Must update the global `i' to
- * reflect the token after the parsed string. May return NULL.
- *
- * evaluate() should report its own errors: on return it is assumed
- * that if NULL has been returned, the error has already been
- * reported.
- */
-
-/*
- * Grammar parsed is:
- *
- * expr : bexpr [ WRT expr6 ]
- * bexpr : rexp0 or expr0 depending on relative-mode setting
- * rexp0 : rexp1 [ {||} rexp1...]
- * rexp1 : rexp2 [ {^^} rexp2...]
- * rexp2 : rexp3 [ {&&} rexp3...]
- * rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=} expr0 ]
- * expr0 : expr1 [ {|} expr1...]
- * expr1 : expr2 [ {^} expr2...]
- * expr2 : expr3 [ {&} expr3...]
- * expr3 : expr4 [ {<<,>>} expr4...]
- * expr4 : expr5 [ {+,-} expr5...]
- * expr5 : expr6 [ {*,/,%,//,%%} expr6...]
- * expr6 : { ~,+,-,SEG } expr6
- * | (bexpr)
- * | symbol
- * | $
- * | number
- */
-
-static nasm_expr *rexp0(int), *rexp1(int), *rexp2(int), *rexp3(int);
-
-static nasm_expr *expr0(int), *expr1(int), *expr2(int), *expr3(int);
-static nasm_expr *expr4(int), *expr5(int), *expr6(int);
-
-static nasm_expr *(*bexpr)(int);
-
-static nasm_expr *rexp0(int critical)
-{
- nasm_expr *e, *f;
-
- e = rexp1(critical);
- if (!e)
- return NULL;
-
- while (i == TOKEN_DBL_OR)
- {
- i = scan(scpriv, tokval);
- f = rexp1(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`|' operator may only be applied to"
- " scalar values");
- }
-
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect ((long) (nasm_reloc_value(e) || nasm_reloc_value(f)));
- }
- return e;
-}
-
-static nasm_expr *rexp1(int critical)
-{
- nasm_expr *e, *f;
-
- e = rexp2(critical);
- if (!e)
- return NULL;
-
- while (i == TOKEN_DBL_XOR)
- {
- i = scan(scpriv, tokval);
- f = rexp2(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`^' operator may only be applied to"
- " scalar values");
- }
-
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect ((long) (!nasm_reloc_value(e) ^ !nasm_reloc_value(f)));
- }
- return e;
-}
-
-static nasm_expr *rexp2(int critical)
-{
- nasm_expr *e, *f;
-
- e = rexp3(critical);
- if (!e)
- return NULL;
- while (i == TOKEN_DBL_AND)
- {
- i = scan(scpriv, tokval);
- f = rexp3(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`&' operator may only be applied to"
- " scalar values");
- }
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect ((long) (nasm_reloc_value(e) && nasm_reloc_value(f)));
- }
- return e;
-}
-
-static nasm_expr *rexp3(int critical)
-{
- nasm_expr *e, *f;
- long v;
-
- e = expr0(critical);
- if (!e)
- return NULL;
-
- while (i == TOKEN_EQ || i == TOKEN_LT || i == TOKEN_GT ||
- i == TOKEN_NE || i == TOKEN_LE || i == TOKEN_GE)
- {
- int j = i;
- i = scan(scpriv, tokval);
- f = expr0(critical);
- if (!f)
- return NULL;
-
- e = add_vectors (e, scalar_mult(f, -1L, FALSE));
-
- switch (j)
- {
- case TOKEN_EQ: case TOKEN_NE:
- if (nasm_is_unknown(e))
- v = -1; /* means unknown */
- else if (!nasm_is_really_simple(e) || nasm_reloc_value(e) != 0)
- v = (j == TOKEN_NE); /* unequal, so return TRUE if NE */
- else
- v = (j == TOKEN_EQ); /* equal, so return TRUE if EQ */
- break;
- default:
- if (nasm_is_unknown(e))
- v = -1; /* means unknown */
- else if (!nasm_is_really_simple(e)) {
- error(ERR_NONFATAL, "`%s': operands differ by a non-scalar",
- (j == TOKEN_LE ? "<=" : j == TOKEN_LT ? "<" :
- j == TOKEN_GE ? ">=" : ">"));
- v = 0; /* must set it to _something_ */
- } else {
- int vv = nasm_reloc_value(e);
- if (vv == 0)
- v = (j == TOKEN_LE || j == TOKEN_GE);
- else if (vv > 0)
- v = (j == TOKEN_GE || j == TOKEN_GT);
- else /* vv < 0 */
- v = (j == TOKEN_LE || j == TOKEN_LT);
- }
- break;
- }
-
- if (v == -1)
- e = unknown_expr();
- else
- e = scalarvect(v);
- }
- return e;
-}
-
-static nasm_expr *expr0(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr1(critical);
- if (!e)
- return NULL;
-
- while (i == '|')
- {
- i = scan(scpriv, tokval);
- f = expr1(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`|' operator may only be applied to"
- " scalar values");
- }
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (nasm_reloc_value(e) | nasm_reloc_value(f));
- }
- return e;
-}
-
-static nasm_expr *expr1(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr2(critical);
- if (!e)
- return NULL;
-
- while (i == '^') {
- i = scan(scpriv, tokval);
- f = expr2(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`^' operator may only be applied to"
- " scalar values");
- }
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (nasm_reloc_value(e) ^ nasm_reloc_value(f));
- }
- return e;
-}
-
-static nasm_expr *expr2(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr3(critical);
- if (!e)
- return NULL;
-
- while (i == '&') {
- i = scan(scpriv, tokval);
- f = expr3(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "`&' operator may only be applied to"
- " scalar values");
- }
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (nasm_reloc_value(e) & nasm_reloc_value(f));
- }
- return e;
-}
-
-static nasm_expr *expr3(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr4(critical);
- if (!e)
- return NULL;
-
- while (i == TOKEN_SHL || i == TOKEN_SHR)
- {
- int j = i;
- i = scan(scpriv, tokval);
- f = expr4(critical);
- if (!f)
- return NULL;
- if (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f)))
- {
- error(ERR_NONFATAL, "shift operator may only be applied to"
- " scalar values");
- } else if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f)) {
- e = unknown_expr();
- } else switch (j) {
- case TOKEN_SHL:
- e = scalarvect (nasm_reloc_value(e) << nasm_reloc_value(f));
- break;
- case TOKEN_SHR:
- e = scalarvect (((unsigned long)nasm_reloc_value(e)) >>
- nasm_reloc_value(f));
- break;
- }
- }
- return e;
-}
-
-static nasm_expr *expr4(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr5(critical);
- if (!e)
- return NULL;
- while (i == '+' || i == '-')
- {
- int j = i;
- i = scan(scpriv, tokval);
- f = expr5(critical);
- if (!f)
- return NULL;
- switch (j) {
- case '+':
- e = add_vectors (e, f);
- break;
- case '-':
- e = add_vectors (e, scalar_mult(f, -1L, FALSE));
- break;
- }
- }
- return e;
-}
-
-static nasm_expr *expr5(int critical)
-{
- nasm_expr *e, *f;
-
- e = expr6(critical);
- if (!e)
- return NULL;
- while (i == '*' || i == '/' || i == '%' ||
- i == TOKEN_SDIV || i == TOKEN_SMOD)
- {
- int j = i;
- i = scan(scpriv, tokval);
- f = expr6(critical);
- if (!f)
- return NULL;
- if (j != '*' && (!(nasm_is_simple(e) || nasm_is_just_unknown(e)) ||
- !(nasm_is_simple(f) || nasm_is_just_unknown(f))))
- {
- error(ERR_NONFATAL, "division operator may only be applied to"
- " scalar values");
- return NULL;
- }
- if (j != '*' && !nasm_is_unknown(f) && nasm_reloc_value(f) == 0) {
- error(ERR_NONFATAL, "division by zero");
- return NULL;
- }
- switch (j) {
- case '*':
- if (nasm_is_simple(e))
- e = scalar_mult (f, nasm_reloc_value(e), TRUE);
- else if (nasm_is_simple(f))
- e = scalar_mult (e, nasm_reloc_value(f), TRUE);
- else if (nasm_is_just_unknown(e) && nasm_is_just_unknown(f))
- e = unknown_expr();
- else {
- error(ERR_NONFATAL, "unable to multiply two "
- "non-scalar objects");
- return NULL;
- }
- break;
- case '/':
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (((unsigned long)nasm_reloc_value(e)) /
- ((unsigned long)nasm_reloc_value(f)));
- break;
- case '%':
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (((unsigned long)nasm_reloc_value(e)) %
- ((unsigned long)nasm_reloc_value(f)));
- break;
- case TOKEN_SDIV:
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (((signed long)nasm_reloc_value(e)) /
- ((signed long)nasm_reloc_value(f)));
- break;
- case TOKEN_SMOD:
- if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
- e = unknown_expr();
- else
- e = scalarvect (((signed long)nasm_reloc_value(e)) %
- ((signed long)nasm_reloc_value(f)));
- break;
- }
- }
- return e;
-}
-
-static nasm_expr *expr6(int critical)
-{
- long type;
- nasm_expr *e;
- long label_seg, label_ofs;
-
- if (i == '-') {
- i = scan(scpriv, tokval);
- e = expr6(critical);
- if (!e)
- return NULL;
- return scalar_mult (e, -1L, FALSE);
- } else if (i == '+') {
- i = scan(scpriv, tokval);
- return expr6(critical);
- } else if (i == '~') {
- i = scan(scpriv, tokval);
- e = expr6(critical);
- if (!e)
- return NULL;
- if (nasm_is_just_unknown(e))
- return unknown_expr();
- else if (!nasm_is_simple(e)) {
- error(ERR_NONFATAL, "`~' operator may only be applied to"
- " scalar values");
- return NULL;
- }
- return scalarvect(~nasm_reloc_value(e));
- } else if (i == TOKEN_SEG) {
- i = scan(scpriv, tokval);
- e = expr6(critical);
- if (!e)
- return NULL;
- e = segment_part(e);
- if (!e)
- return NULL;
- if (nasm_is_unknown(e) && critical) {
- error(ERR_NONFATAL, "unable to determine segment base");
- return NULL;
- }
- return e;
- } else if (i == '(') {
- i = scan(scpriv, tokval);
- e = bexpr(critical);
- if (!e)
- return NULL;
- if (i != ')') {
- error(ERR_NONFATAL, "expecting `)'");
- return NULL;
- }
- i = scan(scpriv, tokval);
- return e;
- }
- else if (i == TOKEN_NUM || i == TOKEN_REG || i == TOKEN_ID ||
- i == TOKEN_HERE || i == TOKEN_BASE)
- {
- begintemp();
- switch (i) {
- case TOKEN_NUM:
- addtotemp(EXPR_SIMPLE, tokval->t_integer);
- break;
- case TOKEN_REG:
- addtotemp(tokval->t_integer, 1L);
- if (hint && hint->type == EAH_NOHINT)
- hint->base = tokval->t_integer, hint->type = EAH_MAKEBASE;
- break;
- case TOKEN_ID:
- case TOKEN_HERE:
- case TOKEN_BASE:
- /*
- * If !location->known, this indicates that no
- * symbol, Here or Base references are valid because we
- * are in preprocess-only mode.
- */
- if (!location->known) {
- error(ERR_NONFATAL,
- "%s not supported in preprocess-only mode",
- (i == TOKEN_ID ? "symbol references" :
- i == TOKEN_HERE ? "`$'" : "`$$'"));
- addtotemp(EXPR_UNKNOWN, 1L);
- break;
- }
-
- type = EXPR_SIMPLE; /* might get overridden by UNKNOWN */
- if (i == TOKEN_BASE)
- {
- label_seg = in_abs_seg ? abs_seg : location->segment;
- label_ofs = 0;
- } else if (i == TOKEN_HERE) {
- label_seg = in_abs_seg ? abs_seg : location->segment;
- label_ofs = in_abs_seg ? abs_offset : location->offset;
- } else {
- if (!labelfunc(tokval->t_charptr,&label_seg,&label_ofs))
- {
- if (critical == 2) {
- error (ERR_NONFATAL, "symbol `%s' undefined",
- tokval->t_charptr);
- return NULL;
- } else if (critical == 1) {
- error (ERR_NONFATAL,
- "symbol `%s' not defined before use",
- tokval->t_charptr);
- return NULL;
- } else {
- if (opflags)
- *opflags |= 1;
- type = EXPR_UNKNOWN;
- label_seg = NO_SEG;
- label_ofs = 1;
- }
- }
-#if 0
- if (opflags && nasm_is_extern (tokval->t_charptr))
- *opflags |= OPFLAG_EXTERN;
-#endif
- }
- addtotemp(type, label_ofs);
- if (label_seg!=NO_SEG)
- addtotemp(EXPR_SEGBASE + label_seg, 1L);
- break;
- }
- i = scan(scpriv, tokval);
- return finishtemp();
- } else {
- error(ERR_NONFATAL, "expression syntax error");
- return NULL;
- }
-}
-
-void nasm_eval_global_info (struct ofmt *output, lfunc lookup_label, loc_t *locp)
-{
- outfmt = output;
- labelfunc = lookup_label;
- location = locp;
-}
-
-nasm_expr *nasm_evaluate (scanner sc, void *scprivate, struct tokenval *tv,
- int *fwref, int critical, efunc report_error,
- struct eval_hints *hints)
-{
- nasm_expr *e;
- nasm_expr *f = NULL;
-
- hint = hints;
- if (hint)
- hint->type = EAH_NOHINT;
-
- if (critical & CRITICAL) {
- critical &= ~CRITICAL;
- bexpr = rexp0;
- } else
- bexpr = expr0;
-
- scan = sc;
- scpriv = scprivate;
- tokval = tv;
- error = report_error;
- opflags = fwref;
-
- if (tokval->t_type == TOKEN_INVALID)
- i = scan(scpriv, tokval);
- else
- i = tokval->t_type;
-
- while (ntempexprs) /* initialise temporary storage */
- nasm_free (tempexprs[--ntempexprs]);
-
- e = bexpr (critical);
- if (!e)
- return NULL;
-
- if (i == TOKEN_WRT) {
- i = scan(scpriv, tokval); /* eat the WRT */
- f = expr6 (critical);
- if (!f)
- return NULL;
- }
- e = scalar_mult (e, 1L, FALSE); /* strip far-absolute segment part */
- if (f) {
- nasm_expr *g;
- if (nasm_is_just_unknown(f))
- g = unknown_expr();
- else {
- long value;
- begintemp();
- if (!nasm_is_reloc(f)) {
- error(ERR_NONFATAL, "invalid right-hand operand to WRT");
- return NULL;
- }
- value = nasm_reloc_seg(f);
- if (value == NO_SEG)
- value = nasm_reloc_value(f) | SEG_ABS;
- else if (!(value & SEG_ABS) && !(value % 2) && critical)
- {
- error(ERR_NONFATAL, "invalid right-hand operand to WRT");
- return NULL;
- }
- addtotemp(EXPR_WRT, value);
- g = finishtemp();
- }
- e = add_vectors (e, g);
- }
- return e;
-}
+++ /dev/null
-/* eval.h header file for eval.c
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-
-#ifndef NASM_EVAL_H
-#define NASM_EVAL_H
-
-/*
- * Called once to tell the evaluator what output format is
- * providing segment-base details, and what function can be used to
- * look labels up.
- */
-void nasm_eval_global_info (struct ofmt *output, lfunc lookup_label, loc_t *locp);
-
-/*
- * The evaluator itself.
- */
-nasm_expr *nasm_evaluate (scanner sc, void *scprivate, struct tokenval *tv,
- int *fwref, int critical, efunc report_error,
- struct eval_hints *hints);
-
-void nasm_eval_cleanup(void);
-
-#endif
+++ /dev/null
-/* -*- mode: c; c-file-style: "bsd" -*- */
-/* preproc.c macro preprocessor for the Netwide Assembler
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- *
- * initial version 18/iii/97 by Simon Tatham
- */
-
-/* Typical flow of text through preproc
- *
- * pp_getline gets tokenised lines, either
- *
- * from a macro expansion
- *
- * or
- * {
- * read_line gets raw text from stdmacpos, or predef, or current input file
- * tokenise converts to tokens
- * }
- *
- * expand_mmac_params is used to expand %1 etc., unless a macro is being
- * defined or a false conditional is being processed
- * (%0, %1, %+1, %-1, %%foo
- *
- * do_directive checks for directives
- *
- * expand_smacro is used to expand single line macros
- *
- * expand_mmacro is used to expand multi-line macros
- *
- * detoken is used to convert the line back to text
- */
-#include "util.h"
-#include <stdarg.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "nasm.h"
-#include "nasmlib.h"
-#include "nasm-pp.h"
-
-typedef struct SMacro SMacro;
-typedef struct MMacro MMacro;
-typedef struct Context Context;
-typedef struct Token Token;
-typedef struct Blocks Blocks;
-typedef struct Line Line;
-typedef struct Include Include;
-typedef struct Cond Cond;
-typedef struct IncPath IncPath;
-
-/*
- * Store the definition of a single-line macro.
- */
-struct SMacro
-{
- SMacro *next;
- char *name;
- int casesense;
- int nparam;
- int in_progress;
- Token *expansion;
-};
-
-/*
- * Store the definition of a multi-line macro. This is also used to
- * store the interiors of `%rep...%endrep' blocks, which are
- * effectively self-re-invoking multi-line macros which simply
- * don't have a name or bother to appear in the hash tables. %rep
- * blocks are signified by having a NULL `name' field.
- *
- * In a MMacro describing a `%rep' block, the `in_progress' field
- * isn't merely boolean, but gives the number of repeats left to
- * run.
- *
- * The `next' field is used for storing MMacros in hash tables; the
- * `next_active' field is for stacking them on istk entries.
- *
- * When a MMacro is being expanded, `params', `iline', `nparam',
- * `paramlen', `rotate' and `unique' are local to the invocation.
- */
-struct MMacro
-{
- MMacro *next;
- char *name;
- int casesense;
- int nparam_min, nparam_max;
- int plus; /* is the last parameter greedy? */
- int nolist; /* is this macro listing-inhibited? */
- int in_progress;
- Token *dlist; /* All defaults as one list */
- Token **defaults; /* Parameter default pointers */
- int ndefs; /* number of default parameters */
- Line *expansion;
-
- MMacro *next_active;
- MMacro *rep_nest; /* used for nesting %rep */
- Token **params; /* actual parameters */
- Token *iline; /* invocation line */
- int nparam, rotate, *paramlen;
- unsigned long unique;
- int lineno; /* Current line number on expansion */
-};
-
-/*
- * The context stack is composed of a linked list of these.
- */
-struct Context
-{
- Context *next;
- SMacro *localmac;
- char *name;
- unsigned long number;
-};
-
-/*
- * This is the internal form which we break input lines up into.
- * Typically stored in linked lists.
- *
- * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not
- * necessarily used as-is, but is intended to denote the number of
- * the substituted parameter. So in the definition
- *
- * %define a(x,y) ( (x) & ~(y) )
- *
- * the token representing `x' will have its type changed to
- * TOK_SMAC_PARAM, but the one representing `y' will be
- * TOK_SMAC_PARAM+1.
- *
- * TOK_INTERNAL_STRING is a dirty hack: it's a single string token
- * which doesn't need quotes around it. Used in the pre-include
- * mechanism as an alternative to trying to find a sensible type of
- * quote to use on the filename we were passed.
- */
-struct Token
-{
- Token *next;
- char *text;
- SMacro *mac; /* associated macro for TOK_SMAC_END */
- int type;
-};
-enum
-{
- TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
- TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
- TOK_INTERNAL_STRING
-};
-
-/*
- * Multi-line macro definitions are stored as a linked list of
- * these, which is essentially a container to allow several linked
- * lists of Tokens.
- *
- * Note that in this module, linked lists are treated as stacks
- * wherever possible. For this reason, Lines are _pushed_ on to the
- * `expansion' field in MMacro structures, so that the linked list,
- * if walked, would give the macro lines in reverse order; this
- * means that we can walk the list when expanding a macro, and thus
- * push the lines on to the `expansion' field in _istk_ in reverse
- * order (so that when popped back off they are in the right
- * order). It may seem cockeyed, and it relies on my design having
- * an even number of steps in, but it works...
- *
- * Some of these structures, rather than being actual lines, are
- * markers delimiting the end of the expansion of a given macro.
- * This is for use in the cycle-tracking and %rep-handling code.
- * Such structures have `finishes' non-NULL, and `first' NULL. All
- * others have `finishes' NULL, but `first' may still be NULL if
- * the line is blank.
- */
-struct Line
-{
- Line *next;
- MMacro *finishes;
- Token *first;
-};
-
-/*
- * To handle an arbitrary level of file inclusion, we maintain a
- * stack (ie linked list) of these things.
- */
-struct Include
-{
- Include *next;
- FILE *fp;
- Cond *conds;
- Line *expansion;
- char *fname;
- int lineno, lineinc;
- MMacro *mstk; /* stack of active macros/reps */
-};
-
-/*
- * Include search path. This is simply a list of strings which get
- * prepended, in turn, to the name of an include file, in an
- * attempt to find the file if it's not in the current directory.
- */
-struct IncPath
-{
- IncPath *next;
- char *path;
-};
-
-/*
- * Conditional assembly: we maintain a separate stack of these for
- * each level of file inclusion. (The only reason we keep the
- * stacks separate is to ensure that a stray `%endif' in a file
- * included from within the true branch of a `%if' won't terminate
- * it and cause confusion: instead, rightly, it'll cause an error.)
- */
-struct Cond
-{
- Cond *next;
- int state;
-};
-enum
-{
- /*
- * These states are for use just after %if or %elif: IF_TRUE
- * means the condition has evaluated to truth so we are
- * currently emitting, whereas IF_FALSE means we are not
- * currently emitting but will start doing so if a %else comes
- * up. In these states, all directives are admissible: %elif,
- * %else and %endif. (And of course %if.)
- */
- COND_IF_TRUE, COND_IF_FALSE,
- /*
- * These states come up after a %else: ELSE_TRUE means we're
- * emitting, and ELSE_FALSE means we're not. In ELSE_* states,
- * any %elif or %else will cause an error.
- */
- COND_ELSE_TRUE, COND_ELSE_FALSE,
- /*
- * This state means that we're not emitting now, and also that
- * nothing until %endif will be emitted at all. It's for use in
- * two circumstances: (i) when we've had our moment of emission
- * and have now started seeing %elifs, and (ii) when the
- * condition construct in question is contained within a
- * non-emitting branch of a larger condition construct.
- */
- COND_NEVER
-};
-#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
-
-/*
- * These defines are used as the possible return values for do_directive
- */
-#define NO_DIRECTIVE_FOUND 0
-#define DIRECTIVE_FOUND 1
-
-/*
- * Condition codes. Note that we use c_ prefix not C_ because C_ is
- * used in nasm.h for the "real" condition codes. At _this_ level,
- * we treat CXZ and ECXZ as condition codes, albeit non-invertible
- * ones, so we need a different enum...
- */
-static const char *conditions[] = {
- "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le",
- "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
- "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
-};
-enum
-{
- c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE,
- c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO,
- c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_S, c_Z
-};
-static int inverse_ccs[] = {
- c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE,
- c_A, c_AE, c_B, c_BE, c_C, c_E, c_G, c_GE, c_L, c_LE, c_O, c_P, c_S,
- c_Z, c_NO, c_NP, c_PO, c_PE, c_NS, c_NZ
-};
-
-/*
- * Directive names.
- */
-static const char *directives[] = {
- "%arg",
- "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
- "%elifid", "%elifidn", "%elifidni", "%elifmacro", "%elifnctx", "%elifndef",
- "%elifnid", "%elifnidn", "%elifnidni", "%elifnmacro", "%elifnnum", "%elifnstr",
- "%elifnum", "%elifstr", "%else", "%endif", "%endm", "%endmacro",
- "%endrep", "%error", "%exitrep", "%iassign", "%idefine", "%if",
- "%ifctx", "%ifdef", "%ifid", "%ifidn", "%ifidni", "%ifmacro", "%ifnctx",
- "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnmacro", "%ifnnum",
- "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
- "%ixdefine", "%line",
- "%local",
- "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
- "%stacksize",
- "%strlen", "%substr", "%undef", "%xdefine"
-};
-enum
-{
- PP_ARG,
- PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
- PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFMACRO, PP_ELIFNCTX, PP_ELIFNDEF,
- PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNMACRO, PP_ELIFNNUM, PP_ELIFNSTR,
- PP_ELIFNUM, PP_ELIFSTR, PP_ELSE, PP_ENDIF, PP_ENDM, PP_ENDMACRO,
- PP_ENDREP, PP_ERROR, PP_EXITREP, PP_IASSIGN, PP_IDEFINE, PP_IF,
- PP_IFCTX, PP_IFDEF, PP_IFID, PP_IFIDN, PP_IFIDNI, PP_IFMACRO, PP_IFNCTX,
- PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNMACRO, PP_IFNNUM,
- PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
- PP_IXDEFINE, PP_LINE,
- PP_LOCAL,
- PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
- PP_STACKSIZE,
- PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
-};
-
-/* If this is a an IF, ELIF, ELSE or ENDIF keyword */
-static int is_condition(int arg)
-{
- return ((arg >= PP_ELIF) && (arg <= PP_ENDIF)) ||
- ((arg >= PP_IF) && (arg <= PP_IFSTR));
-}
-
-/* For TASM compatibility we need to be able to recognise TASM compatible
- * conditional compilation directives. Using the NASM pre-processor does
- * not work, so we look for them specifically from the following list and
- * then jam in the equivalent NASM directive into the input stream.
- */
-
-#ifndef MAX
-# define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
-#endif
-
-enum
-{
- TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
- TM_IFNDEF, TM_INCLUDE, TM_LOCAL
-};
-
-static const char *tasm_directives[] = {
- "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi",
- "ifndef", "include", "local"
-};
-
-static int StackSize = 4;
-static const char *StackPointer = "ebp";
-static int ArgOffset = 8;
-static int LocalOffset = 4;
-
-
-static Context *cstk;
-static Include *istk;
-static IncPath *ipath = NULL;
-
-static efunc _error; /* Pointer to client-provided error reporting function */
-static evalfunc evaluate;
-
-static int pass; /* HACK: pass 0 = generate dependencies only */
-
-static unsigned long unique; /* unique identifier numbers */
-
-static Line *predef = NULL;
-
-static ListGen *list;
-
-/*
- * The number of hash values we use for the macro lookup tables.
- * FIXME: We should *really* be able to configure this at run time,
- * or even have the hash table automatically expanding when necessary.
- */
-#define NHASH 31
-
-/*
- * The current set of multi-line macros we have defined.
- */
-static MMacro *mmacros[NHASH];
-
-/*
- * The current set of single-line macros we have defined.
- */
-static SMacro *smacros[NHASH];
-
-/*
- * The multi-line macro we are currently defining, or the %rep
- * block we are currently reading, if any.
- */
-static MMacro *defining;
-
-/*
- * The number of macro parameters to allocate space for at a time.
- */
-#define PARAM_DELTA 16
-
-/*
- * The standard macro set: defined as `static char *stdmac[]'. Also
- * gives our position in the macro set, when we're processing it.
- */
-#include "nasm-macros.c"
-static const char **stdmacpos;
-
-/*
- * The extra standard macros that come from the object format, if
- * any.
- */
-static const char **extrastdmac = NULL;
-int any_extrastdmac;
-
-/*
- * Tokens are allocated in blocks to improve speed
- */
-#define TOKEN_BLOCKSIZE 4096
-static Token *freeTokens = NULL;
-struct Blocks {
- Blocks *next;
- void *chunk;
-};
-
-static Blocks blocks = { NULL, NULL };
-
-/*
- * Forward declarations.
- */
-static Token *expand_mmac_params(Token * tline);
-static Token *expand_smacro(Token * tline);
-static Token *expand_id(Token * tline);
-static Context *get_ctx(char *name, int all_contexts);
-static void make_tok_num(Token * tok, long val);
-static void error(int severity, const char *fmt, ...);
-static void *new_Block(size_t size);
-static void delete_Blocks(void);
-static Token *new_Token(Token * next, int type, const char *text, int txtlen);
-static Token *delete_Token(Token * t);
-
-/*
- * Macros for safe checking of token pointers, avoid *(NULL)
- */
-#define tok_type_(x,t) ((x) && (x)->type == (t))
-#define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next
-#define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v)))
-#define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v))))
-
-/* Handle TASM specific directives, which do not contain a % in
- * front of them. We do it here because I could not find any other
- * place to do it for the moment, and it is a hack (ideally it would
- * be nice to be able to use the NASM pre-processor to do it).
- */
-static char *
-check_tasm_directive(char *line)
-{
- int i, j, k, m, len;
- char *p = line, *oldline, oldchar;
-
- /* Skip whitespace */
- while (isspace(*p) && *p != 0)
- p++;
-
- /* Binary search for the directive name */
- i = -1;
- j = elements(tasm_directives);
- len = 0;
- while (!isspace(p[len]) && p[len] != 0)
- len++;
- if (len)
- {
- oldchar = p[len];
- p[len] = 0;
- while (j - i > 1)
- {
- k = (j + i) / 2;
- m = nasm_stricmp(p, tasm_directives[k]);
- if (m == 0)
- {
- /* We have found a directive, so jam a % in front of it
- * so that NASM will then recognise it as one if it's own.
- */
- p[len] = oldchar;
- len = strlen(p);
- oldline = line;
- line = nasm_malloc(len + 2);
- line[0] = '%';
- if (k == TM_IFDIFI)
- {
- /* NASM does not recognise IFDIFI, so we convert it to
- * %ifdef BOGUS. This is not used in NASM comaptible
- * code, but does need to parse for the TASM macro
- * package.
- */
- strcpy(line + 1, "ifdef BOGUS");
- }
- else
- {
- memcpy(line + 1, p, len + 1);
- }
- nasm_free(oldline);
- return line;
- }
- else if (m < 0)
- {
- j = k;
- }
- else
- i = k;
- }
- p[len] = oldchar;
- }
- return line;
-}
-
-/*
- * The pre-preprocessing stage... This function translates line
- * number indications as they emerge from GNU cpp (`# lineno "file"
- * flags') into NASM preprocessor line number indications (`%line
- * lineno file').
- */
-static char *
-prepreproc(char *line)
-{
- int lineno, fnlen;
- char *fname, *oldline;
-
- if (line[0] == '#' && line[1] == ' ')
- {
- oldline = line;
- fname = oldline + 2;
- lineno = atoi(fname);
- fname += strspn(fname, "0123456789 ");
- if (*fname == '"')
- fname++;
- fnlen = strcspn(fname, "\"");
- line = nasm_malloc(20 + fnlen);
- sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
- nasm_free(oldline);
- }
- if (tasm_compatible_mode)
- return check_tasm_directive(line);
- return line;
-}
-
-/*
- * The hash function for macro lookups. Note that due to some
- * macros having case-insensitive names, the hash function must be
- * invariant under case changes. We implement this by applying a
- * perfectly normal hash function to the uppercase of the string.
- */
-static int
-hash(char *s)
-{
- unsigned int h = 0;
- int i = 0;
- /*
- * Powers of three, mod 31.
- */
- static const int multipliers[] = {
- 1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10,
- 30, 28, 22, 4, 12, 5, 15, 14, 11, 2, 6, 18, 23, 7, 21
- };
-
-
- while (*s)
- {
- h += multipliers[i] * (unsigned char) (toupper(*s));
- s++;
- if (++i >= elements(multipliers))
- i = 0;
- }
- h %= NHASH;
- return h;
-}
-
-/*
- * Free a linked list of tokens.
- */
-static void
-free_tlist(Token * list_)
-{
- while (list_)
- {
- list_ = delete_Token(list_);
- }
-}
-
-/*
- * Free a linked list of lines.
- */
-static void
-free_llist(Line * list_)
-{
- Line *l;
- while (list_)
- {
- l = list_;
- list_ = list_->next;
- free_tlist(l->first);
- nasm_free(l);
- }
-}
-
-/*
- * Free an MMacro
- */
-static void
-free_mmacro(MMacro * m)
-{
- nasm_free(m->name);
- free_tlist(m->dlist);
- nasm_free(m->defaults);
- free_llist(m->expansion);
- nasm_free(m);
-}
-
-/*
- * Pop the context stack.
- */
-static void
-ctx_pop(void)
-{
- Context *c = cstk;
- SMacro *smac, *s;
-
- cstk = cstk->next;
- smac = c->localmac;
- while (smac)
- {
- s = smac;
- smac = smac->next;
- nasm_free(s->name);
- free_tlist(s->expansion);
- nasm_free(s);
- }
- nasm_free(c->name);
- nasm_free(c);
-}
-
-#define BUF_DELTA 512
-/*
- * Read a line from the top file in istk, handling multiple CR/LFs
- * at the end of the line read, and handling spurious ^Zs. Will
- * return lines from the standard macro set if this has not already
- * been done.
- */
-static char *
-read_line(void)
-{
- char *buffer, *p, *q;
- int bufsize, continued_count;
-
- if (stdmacpos)
- {
- if (*stdmacpos)
- {
- char *ret = nasm_strdup(*stdmacpos++);
- if (!*stdmacpos && any_extrastdmac)
- {
- stdmacpos = extrastdmac;
- any_extrastdmac = FALSE;
- return ret;
- }
- /*
- * Nasty hack: here we push the contents of `predef' on
- * to the top-level expansion stack, since this is the
- * most convenient way to implement the pre-include and
- * pre-define features.
- */
- if (!*stdmacpos)
- {
- Line *pd, *l;
- Token *head, **tail, *t;
-
- for (pd = predef; pd; pd = pd->next)
- {
- head = NULL;
- tail = &head;
- for (t = pd->first; t; t = t->next)
- {
- *tail = new_Token(NULL, t->type, t->text, 0);
- tail = &(*tail)->next;
- }
- l = nasm_malloc(sizeof(Line));
- l->next = istk->expansion;
- l->first = head;
- l->finishes = FALSE;
- istk->expansion = l;
- }
- }
- return ret;
- }
- else
- {
- stdmacpos = NULL;
- }
- }
-
- bufsize = BUF_DELTA;
- buffer = nasm_malloc(BUF_DELTA);
- p = buffer;
- continued_count = 0;
- while (1)
- {
- q = fgets(p, bufsize - (p - buffer), istk->fp);
- if (!q)
- break;
- p += strlen(p);
- if (p > buffer && p[-1] == '\n')
- {
- /* Convert backslash-CRLF line continuation sequences into
- nothing at all (for DOS and Windows) */
- if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
- p -= 3;
- *p = 0;
- continued_count++;
- }
- /* Also convert backslash-LF line continuation sequences into
- nothing at all (for Unix) */
- else if (((p - 1) > buffer) && (p[-2] == '\\')) {
- p -= 2;
- *p = 0;
- continued_count++;
- }
- else {
- break;
- }
- }
- if (p - buffer > bufsize - 10)
- {
- long offset = p - buffer;
- bufsize += BUF_DELTA;
- buffer = nasm_realloc(buffer, bufsize);
- p = buffer + offset; /* prevent stale-pointer problems */
- }
- }
-
- if (!q && p == buffer)
- {
- nasm_free(buffer);
- return NULL;
- }
-
- nasm_src_set_linnum(nasm_src_get_linnum() + istk->lineinc + (continued_count * istk->lineinc));
-
- /*
- * Play safe: remove CRs as well as LFs, if any of either are
- * present at the end of the line.
- */
- while (--p >= buffer && (*p == '\n' || *p == '\r'))
- *p = '\0';
-
- /*
- * Handle spurious ^Z, which may be inserted into source files
- * by some file transfer utilities.
- */
- buffer[strcspn(buffer, "\032")] = '\0';
-
- list->line(LIST_READ, buffer);
-
- return buffer;
-}
-
-/*
- * Tokenise a line of text. This is a very simple process since we
- * don't need to parse the value out of e.g. numeric tokens: we
- * simply split one string into many.
- */
-static Token *
-tokenise(char *line)
-{
- char *p = line;
- int type;
- Token *list_ = NULL;
- Token *t, **tail = &list_;
-
- while (*line)
- {
- p = line;
- if (*p == '%')
- {
- p++;
- if ( isdigit(*p) ||
- ((*p == '-' || *p == '+') && isdigit(p[1])) ||
- ((*p == '+') && (isspace(p[1]) || !p[1])))
- {
- do
- {
- p++;
- }
- while (isdigit(*p));
- type = TOK_PREPROC_ID;
- }
- else if (*p == '{')
- {
- p++;
- while (*p && *p != '}')
- {
- p[-1] = *p;
- p++;
- }
- p[-1] = '\0';
- if (*p)
- p++;
- type = TOK_PREPROC_ID;
- }
- else if (isidchar(*p) ||
- ((*p == '!' || *p == '%' || *p == '$') &&
- isidchar(p[1])))
- {
- do
- {
- p++;
- }
- while (isidchar(*p));
- type = TOK_PREPROC_ID;
- }
- else
- {
- type = TOK_OTHER;
- if (*p == '%')
- p++;
- }
- }
- else if (isidstart(*p) || (*p == '$' && isidstart(p[1])))
- {
- type = TOK_ID;
- p++;
- while (*p && isidchar(*p))
- p++;
- }
- else if (*p == '\'' || *p == '"')
- {
- /*
- * A string token.
- */
- char c = *p;
- p++;
- type = TOK_STRING;
- while (*p && *p != c)
- p++;
- if (*p)
- {
- p++;
- }
- else
- {
- error(ERR_WARNING, "unterminated string");
- }
- }
- else if (isnumstart(*p))
- {
- /*
- * A number token.
- */
- type = TOK_NUMBER;
- p++;
- while (*p && isnumchar(*p))
- p++;
- }
- else if (isspace(*p))
- {
- type = TOK_WHITESPACE;
- p++;
- while (*p && isspace(*p))
- p++;
- /*
- * Whitespace just before end-of-line is discarded by
- * pretending it's a comment; whitespace just before a
- * comment gets lumped into the comment.
- */
- if (!*p || *p == ';')
- {
- type = TOK_COMMENT;
- while (*p)
- p++;
- }
- }
- else if (*p == ';')
- {
- type = TOK_COMMENT;
- while (*p)
- p++;
- }
- else
- {
- /*
- * Anything else is an operator of some kind. We check
- * for all the double-character operators (>>, <<, //,
- * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything
- * else is a single-character operator.
- */
- type = TOK_OTHER;
- if ((p[0] == '>' && p[1] == '>') ||
- (p[0] == '<' && p[1] == '<') ||
- (p[0] == '/' && p[1] == '/') ||
- (p[0] == '<' && p[1] == '=') ||
- (p[0] == '>' && p[1] == '=') ||
- (p[0] == '=' && p[1] == '=') ||
- (p[0] == '!' && p[1] == '=') ||
- (p[0] == '<' && p[1] == '>') ||
- (p[0] == '&' && p[1] == '&') ||
- (p[0] == '|' && p[1] == '|') ||
- (p[0] == '^' && p[1] == '^'))
- {
- p++;
- }
- p++;
- }
- if (type != TOK_COMMENT)
- {
- *tail = t = new_Token(NULL, type, line, p - line);
- tail = &t->next;
- }
- line = p;
- }
- return list_;
-}
-
-/*
- * this function allocates a new managed block of memory and
- * returns a pointer to the block. The managed blocks are
- * deleted only all at once by the delete_Blocks function.
- */
-static void *
-new_Block(size_t size)
-{
- Blocks *b = &blocks;
-
- /* first, get to the end of the linked list */
- while (b->next)
- b = b->next;
- /* now allocate the requested chunk */
- b->chunk = nasm_malloc(size);
-
- /* now allocate a new block for the next request */
- b->next = nasm_malloc(sizeof(Blocks));
- /* and initialize the contents of the new block */
- b->next->next = NULL;
- b->next->chunk = NULL;
- return b->chunk;
-}
-
-/*
- * this function deletes all managed blocks of memory
- */
-static void
-delete_Blocks(void)
-{
- Blocks *a,*b = &blocks;
-
- /*
- * keep in mind that the first block, pointed to by blocks
- * is a static and not dynamically allocated, so we don't
- * free it.
- */
- while (b)
- {
- if (b->chunk)
- nasm_free(b->chunk);
- a = b;
- b = b->next;
- if (a != &blocks)
- nasm_free(a);
- }
-}
-
-/*
- * this function creates a new Token and passes a pointer to it
- * back to the caller. It sets the type and text elements, and
- * also the mac and next elements to NULL.
- */
-static Token *
-new_Token(Token * next, int type, const char *text, int txtlen)
-{
- Token *t;
- int i;
-
- if (freeTokens == NULL)
- {
- freeTokens = (Token *)new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
- for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
- freeTokens[i].next = &freeTokens[i + 1];
- freeTokens[i].next = NULL;
- }
- t = freeTokens;
- freeTokens = t->next;
- t->next = next;
- t->mac = NULL;
- t->type = type;
- if (type == TOK_WHITESPACE || text == NULL)
- {
- t->text = NULL;
- }
- else
- {
- if (txtlen == 0)
- txtlen = strlen(text);
- t->text = nasm_malloc(1 + txtlen);
- strncpy(t->text, text, txtlen);
- t->text[txtlen] = '\0';
- }
- return t;
-}
-
-static Token *
-delete_Token(Token * t)
-{
- Token *next = t->next;
- nasm_free(t->text);
- t->next = freeTokens;
- freeTokens = t;
- return next;
-}
-
-/*
- * Convert a line of tokens back into text.
- * If expand_locals is not zero, identifiers of the form "%$*xxx"
- * will be transformed into ..@ctxnum.xxx
- */
-static char *
-detoken(Token * tlist, int expand_locals)
-{
- Token *t;
- int len;
- char *line, *p;
-
- len = 0;
- for (t = tlist; t; t = t->next)
- {
- if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
- {
- char *p2 = getenv(t->text + 2);
- nasm_free(t->text);
- if (p2)
- t->text = nasm_strdup(p2);
- else
- t->text = NULL;
- }
- /* Expand local macros here and not during preprocessing */
- if (expand_locals &&
- t->type == TOK_PREPROC_ID && t->text &&
- t->text[0] == '%' && t->text[1] == '$')
- {
- Context *ctx = get_ctx(t->text, FALSE);
- if (ctx)
- {
- char buffer[40];
- char *p2, *q = t->text + 2;
-
- q += strspn(q, "$");
- sprintf(buffer, "..@%lu.", ctx->number);
- p2 = nasm_strcat(buffer, q);
- nasm_free(t->text);
- t->text = p2;
- }
- }
- if (t->type == TOK_WHITESPACE)
- {
- len++;
- }
- else if (t->text)
- {
- len += strlen(t->text);
- }
- }
- p = line = nasm_malloc(len + 1);
- for (t = tlist; t; t = t->next)
- {
- if (t->type == TOK_WHITESPACE)
- {
- *p = ' ';
- p++;
- *p = '\0';
- }
- else if (t->text)
- {
- strcpy(p, t->text);
- p += strlen(p);
- }
- }
- *p = '\0';
- return line;
-}
-
-/*
- * A scanner, suitable for use by the expression evaluator, which
- * operates on a line of Tokens. Expects a pointer to a pointer to
- * the first token in the line to be passed in as its private_data
- * field.
- */
-static int
-ppscan(void *private_data, struct tokenval *tokval)
-{
- Token **tlineptr = private_data;
- Token *tline;
-
- do
- {
- tline = *tlineptr;
- *tlineptr = tline ? tline->next : NULL;
- }
- while (tline && (tline->type == TOK_WHITESPACE ||
- tline->type == TOK_COMMENT));
-
- if (!tline)
- return tokval->t_type = TOKEN_EOS;
-
- if (tline->text[0] == '$' && !tline->text[1])
- return tokval->t_type = TOKEN_HERE;
- if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2])
- return tokval->t_type = TOKEN_BASE;
-
- if (tline->type == TOK_ID)
- {
- tokval->t_charptr = tline->text;
- if (tline->text[0] == '$')
- {
- tokval->t_charptr++;
- return tokval->t_type = TOKEN_ID;
- }
-
- /*
- * This is the only special case we actually need to worry
- * about in this restricted context.
- */
- if (!nasm_stricmp(tline->text, "seg"))
- return tokval->t_type = TOKEN_SEG;
-
- return tokval->t_type = TOKEN_ID;
- }
-
- if (tline->type == TOK_NUMBER)
- {
- int rn_error;
-
- tokval->t_integer = nasm_readnum(tline->text, &rn_error);
- if (rn_error)
- return tokval->t_type = TOKEN_ERRNUM;
- tokval->t_charptr = NULL;
- return tokval->t_type = TOKEN_NUM;
- }
-
- if (tline->type == TOK_STRING)
- {
- int rn_warn;
- char q, *r;
- int l;
-
- r = tline->text;
- q = *r++;
- l = strlen(r);
-
- if (l == 0 || r[l - 1] != q)
- return tokval->t_type = TOKEN_ERRNUM;
- tokval->t_integer = nasm_readstrnum(r, l - 1, &rn_warn);
- if (rn_warn)
- error(ERR_WARNING | ERR_PASS1, "character constant too long");
- tokval->t_charptr = NULL;
- return tokval->t_type = TOKEN_NUM;
- }
-
- if (tline->type == TOK_OTHER)
- {
- if (!strcmp(tline->text, "<<"))
- return tokval->t_type = TOKEN_SHL;
- if (!strcmp(tline->text, ">>"))
- return tokval->t_type = TOKEN_SHR;
- if (!strcmp(tline->text, "//"))
- return tokval->t_type = TOKEN_SDIV;
- if (!strcmp(tline->text, "%%"))
- return tokval->t_type = TOKEN_SMOD;
- if (!strcmp(tline->text, "=="))
- return tokval->t_type = TOKEN_EQ;
- if (!strcmp(tline->text, "<>"))
- return tokval->t_type = TOKEN_NE;
- if (!strcmp(tline->text, "!="))
- return tokval->t_type = TOKEN_NE;
- if (!strcmp(tline->text, "<="))
- return tokval->t_type = TOKEN_LE;
- if (!strcmp(tline->text, ">="))
- return tokval->t_type = TOKEN_GE;
- if (!strcmp(tline->text, "&&"))
- return tokval->t_type = TOKEN_DBL_AND;
- if (!strcmp(tline->text, "^^"))
- return tokval->t_type = TOKEN_DBL_XOR;
- if (!strcmp(tline->text, "||"))
- return tokval->t_type = TOKEN_DBL_OR;
- }
-
- /*
- * We have no other options: just return the first character of
- * the token text.
- */
- return tokval->t_type = tline->text[0];
-}
-
-/*
- * Compare a string to the name of an existing macro; this is a
- * simple wrapper which calls either strcmp or nasm_stricmp
- * depending on the value of the `casesense' parameter.
- */
-static int
-mstrcmp(char *p, char *q, int casesense)
-{
- return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
-}
-
-/*
- * Return the Context structure associated with a %$ token. Return
- * NULL, having _already_ reported an error condition, if the
- * context stack isn't deep enough for the supplied number of $
- * signs.
- * If all_contexts == TRUE, contexts that enclose current are
- * also scanned for such smacro, until it is found; if not -
- * only the context that directly results from the number of $'s
- * in variable's name.
- */
-static Context *
-get_ctx(char *name, int all_contexts)
-{
- Context *ctx;
- SMacro *m;
- int i;
-
- if (!name || name[0] != '%' || name[1] != '$')
- return NULL;
-
- if (!cstk)
- {
- error(ERR_NONFATAL, "`%s': context stack is empty", name);
- return NULL;
- }
-
- for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
- {
- ctx = ctx->next;
-/* i--; Lino - 02/25/02 */
- }
- if (!ctx)
- {
- error(ERR_NONFATAL, "`%s': context stack is only"
- " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
- return NULL;
- }
- if (!all_contexts)
- return ctx;
-
- do
- {
- /* Search for this smacro in found context */
- m = ctx->localmac;
- while (m)
- {
- if (!mstrcmp(m->name, name, m->casesense))
- return ctx;
- m = m->next;
- }
- ctx = ctx->next;
- }
- while (ctx);
- return NULL;
-}
-
-/* Add a slash to the end of a path if it is missing. We use the
- * forward slash to make it compatible with Unix systems.
- */
-static void
-backslash(char *s)
-{
- int pos = strlen(s);
- if (s[pos - 1] != '\\' && s[pos - 1] != '/')
- {
- s[pos] = '/';
- s[pos + 1] = '\0';
- }
-}
-
-/*
- * Open an include file. This routine must always return a valid
- * file pointer if it returns - it's responsible for throwing an
- * ERR_FATAL and bombing out completely if not. It should also try
- * the include path one by one until it finds the file or reaches
- * the end of the path.
- */
-static FILE *
-inc_fopen(char *file)
-{
- FILE *fp;
- const char *prefix = "";
- char *combine;
- IncPath *ip = ipath;
- static int namelen = 0;
- int len = strlen(file);
-
- while (1)
- {
- combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
- strcpy(combine, prefix);
- if (prefix[0] != 0)
- backslash(combine);
- strcat(combine, file);
- fp = fopen(combine, "r");
- if (pass == 0 && fp)
- {
- namelen += strlen(combine) + 1;
- if (namelen > 62)
- {
- printf(" \\\n ");
- namelen = 2;
- }
- printf(" %s", combine);
- }
- nasm_free(combine);
- if (fp)
- return fp;
- if (!ip)
- break;
- prefix = ip->path;
- ip = ip->next;
- }
-
- error(ERR_FATAL, "unable to open include file `%s'", file);
- return NULL; /* never reached - placate compilers */
-}
-
-/*
- * Determine if we should warn on defining a single-line macro of
- * name `name', with `nparam' parameters. If nparam is 0 or -1, will
- * return TRUE if _any_ single-line macro of that name is defined.
- * Otherwise, will return TRUE if a single-line macro with either
- * `nparam' or no parameters is defined.
- *
- * If a macro with precisely the right number of parameters is
- * defined, or nparam is -1, the address of the definition structure
- * will be returned in `defn'; otherwise NULL will be returned. If `defn'
- * is NULL, no action will be taken regarding its contents, and no
- * error will occur.
- *
- * Note that this is also called with nparam zero to resolve
- * `ifdef'.
- *
- * If you already know which context macro belongs to, you can pass
- * the context pointer as first parameter; if you won't but name begins
- * with %$ the context will be automatically computed. If all_contexts
- * is true, macro will be searched in outer contexts as well.
- */
-static int
-smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
- int nocase)
-{
- SMacro *m;
-
- if (ctx)
- m = ctx->localmac;
- else if (name[0] == '%' && name[1] == '$')
- {
- if (cstk)
- ctx = get_ctx(name, FALSE);
- if (!ctx)
- return FALSE; /* got to return _something_ */
- m = ctx->localmac;
- }
- else
- m = smacros[hash(name)];
-
- while (m)
- {
- if (!mstrcmp(m->name, name, m->casesense && nocase) &&
- (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
- {
- if (defn)
- {
- if (nparam == m->nparam || nparam == -1)
- *defn = m;
- else
- *defn = NULL;
- }
- return TRUE;
- }
- m = m->next;
- }
-
- return FALSE;
-}
-
-/*
- * Count and mark off the parameters in a multi-line macro call.
- * This is called both from within the multi-line macro expansion
- * code, and also to mark off the default parameters when provided
- * in a %macro definition line.
- */
-static void
-count_mmac_params(Token * t, int *nparam, Token *** params)
-{
- int paramsize, brace;
-
- *nparam = paramsize = 0;
- *params = NULL;
- while (t)
- {
- if (*nparam >= paramsize)
- {
- paramsize += PARAM_DELTA;
- *params = nasm_realloc(*params, sizeof(**params) * paramsize);
- }
- skip_white_(t);
- brace = FALSE;
- if (tok_is_(t, "{"))
- brace = TRUE;
- (*params)[(*nparam)++] = t;
- while (tok_isnt_(t, brace ? "}" : ","))
- t = t->next;
- if (t)
- { /* got a comma/brace */
- t = t->next;
- if (brace)
- {
- /*
- * Now we've found the closing brace, look further
- * for the comma.
- */
- skip_white_(t);
- if (tok_isnt_(t, ","))
- {
- error(ERR_NONFATAL,
- "braces do not enclose all of macro parameter");
- while (tok_isnt_(t, ","))
- t = t->next;
- }
- if (t)
- t = t->next; /* eat the comma */
- }
- }
- }
-}
-
-/*
- * Determine whether one of the various `if' conditions is true or
- * not.
- *
- * We must free the tline we get passed.
- */
-static int
-if_condition(Token * tline, int i)
-{
- int j, casesense;
- Token *t, *tt, **tptr, *origline;
- struct tokenval tokval;
- nasm_expr *evalresult;
-
- origline = tline;
-
- switch (i)
- {
- case PP_IFCTX:
- case PP_ELIFCTX:
- case PP_IFNCTX:
- case PP_ELIFNCTX:
- j = FALSE; /* have we matched yet? */
- while (cstk && tline)
- {
- skip_white_(tline);
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL,
- "`%s' expects context identifiers",
- directives[i]);
- free_tlist(origline);
- return -1;
- }
- if (!nasm_stricmp(tline->text, cstk->name))
- j = TRUE;
- tline = tline->next;
- }
- if (i == PP_IFNCTX || i == PP_ELIFNCTX)
- j = !j;
- free_tlist(origline);
- return j;
-
- case PP_IFDEF:
- case PP_ELIFDEF:
- case PP_IFNDEF:
- case PP_ELIFNDEF:
- j = FALSE; /* have we matched yet? */
- while (tline)
- {
- skip_white_(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL,
- "`%s' expects macro identifiers",
- directives[i]);
- free_tlist(origline);
- return -1;
- }
- if (smacro_defined(NULL, tline->text, 0, NULL, 1))
- j = TRUE;
- tline = tline->next;
- }
- if (i == PP_IFNDEF || i == PP_ELIFNDEF)
- j = !j;
- free_tlist(origline);
- return j;
-
- case PP_IFIDN:
- case PP_ELIFIDN:
- case PP_IFNIDN:
- case PP_ELIFNIDN:
- case PP_IFIDNI:
- case PP_ELIFIDNI:
- case PP_IFNIDNI:
- case PP_ELIFNIDNI:
- tline = expand_smacro(tline);
- t = tt = tline;
- while (tok_isnt_(tt, ","))
- tt = tt->next;
- if (!tt)
- {
- error(ERR_NONFATAL,
- "`%s' expects two comma-separated arguments",
- directives[i]);
- free_tlist(tline);
- return -1;
- }
- tt = tt->next;
- casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
- i == PP_IFNIDN || i == PP_ELIFNIDN);
- j = TRUE; /* assume equality unless proved not */
- while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt)
- {
- if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
- {
- error(ERR_NONFATAL, "`%s': more than one comma on line",
- directives[i]);
- free_tlist(tline);
- return -1;
- }
- if (t->type == TOK_WHITESPACE)
- {
- t = t->next;
- continue;
- }
- else if (tt->type == TOK_WHITESPACE)
- {
- tt = tt->next;
- continue;
- }
- else if (tt->type != t->type ||
- mstrcmp(tt->text, t->text, casesense))
- {
- j = FALSE; /* found mismatching tokens */
- break;
- }
- else
- {
- t = t->next;
- tt = tt->next;
- continue;
- }
- }
- if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
- j = FALSE; /* trailing gunk on one end or other */
- if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
- i == PP_IFNIDNI || i == PP_ELIFNIDNI)
- j = !j;
- free_tlist(tline);
- return j;
-
- case PP_IFMACRO:
- case PP_ELIFMACRO:
- case PP_IFNMACRO:
- case PP_ELIFNMACRO:
- {
- int found = 0;
- MMacro searching, *mmac;
-
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tok_type_(tline, TOK_ID))
- {
- error(ERR_NONFATAL,
- "`%s' expects a macro name",
- directives[i]);
- return -1;
- }
- searching.name = nasm_strdup(tline->text);
- searching.casesense = (i == PP_MACRO);
- searching.plus = FALSE;
- searching.nolist = FALSE;
- searching.in_progress = FALSE;
- searching.rep_nest = NULL;
- searching.nparam_min = 0;
- searching.nparam_max = INT_MAX;
- tline = expand_smacro(tline->next);
- skip_white_(tline);
- if (!tline)
- {
- } else if (!tok_type_(tline, TOK_NUMBER))
- {
- error(ERR_NONFATAL,
- "`%s' expects a parameter count or nothing",
- directives[i]);
- }
- else
- {
- searching.nparam_min = searching.nparam_max =
- nasm_readnum(tline->text, &j);
- if (j)
- error(ERR_NONFATAL,
- "unable to parse parameter count `%s'",
- tline->text);
- }
- if (tline && tok_is_(tline->next, "-"))
- {
- tline = tline->next->next;
- if (tok_is_(tline, "*"))
- searching.nparam_max = INT_MAX;
- else if (!tok_type_(tline, TOK_NUMBER))
- error(ERR_NONFATAL,
- "`%s' expects a parameter count after `-'",
- directives[i]);
- else
- {
- searching.nparam_max = nasm_readnum(tline->text, &j);
- if (j)
- error(ERR_NONFATAL,
- "unable to parse parameter count `%s'",
- tline->text);
- if (searching.nparam_min > searching.nparam_max)
- error(ERR_NONFATAL,
- "minimum parameter count exceeds maximum");
- }
- }
- if (tline && tok_is_(tline->next, "+"))
- {
- tline = tline->next;
- searching.plus = TRUE;
- }
- mmac = mmacros[hash(searching.name)];
- while (mmac)
- {
- if (!strcmp(mmac->name, searching.name) &&
- (mmac->nparam_min <= searching.nparam_max
- || searching.plus)
- && (searching.nparam_min <= mmac->nparam_max
- || mmac->plus))
- {
- found = TRUE;
- break;
- }
- mmac = mmac->next;
- }
- nasm_free(searching.name);
- free_tlist(origline);
- if (i == PP_IFNMACRO || i == PP_ELIFNMACRO)
- found = !found;
- return found;
- }
-
- case PP_IFID:
- case PP_ELIFID:
- case PP_IFNID:
- case PP_ELIFNID:
- case PP_IFNUM:
- case PP_ELIFNUM:
- case PP_IFNNUM:
- case PP_ELIFNNUM:
- case PP_IFSTR:
- case PP_ELIFSTR:
- case PP_IFNSTR:
- case PP_ELIFNSTR:
- tline = expand_smacro(tline);
- t = tline;
- while (tok_type_(t, TOK_WHITESPACE))
- t = t->next;
- j = FALSE; /* placate optimiser */
- if (t)
- switch (i)
- {
- case PP_IFID:
- case PP_ELIFID:
- case PP_IFNID:
- case PP_ELIFNID:
- j = (t->type == TOK_ID);
- break;
- case PP_IFNUM:
- case PP_ELIFNUM:
- case PP_IFNNUM:
- case PP_ELIFNNUM:
- j = (t->type == TOK_NUMBER);
- break;
- case PP_IFSTR:
- case PP_ELIFSTR:
- case PP_IFNSTR:
- case PP_ELIFNSTR:
- j = (t->type == TOK_STRING);
- break;
- }
- if (i == PP_IFNID || i == PP_ELIFNID ||
- i == PP_IFNNUM || i == PP_ELIFNNUM ||
- i == PP_IFNSTR || i == PP_ELIFNSTR)
- j = !j;
- free_tlist(tline);
- return j;
-
- case PP_IF:
- case PP_ELIF:
- t = tline = expand_smacro(tline);
- tptr = &t;
- tokval.t_type = TOKEN_INVALID;
- evalresult = evaluate(ppscan, tptr, &tokval,
- NULL, pass | CRITICAL, error, NULL);
- free_tlist(tline);
- if (!evalresult)
- return -1;
- if (tokval.t_type)
- error(ERR_WARNING,
- "trailing garbage after expression ignored");
- if (!nasm_is_simple(evalresult))
- {
- error(ERR_NONFATAL,
- "non-constant value given to `%s'", directives[i]);
- return -1;
- }
- return nasm_reloc_value(evalresult) != 0;
-
- default:
- error(ERR_FATAL,
- "preprocessor directive `%s' not yet implemented",
- directives[i]);
- free_tlist(origline);
- return -1; /* yeah, right */
- }
-}
-
-/*
- * Expand macros in a string. Used in %error and %include directives.
- * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
- * The returned variable should ALWAYS be freed after usage.
- */
-static void
-expand_macros_in_string(char **p)
-{
- Token *line = tokenise(*p);
- line = expand_smacro(line);
- *p = detoken(line, FALSE);
-}
-
-/**
- * find and process preprocessor directive in passed line
- * Find out if a line contains a preprocessor directive, and deal
- * with it if so.
- *
- * If a directive _is_ found, it is the responsibility of this routine
- * (and not the caller) to free_tlist() the line.
- *
- * @param tline a pointer to the current tokeninzed line linked list
- * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND
- *
- */
-static int
-do_directive(Token * tline)
-{
- int i, j, k, m, nparam, nolist;
- int offset;
- char *p, *mname;
- Include *inc;
- Context *ctx;
- Cond *cond;
- SMacro *smac, **smhead;
- MMacro *mmac;
- Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
- Line *l;
- struct tokenval tokval;
- nasm_expr *evalresult;
- MMacro *tmp_defining; /* Used when manipulating rep_nest */
-
- origline = tline;
-
- skip_white_(tline);
- if (!tok_type_(tline, TOK_PREPROC_ID) ||
- (tline->text[1] == '%' || tline->text[1] == '$'
- || tline->text[1] == '!'))
- return NO_DIRECTIVE_FOUND;
-
- i = -1;
- j = elements(directives);
- while (j - i > 1)
- {
- k = (j + i) / 2;
- m = nasm_stricmp(tline->text, directives[k]);
- if (m == 0) {
- if (tasm_compatible_mode) {
- i = k;
- j = -2;
- } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
- i = k;
- j = -2;
- }
- break;
- }
- else if (m < 0) {
- j = k;
- }
- else
- i = k;
- }
-
- /*
- * If we're in a non-emitting branch of a condition construct,
- * or walking to the end of an already terminated %rep block,
- * we should ignore all directives except for condition
- * directives.
- */
- if (((istk->conds && !emitting(istk->conds->state)) ||
- (istk->mstk && !istk->mstk->in_progress)) &&
- !is_condition(i))
- {
- return NO_DIRECTIVE_FOUND;
- }
-
- /*
- * If we're defining a macro or reading a %rep block, we should
- * ignore all directives except for %macro/%imacro (which
- * generate an error), %endm/%endmacro, and (only if we're in a
- * %rep block) %endrep. If we're in a %rep block, another %rep
- * causes an error, so should be let through.
- */
- if (defining && i != PP_MACRO && i != PP_IMACRO &&
- i != PP_ENDMACRO && i != PP_ENDM &&
- (defining->name || (i != PP_ENDREP && i != PP_REP)))
- {
- return NO_DIRECTIVE_FOUND;
- }
-
- if (j != -2)
- {
- error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
- tline->text);
- return NO_DIRECTIVE_FOUND; /* didn't get it */
- }
-
- switch (i)
- {
- case PP_STACKSIZE:
- /* Directive to tell NASM what the default stack size is. The
- * default is for a 16-bit stack, and this can be overriden with
- * %stacksize large.
- * the following form:
- *
- * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
- */
- tline = tline->next;
- if (tline && tline->type == TOK_WHITESPACE)
- tline = tline->next;
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- if (nasm_stricmp(tline->text, "flat") == 0)
- {
- /* All subsequent ARG directives are for a 32-bit stack */
- StackSize = 4;
- StackPointer = "ebp";
- ArgOffset = 8;
- LocalOffset = 4;
- }
- else if (nasm_stricmp(tline->text, "large") == 0)
- {
- /* All subsequent ARG directives are for a 16-bit stack,
- * far function call.
- */
- StackSize = 2;
- StackPointer = "bp";
- ArgOffset = 4;
- LocalOffset = 2;
- }
- else if (nasm_stricmp(tline->text, "small") == 0)
- {
- /* All subsequent ARG directives are for a 16-bit stack,
- * far function call. We don't support near functions.
- */
- StackSize = 2;
- StackPointer = "bp";
- ArgOffset = 6;
- LocalOffset = 2;
- }
- else
- {
- error(ERR_NONFATAL, "`%%stacksize' invalid size type");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_ARG:
- /* TASM like ARG directive to define arguments to functions, in
- * the following form:
- *
- * ARG arg1:WORD, arg2:DWORD, arg4:QWORD
- */
- offset = ArgOffset;
- do
- {
- char *arg, directive[256];
- int size = StackSize;
-
- /* Find the argument name */
- tline = tline->next;
- if (tline && tline->type == TOK_WHITESPACE)
- tline = tline->next;
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL, "`%%arg' missing argument parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- arg = tline->text;
-
- /* Find the argument size type */
- tline = tline->next;
- if (!tline || tline->type != TOK_OTHER
- || tline->text[0] != ':')
- {
- error(ERR_NONFATAL,
- "Syntax error processing `%%arg' directive");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- tline = tline->next;
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL,
- "`%%arg' missing size type parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- /* Allow macro expansion of type parameter */
- tt = tokenise(tline->text);
- tt = expand_smacro(tt);
- if (nasm_stricmp(tt->text, "byte") == 0)
- {
- size = MAX(StackSize, 1);
- }
- else if (nasm_stricmp(tt->text, "word") == 0)
- {
- size = MAX(StackSize, 2);
- }
- else if (nasm_stricmp(tt->text, "dword") == 0)
- {
- size = MAX(StackSize, 4);
- }
- else if (nasm_stricmp(tt->text, "qword") == 0)
- {
- size = MAX(StackSize, 8);
- }
- else if (nasm_stricmp(tt->text, "tword") == 0)
- {
- size = MAX(StackSize, 10);
- }
- else
- {
- error(ERR_NONFATAL,
- "Invalid size type for `%%arg' missing directive");
- free_tlist(tt);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- free_tlist(tt);
-
- /* Now define the macro for the argument */
- sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
- offset);
- do_directive(tokenise(directive));
- offset += size;
-
- /* Move to the next argument in the list */
- tline = tline->next;
- if (tline && tline->type == TOK_WHITESPACE)
- tline = tline->next;
- }
- while (tline && tline->type == TOK_OTHER
- && tline->text[0] == ',');
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_LOCAL:
- /* TASM like LOCAL directive to define local variables for a
- * function, in the following form:
- *
- * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize
- *
- * The '= LocalSize' at the end is ignored by NASM, but is
- * required by TASM to define the local parameter size (and used
- * by the TASM macro package).
- */
- offset = LocalOffset;
- do
- {
- char *local, directive[256];
- int size = StackSize;
-
- /* Find the argument name */
- tline = tline->next;
- if (tline && tline->type == TOK_WHITESPACE)
- tline = tline->next;
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL,
- "`%%local' missing argument parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- local = tline->text;
-
- /* Find the argument size type */
- tline = tline->next;
- if (!tline || tline->type != TOK_OTHER
- || tline->text[0] != ':')
- {
- error(ERR_NONFATAL,
- "Syntax error processing `%%local' directive");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- tline = tline->next;
- if (!tline || tline->type != TOK_ID)
- {
- error(ERR_NONFATAL,
- "`%%local' missing size type parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- /* Allow macro expansion of type parameter */
- tt = tokenise(tline->text);
- tt = expand_smacro(tt);
- if (nasm_stricmp(tt->text, "byte") == 0)
- {
- size = MAX(StackSize, 1);
- }
- else if (nasm_stricmp(tt->text, "word") == 0)
- {
- size = MAX(StackSize, 2);
- }
- else if (nasm_stricmp(tt->text, "dword") == 0)
- {
- size = MAX(StackSize, 4);
- }
- else if (nasm_stricmp(tt->text, "qword") == 0)
- {
- size = MAX(StackSize, 8);
- }
- else if (nasm_stricmp(tt->text, "tword") == 0)
- {
- size = MAX(StackSize, 10);
- }
- else
- {
- error(ERR_NONFATAL,
- "Invalid size type for `%%local' missing directive");
- free_tlist(tt);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- free_tlist(tt);
-
- /* Now define the macro for the argument */
- sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
- offset);
- do_directive(tokenise(directive));
- offset += size;
-
- /* Now define the assign to setup the enter_c macro correctly */
- sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
- size);
- do_directive(tokenise(directive));
-
- /* Move to the next argument in the list */
- tline = tline->next;
- if (tline && tline->type == TOK_WHITESPACE)
- tline = tline->next;
- }
- while (tline && tline->type == TOK_OTHER
- && tline->text[0] == ',');
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_CLEAR:
- if (tline->next)
- error(ERR_WARNING,
- "trailing garbage after `%%clear' ignored");
- for (j = 0; j < NHASH; j++)
- {
- while (mmacros[j])
- {
- MMacro *m2 = mmacros[j];
- mmacros[j] = m2->next;
- free_mmacro(m2);
- }
- while (smacros[j])
- {
- SMacro *s = smacros[j];
- smacros[j] = smacros[j]->next;
- nasm_free(s->name);
- free_tlist(s->expansion);
- nasm_free(s);
- }
- }
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_INCLUDE:
- tline = tline->next;
- skip_white_(tline);
- if (!tline || (tline->type != TOK_STRING &&
- tline->type != TOK_INTERNAL_STRING))
- {
- error(ERR_NONFATAL, "`%%include' expects a file name");
- free_tlist(origline);
- return DIRECTIVE_FOUND; /* but we did _something_ */
- }
- if (tline->next)
- error(ERR_WARNING,
- "trailing garbage after `%%include' ignored");
- if (tline->type != TOK_INTERNAL_STRING)
- {
- p = tline->text + 1; /* point past the quote to the name */
- p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
- }
- else
- p = tline->text; /* internal_string is easier */
- expand_macros_in_string(&p);
- inc = nasm_malloc(sizeof(Include));
- inc->next = istk;
- inc->conds = NULL;
- inc->fp = inc_fopen(p);
- inc->fname = nasm_src_set_fname(p);
- inc->lineno = nasm_src_set_linnum(0);
- inc->lineinc = 1;
- inc->expansion = NULL;
- inc->mstk = NULL;
- istk = inc;
- list->uplevel(LIST_INCLUDE);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_PUSH:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tok_type_(tline, TOK_ID))
- {
- error(ERR_NONFATAL, "`%%push' expects a context identifier");
- free_tlist(origline);
- return DIRECTIVE_FOUND; /* but we did _something_ */
- }
- if (tline->next)
- error(ERR_WARNING, "trailing garbage after `%%push' ignored");
- ctx = nasm_malloc(sizeof(Context));
- ctx->next = cstk;
- ctx->localmac = NULL;
- ctx->name = nasm_strdup(tline->text);
- ctx->number = unique++;
- cstk = ctx;
- free_tlist(origline);
- break;
-
- case PP_REPL:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tok_type_(tline, TOK_ID))
- {
- error(ERR_NONFATAL, "`%%repl' expects a context identifier");
- free_tlist(origline);
- return DIRECTIVE_FOUND; /* but we did _something_ */
- }
- if (tline->next)
- error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
- if (!cstk)
- error(ERR_NONFATAL, "`%%repl': context stack is empty");
- else
- {
- nasm_free(cstk->name);
- cstk->name = nasm_strdup(tline->text);
- }
- free_tlist(origline);
- break;
-
- case PP_POP:
- if (tline->next)
- error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
- if (!cstk)
- error(ERR_NONFATAL,
- "`%%pop': context stack is already empty");
- else
- ctx_pop();
- free_tlist(origline);
- break;
-
- case PP_ERROR:
- tline->next = expand_smacro(tline->next);
- tline = tline->next;
- skip_white_(tline);
- if (tok_type_(tline, TOK_STRING))
- {
- p = tline->text + 1; /* point past the quote to the name */
- p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
- expand_macros_in_string(&p);
- error(ERR_NONFATAL, "%s", p);
- nasm_free(p);
- }
- else
- {
- p = detoken(tline, FALSE);
- error(ERR_WARNING, "%s", p);
- nasm_free(p);
- }
- free_tlist(origline);
- break;
-
- case PP_IF:
- case PP_IFCTX:
- case PP_IFDEF:
- case PP_IFID:
- case PP_IFIDN:
- case PP_IFIDNI:
- case PP_IFMACRO:
- case PP_IFNCTX:
- case PP_IFNDEF:
- case PP_IFNID:
- case PP_IFNIDN:
- case PP_IFNIDNI:
- case PP_IFNMACRO:
- case PP_IFNNUM:
- case PP_IFNSTR:
- case PP_IFNUM:
- case PP_IFSTR:
- if (istk->conds && !emitting(istk->conds->state))
- j = COND_NEVER;
- else
- {
- j = if_condition(tline->next, i);
- tline->next = NULL; /* it got freed */
- free_tlist(origline);
- j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
- }
- cond = nasm_malloc(sizeof(Cond));
- cond->next = istk->conds;
- cond->state = j;
- istk->conds = cond;
- return DIRECTIVE_FOUND;
-
- case PP_ELIF:
- case PP_ELIFCTX:
- case PP_ELIFDEF:
- case PP_ELIFID:
- case PP_ELIFIDN:
- case PP_ELIFIDNI:
- case PP_ELIFMACRO:
- case PP_ELIFNCTX:
- case PP_ELIFNDEF:
- case PP_ELIFNID:
- case PP_ELIFNIDN:
- case PP_ELIFNIDNI:
- case PP_ELIFNMACRO:
- case PP_ELIFNNUM:
- case PP_ELIFNSTR:
- case PP_ELIFNUM:
- case PP_ELIFSTR:
- if (!istk->conds)
- error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
- if (emitting(istk->conds->state)
- || istk->conds->state == COND_NEVER)
- istk->conds->state = COND_NEVER;
- else
- {
- /*
- * IMPORTANT: In the case of %if, we will already have
- * called expand_mmac_params(); however, if we're
- * processing an %elif we must have been in a
- * non-emitting mode, which would have inhibited
- * the normal invocation of expand_mmac_params(). Therefore,
- * we have to do it explicitly here.
- */
- j = if_condition(expand_mmac_params(tline->next), i);
- tline->next = NULL; /* it got freed */
- free_tlist(origline);
- istk->conds->state =
- j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
- }
- return DIRECTIVE_FOUND;
-
- case PP_ELSE:
- if (tline->next)
- error(ERR_WARNING, "trailing garbage after `%%else' ignored");
- if (!istk->conds)
- error(ERR_FATAL, "`%%else': no matching `%%if'");
- if (emitting(istk->conds->state)
- || istk->conds->state == COND_NEVER)
- istk->conds->state = COND_ELSE_FALSE;
- else
- istk->conds->state = COND_ELSE_TRUE;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_ENDIF:
- if (tline->next)
- error(ERR_WARNING,
- "trailing garbage after `%%endif' ignored");
- if (!istk->conds)
- error(ERR_FATAL, "`%%endif': no matching `%%if'");
- cond = istk->conds;
- istk->conds = cond->next;
- nasm_free(cond);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_MACRO:
- case PP_IMACRO:
- if (defining)
- error(ERR_FATAL,
- "`%%%smacro': already defining a macro",
- (i == PP_IMACRO ? "i" : ""));
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tok_type_(tline, TOK_ID))
- {
- error(ERR_NONFATAL,
- "`%%%smacro' expects a macro name",
- (i == PP_IMACRO ? "i" : ""));
- return DIRECTIVE_FOUND;
- }
- defining = nasm_malloc(sizeof(MMacro));
- defining->name = nasm_strdup(tline->text);
- defining->casesense = (i == PP_MACRO);
- defining->plus = FALSE;
- defining->nolist = FALSE;
- defining->in_progress = FALSE;
- defining->rep_nest = NULL;
- tline = expand_smacro(tline->next);
- skip_white_(tline);
- if (!tok_type_(tline, TOK_NUMBER))
- {
- error(ERR_NONFATAL,
- "`%%%smacro' expects a parameter count",
- (i == PP_IMACRO ? "i" : ""));
- defining->nparam_min = defining->nparam_max = 0;
- }
- else
- {
- defining->nparam_min = defining->nparam_max =
- nasm_readnum(tline->text, &j);
- if (j)
- error(ERR_NONFATAL,
- "unable to parse parameter count `%s'",
- tline->text);
- }
- if (tline && tok_is_(tline->next, "-"))
- {
- tline = tline->next->next;
- if (tok_is_(tline, "*"))
- defining->nparam_max = INT_MAX;
- else if (!tok_type_(tline, TOK_NUMBER))
- error(ERR_NONFATAL,
- "`%%%smacro' expects a parameter count after `-'",
- (i == PP_IMACRO ? "i" : ""));
- else
- {
- defining->nparam_max = nasm_readnum(tline->text, &j);
- if (j)
- error(ERR_NONFATAL,
- "unable to parse parameter count `%s'",
- tline->text);
- if (defining->nparam_min > defining->nparam_max)
- error(ERR_NONFATAL,
- "minimum parameter count exceeds maximum");
- }
- }
- if (tline && tok_is_(tline->next, "+"))
- {
- tline = tline->next;
- defining->plus = TRUE;
- }
- if (tline && tok_type_(tline->next, TOK_ID) &&
- !nasm_stricmp(tline->next->text, ".nolist"))
- {
- tline = tline->next;
- defining->nolist = TRUE;
- }
- mmac = mmacros[hash(defining->name)];
- while (mmac)
- {
- if (!strcmp(mmac->name, defining->name) &&
- (mmac->nparam_min <= defining->nparam_max
- || defining->plus)
- && (defining->nparam_min <= mmac->nparam_max
- || mmac->plus))
- {
- error(ERR_WARNING,
- "redefining multi-line macro `%s'",
- defining->name);
- break;
- }
- mmac = mmac->next;
- }
- /*
- * Handle default parameters.
- */
- if (tline && tline->next)
- {
- defining->dlist = tline->next;
- tline->next = NULL;
- count_mmac_params(defining->dlist, &defining->ndefs,
- &defining->defaults);
- }
- else
- {
- defining->dlist = NULL;
- defining->defaults = NULL;
- }
- defining->expansion = NULL;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_ENDM:
- case PP_ENDMACRO:
- if (!defining)
- {
- error(ERR_NONFATAL, "`%s': not defining a macro",
- tline->text);
- return DIRECTIVE_FOUND;
- }
- k = hash(defining->name);
- defining->next = mmacros[k];
- mmacros[k] = defining;
- defining = NULL;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_ROTATE:
- if (tline->next && tline->next->type == TOK_WHITESPACE)
- tline = tline->next;
- if (tline->next == NULL)
- {
- free_tlist(origline);
- error(ERR_NONFATAL, "`%%rotate' missing rotate count");
- return DIRECTIVE_FOUND;
- }
- t = expand_smacro(tline->next);
- tline->next = NULL;
- free_tlist(origline);
- tline = t;
- tptr = &t;
- tokval.t_type = TOKEN_INVALID;
- evalresult =
- evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
- free_tlist(tline);
- if (!evalresult)
- return DIRECTIVE_FOUND;
- if (tokval.t_type)
- error(ERR_WARNING,
- "trailing garbage after expression ignored");
- if (!nasm_is_simple(evalresult))
- {
- error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
- return DIRECTIVE_FOUND;
- }
- mmac = istk->mstk;
- while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
- mmac = mmac->next_active;
- if (!mmac)
- {
- error(ERR_NONFATAL,
- "`%%rotate' invoked outside a macro call");
- }
- else if (mmac->nparam == 0)
- {
- error(ERR_NONFATAL,
- "`%%rotate' invoked within macro without parameters");
- }
- else
- {
- mmac->rotate = mmac->rotate + nasm_reloc_value(evalresult);
-
- if (mmac->rotate < 0)
- mmac->rotate =
- mmac->nparam - (-mmac->rotate) % mmac->nparam;
- mmac->rotate %= mmac->nparam;
- }
- return DIRECTIVE_FOUND;
-
- case PP_REP:
- nolist = FALSE;
- tline = tline->next;
- if (tline->next && tline->next->type == TOK_WHITESPACE)
- tline = tline->next;
- if (tline->next && tline->next->type == TOK_ID &&
- !nasm_stricmp(tline->next->text, ".nolist"))
- {
- tline = tline->next;
- nolist = TRUE;
- }
- t = expand_smacro(tline->next);
- tline->next = NULL;
- free_tlist(origline);
- tline = t;
- tptr = &t;
- tokval.t_type = TOKEN_INVALID;
- evalresult =
- evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
- free_tlist(tline);
- if (!evalresult)
- return DIRECTIVE_FOUND;
- if (tokval.t_type)
- error(ERR_WARNING,
- "trailing garbage after expression ignored");
- if (!nasm_is_simple(evalresult))
- {
- error(ERR_NONFATAL, "non-constant value given to `%%rep'");
- return DIRECTIVE_FOUND;
- }
- tmp_defining = defining;
- defining = nasm_malloc(sizeof(MMacro));
- defining->name = NULL; /* flags this macro as a %rep block */
- defining->casesense = 0;
- defining->plus = FALSE;
- defining->nolist = nolist;
- defining->in_progress = nasm_reloc_value(evalresult) + 1;
- defining->nparam_min = defining->nparam_max = 0;
- defining->defaults = NULL;
- defining->dlist = NULL;
- defining->expansion = NULL;
- defining->next_active = istk->mstk;
- defining->rep_nest = tmp_defining;
- return DIRECTIVE_FOUND;
-
- case PP_ENDREP:
- if (!defining || defining->name)
- {
- error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
- return DIRECTIVE_FOUND;
- }
-
- /*
- * Now we have a "macro" defined - although it has no name
- * and we won't be entering it in the hash tables - we must
- * push a macro-end marker for it on to istk->expansion.
- * After that, it will take care of propagating itself (a
- * macro-end marker line for a macro which is really a %rep
- * block will cause the macro to be re-expanded, complete
- * with another macro-end marker to ensure the process
- * continues) until the whole expansion is forcibly removed
- * from istk->expansion by a %exitrep.
- */
- l = nasm_malloc(sizeof(Line));
- l->next = istk->expansion;
- l->finishes = defining;
- l->first = NULL;
- istk->expansion = l;
-
- istk->mstk = defining;
-
- list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
- tmp_defining = defining;
- defining = defining->rep_nest;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_EXITREP:
- /*
- * We must search along istk->expansion until we hit a
- * macro-end marker for a macro with no name. Then we set
- * its `in_progress' flag to 0.
- */
- for (l = istk->expansion; l; l = l->next)
- if (l->finishes && !l->finishes->name)
- break;
-
- if (l)
- l->finishes->in_progress = 0;
- else
- error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_XDEFINE:
- case PP_IXDEFINE:
- case PP_DEFINE:
- case PP_IDEFINE:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL,
- "`%%%s%sdefine' expects a macro identifier",
- ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
- ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- ctx = get_ctx(tline->text, FALSE);
- if (!ctx)
- smhead = &smacros[hash(tline->text)];
- else
- smhead = &ctx->localmac;
- mname = tline->text;
- last = tline;
- param_start = tline = tline->next;
- nparam = 0;
-
- /* Expand the macro definition now for %xdefine and %ixdefine */
- if ((i == PP_XDEFINE) || (i == PP_IXDEFINE))
- tline = expand_smacro(tline);
-
- if (tok_is_(tline, "("))
- {
- /*
- * This macro has parameters.
- */
-
- tline = tline->next;
- while (1)
- {
- skip_white_(tline);
- if (!tline)
- {
- error(ERR_NONFATAL, "parameter identifier expected");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- if (tline->type != TOK_ID)
- {
- error(ERR_NONFATAL,
- "`%s': parameter identifier expected",
- tline->text);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- tline->type = TOK_SMAC_PARAM + nparam++;
- tline = tline->next;
- skip_white_(tline);
- if (tok_is_(tline, ","))
- {
- tline = tline->next;
- continue;
- }
- if (!tok_is_(tline, ")"))
- {
- error(ERR_NONFATAL,
- "`)' expected to terminate macro template");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- break;
- }
- last = tline;
- tline = tline->next;
- }
- if (tok_type_(tline, TOK_WHITESPACE))
- last = tline, tline = tline->next;
- macro_start = NULL;
- last->next = NULL;
- t = tline;
- while (t)
- {
- if (t->type == TOK_ID)
- {
- for (tt = param_start; tt; tt = tt->next)
- if (tt->type >= TOK_SMAC_PARAM &&
- !strcmp(tt->text, t->text))
- t->type = tt->type;
- }
- tt = t->next;
- t->next = macro_start;
- macro_start = t;
- t = tt;
- }
- /*
- * Good. We now have a macro name, a parameter count, and a
- * token list (in reverse order) for an expansion. We ought
- * to be OK just to create an SMacro, store it, and let
- * free_tlist have the rest of the line (which we have
- * carefully re-terminated after chopping off the expansion
- * from the end).
- */
- if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
- {
- if (!smac)
- {
- error(ERR_WARNING,
- "single-line macro `%s' defined both with and"
- " without parameters", mname);
- free_tlist(origline);
- free_tlist(macro_start);
- return DIRECTIVE_FOUND;
- }
- else
- {
- /*
- * We're redefining, so we have to take over an
- * existing SMacro structure. This means freeing
- * what was already in it.
- */
- nasm_free(smac->name);
- free_tlist(smac->expansion);
- }
- }
- else
- {
- smac = nasm_malloc(sizeof(SMacro));
- smac->next = *smhead;
- *smhead = smac;
- }
- smac->name = nasm_strdup(mname);
- smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
- smac->nparam = nparam;
- smac->expansion = macro_start;
- smac->in_progress = FALSE;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_UNDEF:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- if (tline->next)
- {
- error(ERR_WARNING,
- "trailing garbage after macro name ignored");
- }
-
- /* Find the context that symbol belongs to */
- ctx = get_ctx(tline->text, FALSE);
- if (!ctx)
- smhead = &smacros[hash(tline->text)];
- else
- smhead = &ctx->localmac;
-
- mname = tline->text;
- last = tline;
- last->next = NULL;
-
- /*
- * We now have a macro name... go hunt for it.
- */
- while (smacro_defined(ctx, mname, -1, &smac, 1))
- {
- /* Defined, so we need to find its predecessor and nuke it */
- SMacro **s;
- for (s = smhead; *s && *s != smac; s = &(*s)->next);
- if (*s)
- {
- *s = smac->next;
- nasm_free(smac->name);
- free_tlist(smac->expansion);
- nasm_free(smac);
- }
- }
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_STRLEN:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL,
- "`%%strlen' expects a macro identifier as first parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- ctx = get_ctx(tline->text, FALSE);
- if (!ctx)
- smhead = &smacros[hash(tline->text)];
- else
- smhead = &ctx->localmac;
- mname = tline->text;
- last = tline;
- tline = expand_smacro(tline->next);
- last->next = NULL;
-
- t = tline;
- while (tok_type_(t, TOK_WHITESPACE))
- t = t->next;
- /* t should now point to the string */
- if (t->type != TOK_STRING)
- {
- error(ERR_NONFATAL,
- "`%%strlen` requires string as second parameter");
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- macro_start = nasm_malloc(sizeof(*macro_start));
- macro_start->next = NULL;
- make_tok_num(macro_start, strlen(t->text) - 2);
- macro_start->mac = NULL;
-
- /*
- * We now have a macro name, an implicit parameter count of
- * zero, and a numeric token to use as an expansion. Create
- * and store an SMacro.
- */
- if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
- {
- if (!smac)
- error(ERR_WARNING,
- "single-line macro `%s' defined both with and"
- " without parameters", mname);
- else
- {
- /*
- * We're redefining, so we have to take over an
- * existing SMacro structure. This means freeing
- * what was already in it.
- */
- nasm_free(smac->name);
- free_tlist(smac->expansion);
- }
- }
- else
- {
- smac = nasm_malloc(sizeof(SMacro));
- smac->next = *smhead;
- *smhead = smac;
- }
- smac->name = nasm_strdup(mname);
- smac->casesense = (i == PP_STRLEN);
- smac->nparam = 0;
- smac->expansion = macro_start;
- smac->in_progress = FALSE;
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_SUBSTR:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL,
- "`%%substr' expects a macro identifier as first parameter");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- ctx = get_ctx(tline->text, FALSE);
- if (!ctx)
- smhead = &smacros[hash(tline->text)];
- else
- smhead = &ctx->localmac;
- mname = tline->text;
- last = tline;
- tline = expand_smacro(tline->next);
- last->next = NULL;
-
- t = tline->next;
- while (tok_type_(t, TOK_WHITESPACE))
- t = t->next;
-
- /* t should now point to the string */
- if (t->type != TOK_STRING)
- {
- error(ERR_NONFATAL,
- "`%%substr` requires string as second parameter");
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- tt = t->next;
- tptr = &tt;
- tokval.t_type = TOKEN_INVALID;
- evalresult =
- evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
- if (!evalresult)
- {
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- if (!nasm_is_simple(evalresult))
- {
- error(ERR_NONFATAL, "non-constant value given to `%%substr`");
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- macro_start = nasm_malloc(sizeof(*macro_start));
- macro_start->next = NULL;
- macro_start->text = nasm_strdup("'''");
- if (evalresult->value > 0
- && evalresult->value < strlen(t->text) - 1)
- {
- macro_start->text[1] = t->text[evalresult->value];
- }
- else
- {
- macro_start->text[2] = '\0';
- }
- macro_start->type = TOK_STRING;
- macro_start->mac = NULL;
-
- /*
- * We now have a macro name, an implicit parameter count of
- * zero, and a numeric token to use as an expansion. Create
- * and store an SMacro.
- */
- if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
- {
- if (!smac)
- error(ERR_WARNING,
- "single-line macro `%s' defined both with and"
- " without parameters", mname);
- else
- {
- /*
- * We're redefining, so we have to take over an
- * existing SMacro structure. This means freeing
- * what was already in it.
- */
- nasm_free(smac->name);
- free_tlist(smac->expansion);
- }
- }
- else
- {
- smac = nasm_malloc(sizeof(SMacro));
- smac->next = *smhead;
- *smhead = smac;
- }
- smac->name = nasm_strdup(mname);
- smac->casesense = (i == PP_SUBSTR);
- smac->nparam = 0;
- smac->expansion = macro_start;
- smac->in_progress = FALSE;
- free_tlist(tline);
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
-
- case PP_ASSIGN:
- case PP_IASSIGN:
- tline = tline->next;
- skip_white_(tline);
- tline = expand_id(tline);
- if (!tline || (tline->type != TOK_ID &&
- (tline->type != TOK_PREPROC_ID ||
- tline->text[1] != '$')))
- {
- error(ERR_NONFATAL,
- "`%%%sassign' expects a macro identifier",
- (i == PP_IASSIGN ? "i" : ""));
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- ctx = get_ctx(tline->text, FALSE);
- if (!ctx)
- smhead = &smacros[hash(tline->text)];
- else
- smhead = &ctx->localmac;
- mname = tline->text;
- last = tline;
- tline = expand_smacro(tline->next);
- last->next = NULL;
-
- t = tline;
- tptr = &t;
- tokval.t_type = TOKEN_INVALID;
- evalresult =
- evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
- free_tlist(tline);
- if (!evalresult)
- {
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- if (tokval.t_type)
- error(ERR_WARNING,
- "trailing garbage after expression ignored");
-
- if (!nasm_is_simple(evalresult))
- {
- error(ERR_NONFATAL,
- "non-constant value given to `%%%sassign'",
- (i == PP_IASSIGN ? "i" : ""));
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
-
- macro_start = nasm_malloc(sizeof(*macro_start));
- macro_start->next = NULL;
- make_tok_num(macro_start, nasm_reloc_value(evalresult));
- macro_start->mac = NULL;
-
- /*
- * We now have a macro name, an implicit parameter count of
- * zero, and a numeric token to use as an expansion. Create
- * and store an SMacro.
- */
- if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
- {
- if (!smac)
- error(ERR_WARNING,
- "single-line macro `%s' defined both with and"
- " without parameters", mname);
- else
- {
- /*
- * We're redefining, so we have to take over an
- * existing SMacro structure. This means freeing
- * what was already in it.
- */
- nasm_free(smac->name);
- free_tlist(smac->expansion);
- }
- }
- else
- {
- smac = nasm_malloc(sizeof(SMacro));
- smac->next = *smhead;
- *smhead = smac;
- }
- smac->name = nasm_strdup(mname);
- smac->casesense = (i == PP_ASSIGN);
- smac->nparam = 0;
- smac->expansion = macro_start;
- smac->in_progress = FALSE;
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- case PP_LINE:
- /*
- * Syntax is `%line nnn[+mmm] [filename]'
- */
- tline = tline->next;
- skip_white_(tline);
- if (!tok_type_(tline, TOK_NUMBER))
- {
- error(ERR_NONFATAL, "`%%line' expects line number");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- k = nasm_readnum(tline->text, &j);
- m = 1;
- tline = tline->next;
- if (tok_is_(tline, "+"))
- {
- tline = tline->next;
- if (!tok_type_(tline, TOK_NUMBER))
- {
- error(ERR_NONFATAL, "`%%line' expects line increment");
- free_tlist(origline);
- return DIRECTIVE_FOUND;
- }
- m = nasm_readnum(tline->text, &j);
- tline = tline->next;
- }
- skip_white_(tline);
- nasm_src_set_linnum(k);
- istk->lineinc = m;
- if (tline)
- {
- nasm_free(nasm_src_set_fname(detoken(tline, FALSE)));
- }
- free_tlist(origline);
- return DIRECTIVE_FOUND;
-
- default:
- error(ERR_FATAL,
- "preprocessor directive `%s' not yet implemented",
- directives[i]);
- break;
- }
- return DIRECTIVE_FOUND;
-}
-
-/*
- * Ensure that a macro parameter contains a condition code and
- * nothing else. Return the condition code index if so, or -1
- * otherwise.
- */
-static int
-find_cc(Token * t)
-{
- Token *tt;
- int i, j, k, m;
-
- skip_white_(t);
- if (t->type != TOK_ID)
- return -1;
- tt = t->next;
- skip_white_(tt);
- if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ",")))
- return -1;
-
- i = -1;
- j = elements(conditions);
- while (j - i > 1)
- {
- k = (j + i) / 2;
- m = nasm_stricmp(t->text, conditions[k]);
- if (m == 0)
- {
- i = k;
- j = -2;
- break;
- }
- else if (m < 0)
- {
- j = k;
- }
- else
- i = k;
- }
- if (j != -2)
- return -1;
- return i;
-}
-
-/*
- * Expand MMacro-local things: parameter references (%0, %n, %+n,
- * %-n) and MMacro-local identifiers (%%foo).
- */
-static Token *
-expand_mmac_params(Token * tline)
-{
- Token *t, *tt, **tail, *thead;
-
- tail = &thead;
- thead = NULL;
-
- while (tline)
- {
- if (tline->type == TOK_PREPROC_ID &&
- (((tline->text[1] == '+' || tline->text[1] == '-')
- && tline->text[2]) || tline->text[1] == '%'
- || (tline->text[1] >= '0' && tline->text[1] <= '9')))
- {
- char *text = NULL;
- int type = 0, cc; /* type = 0 to placate optimisers */
- char tmpbuf[30];
- int n, i;
- MMacro *mac;
-
- t = tline;
- tline = tline->next;
-
- mac = istk->mstk;
- while (mac && !mac->name) /* avoid mistaking %reps for macros */
- mac = mac->next_active;
- if (!mac)
- error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
- else
- switch (t->text[1])
- {
- /*
- * We have to make a substitution of one of the
- * forms %1, %-1, %+1, %%foo, %0.
- */
- case '0':
- type = TOK_NUMBER;
- sprintf(tmpbuf, "%d", mac->nparam);
- text = nasm_strdup(tmpbuf);
- break;
- case '%':
- type = TOK_ID;
- sprintf(tmpbuf, "..@%lu.", mac->unique);
- text = nasm_strcat(tmpbuf, t->text + 2);
- break;
- case '-':
- n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
- tt = NULL;
- else
- {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- cc = find_cc(tt);
- if (cc == -1)
- {
- error(ERR_NONFATAL,
- "macro parameter %d is not a condition code",
- n + 1);
- text = NULL;
- }
- else
- {
- type = TOK_ID;
- if (inverse_ccs[cc] == -1)
- {
- error(ERR_NONFATAL,
- "condition code `%s' is not invertible",
- conditions[cc]);
- text = NULL;
- }
- else
- text =
- nasm_strdup(conditions[inverse_ccs
- [cc]]);
- }
- break;
- case '+':
- n = atoi(t->text + 2) - 1;
- if (n >= mac->nparam)
- tt = NULL;
- else
- {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- cc = find_cc(tt);
- if (cc == -1)
- {
- error(ERR_NONFATAL,
- "macro parameter %d is not a condition code",
- n + 1);
- text = NULL;
- }
- else
- {
- type = TOK_ID;
- text = nasm_strdup(conditions[cc]);
- }
- break;
- default:
- n = atoi(t->text + 1) - 1;
- if (n >= mac->nparam)
- tt = NULL;
- else
- {
- if (mac->nparam > 1)
- n = (n + mac->rotate) % mac->nparam;
- tt = mac->params[n];
- }
- if (tt)
- {
- for (i = 0; i < mac->paramlen[n]; i++)
- {
- *tail =
- new_Token(NULL, tt->type, tt->text,
- 0);
- tail = &(*tail)->next;
- tt = tt->next;
- }
- }
- text = NULL; /* we've done it here */
- break;
- }
- if (!text)
- {
- delete_Token(t);
- }
- else
- {
- *tail = t;
- tail = &t->next;
- t->type = type;
- nasm_free(t->text);
- t->text = text;
- t->mac = NULL;
- }
- continue;
- }
- else
- {
- t = *tail = tline;
- tline = tline->next;
- t->mac = NULL;
- tail = &t->next;
- }
- }
- *tail = NULL;
- t = thead;
- for (; t && (tt = t->next) != NULL; t = t->next)
- switch (t->type)
- {
- case TOK_WHITESPACE:
- if (tt->type == TOK_WHITESPACE)
- {
- t->next = delete_Token(tt);
- }
- break;
- case TOK_ID:
- if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
- {
- char *tmp = nasm_strcat(t->text, tt->text);
- nasm_free(t->text);
- t->text = tmp;
- t->next = delete_Token(tt);
- }
- break;
- case TOK_NUMBER:
- if (tt->type == TOK_NUMBER)
- {
- char *tmp = nasm_strcat(t->text, tt->text);
- nasm_free(t->text);
- t->text = tmp;
- t->next = delete_Token(tt);
- }
- break;
- }
-
- return thead;
-}
-
-/*
- * Expand all single-line macro calls made in the given line.
- * Return the expanded version of the line. The original is deemed
- * to be destroyed in the process. (In reality we'll just move
- * Tokens from input to output a lot of the time, rather than
- * actually bothering to destroy and replicate.)
- */
-static Token *
-expand_smacro(Token * tline)
-{
- Token *t, *tt, *mstart, **tail, *thead;
- SMacro *head = NULL, *m;
- Token **params;
- int *paramsize;
- int nparam, sparam, brackets, rescan;
- Token *org_tline = tline;
- Context *ctx;
- char *mname;
-
- /*
- * Trick: we should avoid changing the start token pointer since it can
- * be contained in "next" field of other token. Because of this
- * we allocate a copy of first token and work with it; at the end of
- * routine we copy it back
- */
- if (org_tline)
- {
- tline =
- new_Token(org_tline->next, org_tline->type, org_tline->text,
- 0);
- tline->mac = org_tline->mac;
- nasm_free(org_tline->text);
- org_tline->text = NULL;
- }
-
- again:
- tail = &thead;
- thead = NULL;
-
- while (tline)
- { /* main token loop */
- if ((mname = tline->text))
- {
- /* if this token is a local macro, look in local context */
- if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
- ctx = get_ctx(mname, TRUE);
- else
- ctx = NULL;
- if (!ctx)
- head = smacros[hash(mname)];
- else
- head = ctx->localmac;
- /*
- * We've hit an identifier. As in is_mmacro below, we first
- * check whether the identifier is a single-line macro at
- * all, then think about checking for parameters if
- * necessary.
- */
- for (m = head; m; m = m->next)
- if (!mstrcmp(m->name, mname, m->casesense))
- break;
- if (m)
- {
- mstart = tline;
- params = NULL;
- paramsize = NULL;
- if (m->nparam == 0)
- {
- /*
- * Simple case: the macro is parameterless. Discard the
- * one token that the macro call took, and push the
- * expansion back on the to-do stack.
- */
- if (!m->expansion)
- {
- if (!strcmp("__FILE__", m->name))
- {
- long num = 0;
- nasm_src_get(&num, &(tline->text));
- nasm_quote(&(tline->text));
- tline->type = TOK_STRING;
- continue;
- }
- if (!strcmp("__LINE__", m->name))
- {
- nasm_free(tline->text);
- make_tok_num(tline, nasm_src_get_linnum());
- continue;
- }
- tline = delete_Token(tline);
- continue;
- }
- }
- else
- {
- /*
- * Complicated case: at least one macro with this name
- * exists and takes parameters. We must find the
- * parameters in the call, count them, find the SMacro
- * that corresponds to that form of the macro call, and
- * substitute for the parameters when we expand. What a
- * pain.
- */
- tline = tline->next;
- skip_white_(tline);
- if (!tok_is_(tline, "("))
- {
- /*
- * This macro wasn't called with parameters: ignore
- * the call. (Behaviour borrowed from gnu cpp.)
- */
- tline = mstart;
- m = NULL;
- }
- else
- {
- int paren = 0;
- int white = 0;
- brackets = 0;
- nparam = 0;
- tline = tline->next;
- sparam = PARAM_DELTA;
- params = nasm_malloc(sparam * sizeof(Token *));
- params[0] = tline;
- paramsize = nasm_malloc(sparam * sizeof(int));
- paramsize[0] = 0;
- for (;; tline = tline->next)
- { /* parameter loop */
- if (!tline)
- {
- error(ERR_NONFATAL,
- "macro call expects terminating `)'");
- break;
- }
- if (tline->type == TOK_WHITESPACE
- && brackets <= 0)
- {
- if (paramsize[nparam])
- white++;
- else
- params[nparam] = tline->next;
- continue; /* parameter loop */
- }
- if (tline->type == TOK_OTHER
- && tline->text[1] == 0)
- {
- char ch = tline->text[0];
- if (ch == ',' && !paren && brackets <= 0)
- {
- if (++nparam >= sparam)
- {
- sparam += PARAM_DELTA;
- params = nasm_realloc(params,
- sparam * sizeof(Token *));
- paramsize = nasm_realloc(paramsize,
- sparam * sizeof(int));
- }
- params[nparam] = tline->next;
- paramsize[nparam] = 0;
- white = 0;
- continue; /* parameter loop */
- }
- if (ch == '{' &&
- (brackets > 0 || (brackets == 0 &&
- !paramsize[nparam])))
- {
- if (!(brackets++))
- {
- params[nparam] = tline->next;
- continue; /* parameter loop */
- }
- }
- if (ch == '}' && brackets > 0)
- if (--brackets == 0)
- {
- brackets = -1;
- continue; /* parameter loop */
- }
- if (ch == '(' && !brackets)
- paren++;
- if (ch == ')' && brackets <= 0)
- if (--paren < 0)
- break;
- }
- if (brackets < 0)
- {
- brackets = 0;
- error(ERR_NONFATAL, "braces do not "
- "enclose all of macro parameter");
- }
- paramsize[nparam] += white + 1;
- white = 0;
- } /* parameter loop */
- nparam++;
- while (m && (m->nparam != nparam ||
- mstrcmp(m->name, mname,
- m->casesense)))
- m = m->next;
- if (!m)
- error(ERR_WARNING | ERR_WARN_MNP,
- "macro `%s' exists, "
- "but not taking %d parameters",
- mstart->text, nparam);
- }
- }
- if (m && m->in_progress)
- m = NULL;
- if (!m) /* in progess or didn't find '(' or wrong nparam */
- {
- /*
- * Design question: should we handle !tline, which
- * indicates missing ')' here, or expand those
- * macros anyway, which requires the (t) test a few
- * lines down?
- */
- nasm_free(params);
- nasm_free(paramsize);
- tline = mstart;
- }
- else
- {
- /*
- * Expand the macro: we are placed on the last token of the
- * call, so that we can easily split the call from the
- * following tokens. We also start by pushing an SMAC_END
- * token for the cycle removal.
- */
- t = tline;
- if (t)
- {
- tline = t->next;
- t->next = NULL;
- }
- tt = new_Token(tline, TOK_SMAC_END, NULL, 0);
- tt->mac = m;
- m->in_progress = TRUE;
- tline = tt;
- for (t = m->expansion; t; t = t->next)
- {
- if (t->type >= TOK_SMAC_PARAM)
- {
- Token *pcopy = tline, **ptail = &pcopy;
- Token *ttt, *pt;
- int i;
-
- ttt = params[t->type - TOK_SMAC_PARAM];
- for (i = paramsize[t->type - TOK_SMAC_PARAM];
- --i >= 0;)
- {
- pt = *ptail =
- new_Token(tline, ttt->type, ttt->text,
- 0);
- ptail = &pt->next;
- ttt = ttt->next;
- }
- tline = pcopy;
- }
- else
- {
- tt = new_Token(tline, t->type, t->text, 0);
- tline = tt;
- }
- }
-
- /*
- * Having done that, get rid of the macro call, and clean
- * up the parameters.
- */
- nasm_free(params);
- nasm_free(paramsize);
- free_tlist(mstart);
- continue; /* main token loop */
- }
- }
- }
-
- if (tline->type == TOK_SMAC_END)
- {
- tline->mac->in_progress = FALSE;
- tline = delete_Token(tline);
- }
- else
- {
- t = *tail = tline;
- tline = tline->next;
- t->mac = NULL;
- t->next = NULL;
- tail = &t->next;
- }
- }
-
- /*
- * Now scan the entire line and look for successive TOK_IDs that resulted
- * after expansion (they can't be produced by tokenise()). The successive
- * TOK_IDs should be concatenated.
- * Also we look for %+ tokens and concatenate the tokens before and after
- * them (without white spaces in between).
- */
- t = thead;
- rescan = 0;
- while (t)
- {
- while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
- t = t->next;
- if (!t || !t->next)
- break;
- if (t->next->type == TOK_ID ||
- t->next->type == TOK_PREPROC_ID ||
- t->next->type == TOK_NUMBER)
- {
- char *p = nasm_strcat(t->text, t->next->text);
- nasm_free(t->text);
- t->next = delete_Token(t->next);
- t->text = p;
- rescan = 1;
- }
- else if (t->next->type == TOK_WHITESPACE && t->next->next &&
- t->next->next->type == TOK_PREPROC_ID &&
- strcmp(t->next->next->text, "%+") == 0)
- {
- /* free the next whitespace, the %+ token and next whitespace */
- int i;
- for (i = 1; i <= 3; i++)
- {
- if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
- break;
- t->next = delete_Token(t->next);
- } /* endfor */
- }
- else
- t = t->next;
- }
- /* If we concatenaded something, re-scan the line for macros */
- if (rescan)
- {
- tline = thead;
- goto again;
- }
-
- if (org_tline)
- {
- if (thead)
- {
- *org_tline = *thead;
- /* since we just gave text to org_line, don't free it */
- thead->text = NULL;
- delete_Token(thead);
- }
- else
- {
- /* the expression expanded to empty line;
- we can't return NULL for some reasons
- we just set the line to a single WHITESPACE token. */
- memset(org_tline, 0, sizeof(*org_tline));
- org_tline->text = NULL;
- org_tline->type = TOK_WHITESPACE;
- }
- thead = org_tline;
- }
-
- return thead;
-}
-
-/*
- * Similar to expand_smacro but used exclusively with macro identifiers
- * right before they are fetched in. The reason is that there can be
- * identifiers consisting of several subparts. We consider that if there
- * are more than one element forming the name, user wants a expansion,
- * otherwise it will be left as-is. Example:
- *
- * %define %$abc cde
- *
- * the identifier %$abc will be left as-is so that the handler for %define
- * will suck it and define the corresponding value. Other case:
- *
- * %define _%$abc cde
- *
- * In this case user wants name to be expanded *before* %define starts
- * working, so we'll expand %$abc into something (if it has a value;
- * otherwise it will be left as-is) then concatenate all successive
- * PP_IDs into one.
- */
-static Token *
-expand_id(Token * tline)
-{
- Token *cur, *oldnext = NULL;
-
- if (!tline || !tline->next)
- return tline;
-
- cur = tline;
- while (cur->next &&
- (cur->next->type == TOK_ID ||
- cur->next->type == TOK_PREPROC_ID || cur->next->type == TOK_NUMBER))
- cur = cur->next;
-
- /* If identifier consists of just one token, don't expand */
- if (cur == tline)
- return tline;
-
- if (cur)
- {
- oldnext = cur->next; /* Detach the tail past identifier */
- cur->next = NULL; /* so that expand_smacro stops here */
- }
-
- tline = expand_smacro(tline);
-
- if (cur)
- {
- /* expand_smacro possibly changhed tline; re-scan for EOL */
- cur = tline;
- while (cur && cur->next)
- cur = cur->next;
- if (cur)
- cur->next = oldnext;
- }
-
- return tline;
-}
-
-/*
- * Determine whether the given line constitutes a multi-line macro
- * call, and return the MMacro structure called if so. Doesn't have
- * to check for an initial label - that's taken care of in
- * expand_mmacro - but must check numbers of parameters. Guaranteed
- * to be called with tline->type == TOK_ID, so the putative macro
- * name is easy to find.
- */
-static MMacro *
-is_mmacro(Token * tline, Token *** params_array)
-{
- MMacro *head, *m;
- Token **params;
- int nparam;
-
- head = mmacros[hash(tline->text)];
-
- /*
- * Efficiency: first we see if any macro exists with the given
- * name. If not, we can return NULL immediately. _Then_ we
- * count the parameters, and then we look further along the
- * list if necessary to find the proper MMacro.
- */
- for (m = head; m; m = m->next)
- if (!mstrcmp(m->name, tline->text, m->casesense))
- break;
- if (!m)
- return NULL;
-
- /*
- * OK, we have a potential macro. Count and demarcate the
- * parameters.
- */
- count_mmac_params(tline->next, &nparam, ¶ms);
-
- /*
- * So we know how many parameters we've got. Find the MMacro
- * structure that handles this number.
- */
- while (m)
- {
- if (m->nparam_min <= nparam && (m->plus || nparam <= m->nparam_max))
- {
- /*
- * This one is right. Just check if cycle removal
- * prohibits us using it before we actually celebrate...
- */
- if (m->in_progress)
- {
-#if 0
- error(ERR_NONFATAL,
- "self-reference in multi-line macro `%s'", m->name);
-#endif
- nasm_free(params);
- return NULL;
- }
- /*
- * It's right, and we can use it. Add its default
- * parameters to the end of our list if necessary.
- */
- if (m->defaults && nparam < m->nparam_min + m->ndefs)
- {
- params =
- nasm_realloc(params,
- ((m->nparam_min + m->ndefs + 1) * sizeof(*params)));
- while (nparam < m->nparam_min + m->ndefs)
- {
- params[nparam] = m->defaults[nparam - m->nparam_min];
- nparam++;
- }
- }
- /*
- * If we've gone over the maximum parameter count (and
- * we're in Plus mode), ignore parameters beyond
- * nparam_max.
- */
- if (m->plus && nparam > m->nparam_max)
- nparam = m->nparam_max;
- /*
- * Then terminate the parameter list, and leave.
- */
- if (!params)
- { /* need this special case */
- params = nasm_malloc(sizeof(*params));
- nparam = 0;
- }
- params[nparam] = NULL;
- *params_array = params;
- return m;
- }
- /*
- * This one wasn't right: look for the next one with the
- * same name.
- */
- for (m = m->next; m; m = m->next)
- if (!mstrcmp(m->name, tline->text, m->casesense))
- break;
- }
-
- /*
- * After all that, we didn't find one with the right number of
- * parameters. Issue a warning, and fail to expand the macro.
- */
- error(ERR_WARNING | ERR_WARN_MNP,
- "macro `%s' exists, but not taking %d parameters",
- tline->text, nparam);
- nasm_free(params);
- return NULL;
-}
-
-/*
- * Expand the multi-line macro call made by the given line, if
- * there is one to be expanded. If there is, push the expansion on
- * istk->expansion and return 1. Otherwise return 0.
- */
-static int
-expand_mmacro(Token * tline)
-{
- Token *startline = tline;
- Token *label = NULL;
- int dont_prepend = 0;
- Token **params, *t, *tt;
- MMacro *m;
- Line *l, *ll;
- int i, nparam, *paramlen;
-
- t = tline;
- skip_white_(t);
-/* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */
- if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID))
- return 0;
- m = is_mmacro(t, ¶ms);
- if (!m)
- {
- Token *last;
- /*
- * We have an id which isn't a macro call. We'll assume
- * it might be a label; we'll also check to see if a
- * colon follows it. Then, if there's another id after
- * that lot, we'll check it again for macro-hood.
- */
- label = last = t;
- t = t->next;
- if (tok_type_(t, TOK_WHITESPACE))
- last = t, t = t->next;
- if (tok_is_(t, ":"))
- {
- dont_prepend = 1;
- last = t, t = t->next;
- if (tok_type_(t, TOK_WHITESPACE))
- last = t, t = t->next;
- }
- if (!tok_type_(t, TOK_ID) || (m = is_mmacro(t, ¶ms)) == NULL)
- return 0;
- last->next = NULL;
- tline = t;
- }
-
- /*
- * Fix up the parameters: this involves stripping leading and
- * trailing whitespace, then stripping braces if they are
- * present.
- */
- for (nparam = 0; params[nparam]; nparam++)
- ;
- paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
-
- for (i = 0; params[i]; i++)
- {
- int brace = FALSE;
- int comma = (!m->plus || i < nparam - 1);
-
- t = params[i];
- skip_white_(t);
- if (tok_is_(t, "{"))
- t = t->next, brace = TRUE, comma = FALSE;
- params[i] = t;
- paramlen[i] = 0;
- while (t)
- {
- if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
- break; /* ... because we have hit a comma */
- if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
- break; /* ... or a space then a comma */
- if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
- break; /* ... or a brace */
- t = t->next;
- paramlen[i]++;
- }
- }
-
- /*
- * OK, we have a MMacro structure together with a set of
- * parameters. We must now go through the expansion and push
- * copies of each Line on to istk->expansion. Substitution of
- * parameter tokens and macro-local tokens doesn't get done
- * until the single-line macro substitution process; this is
- * because delaying them allows us to change the semantics
- * later through %rotate.
- *
- * First, push an end marker on to istk->expansion, mark this
- * macro as in progress, and set up its invocation-specific
- * variables.
- */
- ll = nasm_malloc(sizeof(Line));
- ll->next = istk->expansion;
- ll->finishes = m;
- ll->first = NULL;
- istk->expansion = ll;
-
- m->in_progress = TRUE;
- m->params = params;
- m->iline = tline;
- m->nparam = nparam;
- m->rotate = 0;
- m->paramlen = paramlen;
- m->unique = unique++;
- m->lineno = 0;
-
- m->next_active = istk->mstk;
- istk->mstk = m;
-
- for (l = m->expansion; l; l = l->next)
- {
- Token **tail;
-
- ll = nasm_malloc(sizeof(Line));
- ll->finishes = NULL;
- ll->next = istk->expansion;
- istk->expansion = ll;
- tail = &ll->first;
-
- for (t = l->first; t; t = t->next)
- {
- Token *x = t;
- if (t->type == TOK_PREPROC_ID &&
- t->text[1] == '0' && t->text[2] == '0')
- {
- dont_prepend = -1;
- x = label;
- if (!x)
- continue;
- }
- tt = *tail = new_Token(NULL, x->type, x->text, 0);
- tail = &tt->next;
- }
- *tail = NULL;
- }
-
- /*
- * If we had a label, push it on as the first line of
- * the macro expansion.
- */
- if (label)
- {
- if (dont_prepend < 0)
- free_tlist(startline);
- else
- {
- ll = nasm_malloc(sizeof(Line));
- ll->finishes = NULL;
- ll->next = istk->expansion;
- istk->expansion = ll;
- ll->first = startline;
- if (!dont_prepend)
- {
- while (label->next)
- label = label->next;
- label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
- }
- }
- }
-
- list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
-
- return 1;
-}
-
-/*
- * Since preprocessor always operate only on the line that didn't
- * arrived yet, we should always use ERR_OFFBY1. Also since user
- * won't want to see same error twice (preprocessing is done once
- * per pass) we will want to show errors only during pass one.
- */
-static void
-error(int severity, const char *fmt, ...)
-{
- va_list arg;
- char buff[1024];
-
- /* If we're in a dead branch of IF or something like it, ignore the error */
- if (istk && istk->conds && !emitting(istk->conds->state))
- return;
-
- va_start(arg, fmt);
- vsprintf(buff, fmt, arg);
- va_end(arg);
-
- if (istk && istk->mstk && istk->mstk->name)
- _error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
- istk->mstk->lineno, buff);
- else
- _error(severity | ERR_PASS1, "%s", buff);
-}
-
-static void
-pp_reset(FILE *f, const char *file, int apass, efunc errfunc, evalfunc eval,
- ListGen * listgen)
-{
- int h;
-
- _error = errfunc;
- cstk = NULL;
- istk = nasm_malloc(sizeof(Include));
- istk->next = NULL;
- istk->conds = NULL;
- istk->expansion = NULL;
- istk->mstk = NULL;
- istk->fp = f;
- istk->fname = NULL;
- nasm_src_set_fname(nasm_strdup(file));
- nasm_src_set_linnum(0);
- istk->lineinc = 1;
- defining = NULL;
- for (h = 0; h < NHASH; h++)
- {
- mmacros[h] = NULL;
- smacros[h] = NULL;
- }
- unique = 0;
- if (tasm_compatible_mode) {
- stdmacpos = stdmac;
- } else {
- stdmacpos = &stdmac[TASM_MACRO_COUNT];
- }
- any_extrastdmac = (extrastdmac != NULL);
- list = listgen;
- evaluate = eval;
- pass = apass;
-}
-
-static char *
-pp_getline(void)
-{
- char *line;
- Token *tline;
-
- while (1)
- {
- /*
- * Fetch a tokenised line, either from the macro-expansion
- * buffer or from the input file.
- */
- tline = NULL;
- while (istk->expansion && istk->expansion->finishes)
- {
- Line *l = istk->expansion;
- if (!l->finishes->name && l->finishes->in_progress > 1)
- {
- Line *ll;
-
- /*
- * This is a macro-end marker for a macro with no
- * name, which means it's not really a macro at all
- * but a %rep block, and the `in_progress' field is
- * more than 1, meaning that we still need to
- * repeat. (1 means the natural last repetition; 0
- * means termination by %exitrep.) We have
- * therefore expanded up to the %endrep, and must
- * push the whole block on to the expansion buffer
- * again. We don't bother to remove the macro-end
- * marker: we'd only have to generate another one
- * if we did.
- */
- l->finishes->in_progress--;
- for (l = l->finishes->expansion; l; l = l->next)
- {
- Token *t, *tt, **tail;
-
- ll = nasm_malloc(sizeof(Line));
- ll->next = istk->expansion;
- ll->finishes = NULL;
- ll->first = NULL;
- tail = &ll->first;
-
- for (t = l->first; t; t = t->next)
- {
- if (t->text || t->type == TOK_WHITESPACE)
- {
- tt = *tail = new_Token(NULL, t->type, t->text, 0);
- tail = &tt->next;
- }
- }
-
- istk->expansion = ll;
- }
- }
- else
- {
- /*
- * Check whether a `%rep' was started and not ended
- * within this macro expansion. This can happen and
- * should be detected. It's a fatal error because
- * I'm too confused to work out how to recover
- * sensibly from it.
- */
- if (defining)
- {
- if (defining->name)
- error(ERR_PANIC, "defining with name in expansion");
- else if (istk->mstk->name)
- error(ERR_FATAL, "`%%rep' without `%%endrep' within"
- " expansion of macro `%s'", istk->mstk->name);
- }
-
- /*
- * FIXME: investigate the relationship at this point between
- * istk->mstk and l->finishes
- */
- {
- MMacro *m = istk->mstk;
- istk->mstk = m->next_active;
- if (m->name)
- {
- /*
- * This was a real macro call, not a %rep, and
- * therefore the parameter information needs to
- * be freed.
- */
- nasm_free(m->params);
- free_tlist(m->iline);
- nasm_free(m->paramlen);
- l->finishes->in_progress = FALSE;
- }
- else
- free_mmacro(m);
- }
- istk->expansion = l->next;
- nasm_free(l);
- list->downlevel(LIST_MACRO);
- }
- }
- while (1)
- { /* until we get a line we can use */
-
- if (istk->expansion)
- { /* from a macro expansion */
- char *p;
- Line *l = istk->expansion;
- if (istk->mstk)
- istk->mstk->lineno++;
- tline = l->first;
- istk->expansion = l->next;
- nasm_free(l);
- p = detoken(tline, FALSE);
- list->line(LIST_MACRO, p);
- nasm_free(p);
- break;
- }
- line = read_line();
- if (line)
- { /* from the current input file */
- line = prepreproc(line);
- tline = tokenise(line);
- nasm_free(line);
- break;
- }
- /*
- * The current file has ended; work down the istk
- */
- {
- Include *i = istk;
- fclose(i->fp);
- if (i->conds)
- error(ERR_FATAL, "expected `%%endif' before end of file");
- /* only set line and file name if there's a next node */
- if (i->next)
- {
- nasm_src_set_linnum(i->lineno);
- nasm_free(nasm_src_set_fname(nasm_strdup(i->fname)));
- }
- istk = i->next;
- list->downlevel(LIST_INCLUDE);
- nasm_free(i);
- if (!istk)
- return NULL;
- }
- }
-
- /*
- * We must expand MMacro parameters and MMacro-local labels
- * _before_ we plunge into directive processing, to cope
- * with things like `%define something %1' such as STRUC
- * uses. Unless we're _defining_ a MMacro, in which case
- * those tokens should be left alone to go into the
- * definition; and unless we're in a non-emitting
- * condition, in which case we don't want to meddle with
- * anything.
- */
- if (!defining && !(istk->conds && !emitting(istk->conds->state)))
- tline = expand_mmac_params(tline);
-
- /*
- * Check the line to see if it's a preprocessor directive.
- */
- if (do_directive(tline) == DIRECTIVE_FOUND)
- {
- continue;
- }
- else if (defining)
- {
- /*
- * We're defining a multi-line macro. We emit nothing
- * at all, and just
- * shove the tokenised line on to the macro definition.
- */
- Line *l = nasm_malloc(sizeof(Line));
- l->next = defining->expansion;
- l->first = tline;
- l->finishes = FALSE;
- defining->expansion = l;
- continue;
- }
- else if (istk->conds && !emitting(istk->conds->state))
- {
- /*
- * We're in a non-emitting branch of a condition block.
- * Emit nothing at all, not even a blank line: when we
- * emerge from the condition we'll give a line-number
- * directive so we keep our place correctly.
- */
- free_tlist(tline);
- continue;
- }
- else if (istk->mstk && !istk->mstk->in_progress)
- {
- /*
- * We're in a %rep block which has been terminated, so
- * we're walking through to the %endrep without
- * emitting anything. Emit nothing at all, not even a
- * blank line: when we emerge from the %rep block we'll
- * give a line-number directive so we keep our place
- * correctly.
- */
- free_tlist(tline);
- continue;
- }
- else
- {
- tline = expand_smacro(tline);
- if (!expand_mmacro(tline))
- {
- /*
- * De-tokenise the line again, and emit it.
- */
- line = detoken(tline, TRUE);
- free_tlist(tline);
- break;
- }
- else
- {
- continue; /* expand_mmacro calls free_tlist */
- }
- }
- }
-
- return line;
-}
-
-static void
-pp_cleanup(int pass_)
-{
- int h;
-
- if (defining)
- {
- error(ERR_NONFATAL, "end of file while still defining macro `%s'",
- defining->name);
- free_mmacro(defining);
- }
- while (cstk)
- ctx_pop();
- for (h = 0; h < NHASH; h++)
- {
- while (mmacros[h])
- {
- MMacro *m = mmacros[h];
- mmacros[h] = mmacros[h]->next;
- free_mmacro(m);
- }
- while (smacros[h])
- {
- SMacro *s = smacros[h];
- smacros[h] = smacros[h]->next;
- nasm_free(s->name);
- free_tlist(s->expansion);
- nasm_free(s);
- }
- }
- while (istk)
- {
- Include *i = istk;
- istk = istk->next;
- fclose(i->fp);
- nasm_free(i->fname);
- nasm_free(i);
- }
- while (cstk)
- ctx_pop();
- if (pass_ == 0)
- {
- free_llist(predef);
- delete_Blocks();
- }
-}
-
-void
-pp_include_path(char *path)
-{
- IncPath *i;
-
- i = nasm_malloc(sizeof(IncPath));
- i->path = nasm_strdup(path);
- i->next = ipath;
- ipath = i;
-}
-
-void
-pp_pre_include(char *fname)
-{
- Token *inc, *space, *name;
- Line *l;
-
- name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0);
- space = new_Token(name, TOK_WHITESPACE, NULL, 0);
- inc = new_Token(space, TOK_PREPROC_ID, "%include", 0);
-
- l = nasm_malloc(sizeof(Line));
- l->next = predef;
- l->first = inc;
- l->finishes = FALSE;
- predef = l;
-}
-
-void
-pp_pre_define(char *definition)
-{
- Token *def, *space;
- Line *l;
- char *equals;
-
- equals = strchr(definition, '=');
- space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
- def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
- if (equals)
- *equals = ' ';
- space->next = tokenise(definition);
- if (equals)
- *equals = '=';
-
- l = nasm_malloc(sizeof(Line));
- l->next = predef;
- l->first = def;
- l->finishes = FALSE;
- predef = l;
-}
-
-void
-pp_pre_undefine(char *definition)
-{
- Token *def, *space;
- Line *l;
-
- space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
- def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
-
- l = nasm_malloc(sizeof(Line));
- l->next = predef;
- l->first = def;
- l->finishes = FALSE;
- predef = l;
-}
-
-void
-pp_extra_stdmac(const char **macros)
-{
- extrastdmac = macros;
-}
-
-static void
-make_tok_num(Token * tok, long val)
-{
- char numbuf[20];
- sprintf(numbuf, "%ld", val);
- tok->text = nasm_strdup(numbuf);
- tok->type = TOK_NUMBER;
-}
-
-Preproc nasmpp = {
- pp_reset,
- pp_getline,
- pp_cleanup
-};
+++ /dev/null
-/* preproc.h header file for preproc.c
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-
-#ifndef YASM_NASM_PREPROC_H
-#define YASM_NASM_PREPROC_H
-
-void pp_include_path (char *);
-void pp_pre_include (char *);
-void pp_pre_define (char *);
-void pp_pre_undefine (char *);
-void pp_extra_stdmac (const char **);
-
-extern Preproc nasmpp;
-
-#endif
+++ /dev/null
-/*
- * Imported NASM preprocessor - glue code
- *
- * Copyright (C) 2002 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-#include "linemgr.h"
-
-#include "preproc.h"
-#include "nasm.h"
-#include "nasmlib.h"
-#include "nasm-pp.h"
-#include "nasm-eval.h"
-
-static FILE *in;
-static yasm_linemgr *cur_lm;
-static char *line, *linepos;
-static size_t lineleft;
-static char *file_name;
-static long prior_linnum;
-static int lineinc;
-int tasm_compatible_mode = 0;
-
-
-static void
-nil_listgen_init(char *p, efunc e)
-{
-}
-
-static void
-nil_listgen_cleanup(void)
-{
-}
-
-static void
-nil_listgen_output(long v, const void *d, unsigned long v2)
-{
-}
-
-static void
-nil_listgen_line(int v, char *p)
-{
-}
-
-static void
-nil_listgen_uplevel(int v)
-{
-}
-
-static void
-nil_listgen_downlevel(int v)
-{
-}
-
-static ListGen nil_list = {
- nil_listgen_init,
- nil_listgen_cleanup,
- nil_listgen_output,
- nil_listgen_line,
- nil_listgen_uplevel,
- nil_listgen_downlevel
-};
-
-
-static void
-nasm_efunc(int severity, const char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- switch (severity & ERR_MASK) {
- case ERR_WARNING:
- yasm__warning_va(YASM_WARN_PREPROC, cur_lm->get_current(), fmt,
- va);
- break;
- case ERR_NONFATAL:
- yasm__error_va(cur_lm->get_current(), fmt, va);
- break;
- case ERR_FATAL:
- yasm_fatal(N_("unknown")); /* FIXME */
- break;
- case ERR_PANIC:
- yasm_internal_error(fmt); /* FIXME */
- break;
- case ERR_DEBUG:
- break;
- }
- va_end(va);
-}
-
-static void
-nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
-{
- in = f;
- cur_lm = lm;
- line = NULL;
- file_name = NULL;
- prior_linnum = 0;
- lineinc = 0;
- nasmpp.reset(f, in_filename, 2, nasm_efunc, nasm_evaluate, &nil_list);
-}
-
-static void
-nasm_preproc_cleanup(void)
-{
- nasmpp.cleanup(0);
-}
-
-static size_t
-nasm_preproc_input(char *buf, size_t max_size)
-{
- size_t tot = 0, n;
- long linnum = prior_linnum += lineinc;
- int altline;
-
- if (!line) {
- line = nasmpp.getline();
- if (!line)
- return 0;
- linepos = line;
- lineleft = strlen(line) + 1;
- line[lineleft-1] = '\n';
- }
-
- altline = nasm_src_get(&linnum, &file_name);
- if (altline) {
- if (altline == 1 && lineinc == 1) {
- *buf++ = '\n';
- max_size--;
- tot++;
- } else {
- lineinc = (altline != -1 || lineinc != 1);
- n = sprintf(buf, "%%line %ld+%d %s\n", linnum, lineinc, file_name);
- buf += n;
- max_size -= n;
- tot += n;
- }
- prior_linnum = linnum;
- }
-
- n = lineleft<max_size?lineleft:max_size;
- strncpy(buf, linepos, n);
- tot += n;
-
- if (n == lineleft) {
- yasm_xfree(line);
- line = NULL;
- } else {
- lineleft -= n;
- linepos += n;
- }
-
- return tot;
-}
-
-
-/* Define preproc structure -- see preproc.h for details */
-yasm_preproc yasm_nasm_LTX_preproc = {
- "Real NASM Preprocessor",
- "nasm",
- nasm_preproc_initialize,
- nasm_preproc_cleanup,
- nasm_preproc_input
-};
+++ /dev/null
-/* nasm.h main header file for the Netwide Assembler: inter-module interface
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- *
- * initial version: 27/iii/95 by Simon Tatham
- */
-#ifndef YASM_NASM_H
-#define YASM_NASM_H
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef FALSE
-#define FALSE 0 /* comes in handy */
-#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#define NO_SEG -1L /* null segment value */
-#define SEG_ABS 0x40000000L /* mask for far-absolute segments */
-
-#ifndef FILENAME_MAX
-#define FILENAME_MAX 256
-#endif
-
-#ifndef PREFIX_MAX
-#define PREFIX_MAX 10
-#endif
-
-#ifndef POSTFIX_MAX
-#define POSTFIX_MAX 10
-#endif
-
-
-
-/*
- * Name pollution problems: <time.h> on Digital UNIX pulls in some
- * strange hardware header file which sees fit to define R_SP. We
- * undefine it here so as not to break the enum below.
- */
-#ifdef R_SP
-#undef R_SP
-#endif
-
-/*
- * We must declare the existence of this structure type up here,
- * since we have to reference it before we define it...
- */
-struct ofmt;
-
-/*
- * -------------------------
- * Error reporting functions
- * -------------------------
- */
-
-/*
- * An error reporting function should look like this.
- */
-typedef void (*efunc) (int severity, const char *fmt, ...);
-
-/*
- * These are the error severity codes which get passed as the first
- * argument to an efunc.
- */
-
-#define ERR_DEBUG 0x00000008 /* put out debugging message */
-#define ERR_WARNING 0x00000000 /* warn only: no further action */
-#define ERR_NONFATAL 0x00000001 /* terminate assembly after phase */
-#define ERR_FATAL 0x00000002 /* instantly fatal: exit with error */
-#define ERR_PANIC 0x00000003 /* internal error: panic instantly
- * and dump core for reference */
-#define ERR_MASK 0x0000000F /* mask off the above codes */
-#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
-#define ERR_USAGE 0x00000020 /* print a usage message */
-#define ERR_PASS1 0x00000040 /* only print this error on pass one */
-
-/*
- * These codes define specific types of suppressible warning.
- */
-
-#define ERR_WARN_MASK 0x0000FF00 /* the mask for this feature */
-#define ERR_WARN_SHR 8 /* how far to shift right */
-
-#define ERR_WARN_MNP 0x00000100 /* macro-num-parameters warning */
-#define ERR_WARN_MSR 0x00000200 /* macro self-reference */
-#define ERR_WARN_OL 0x00000300 /* orphan label (no colon, and
- * alone on line) */
-#define ERR_WARN_NOV 0x00000400 /* numeric overflow */
-#define ERR_WARN_GNUELF 0x00000500 /* using GNU ELF extensions */
-#define ERR_WARN_MAX 5 /* the highest numbered one */
-
-/*
- * -----------------------
- * Other function typedefs
- * -----------------------
- */
-
-/*
- * A label-lookup function should look like this.
- */
-typedef int (*lfunc) (char *label, long *segment, long *offset);
-
-/*
- * And a label-definition function like this. The boolean parameter
- * `is_norm' states whether the label is a `normal' label (which
- * should affect the local-label system), or something odder like
- * an EQU or a segment-base symbol, which shouldn't.
- */
-typedef void (*ldfunc) (char *label, long segment, long offset, char *special,
- int is_norm, int isextrn, struct ofmt *ofmt,
- efunc error);
-
-/*
- * List-file generators should look like this:
- */
-typedef struct {
- /*
- * Called to initialise the listing file generator. Before this
- * is called, the other routines will silently do nothing when
- * called. The `char *' parameter is the file name to write the
- * listing to.
- */
- void (*init) (char *, efunc);
-
- /*
- * Called to clear stuff up and close the listing file.
- */
- void (*cleanup) (void);
-
- /*
- * Called to output binary data. Parameters are: the offset;
- * the data; the data type. Data types are similar to the
- * output-format interface, only OUT_ADDRESS will _always_ be
- * displayed as if it's relocatable, so ensure that any non-
- * relocatable address has been converted to OUT_RAWDATA by
- * then. Note that OUT_RAWDATA+0 is a valid data type, and is a
- * dummy call used to give the listing generator an offset to
- * work with when doing things like uplevel(LIST_TIMES) or
- * uplevel(LIST_INCBIN).
- */
- void (*output) (long, const void *, unsigned long);
-
- /*
- * Called to send a text line to the listing generator. The
- * `int' parameter is LIST_READ or LIST_MACRO depending on
- * whether the line came directly from an input file or is the
- * result of a multi-line macro expansion.
- */
- void (*line) (int, char *);
-
- /*
- * Called to change one of the various levelled mechanisms in
- * the listing generator. LIST_INCLUDE and LIST_MACRO can be
- * used to increase the nesting level of include files and
- * macro expansions; LIST_TIMES and LIST_INCBIN switch on the
- * two binary-output-suppression mechanisms for large-scale
- * pseudo-instructions.
- *
- * LIST_MACRO_NOLIST is synonymous with LIST_MACRO except that
- * it indicates the beginning of the expansion of a `nolist'
- * macro, so anything under that level won't be expanded unless
- * it includes another file.
- */
- void (*uplevel) (int);
-
- /*
- * Reverse the effects of uplevel.
- */
- void (*downlevel) (int);
-} ListGen;
-
-/*
- * The expression evaluator must be passed a scanner function; a
- * standard scanner is provided as part of nasmlib.c. The
- * preprocessor will use a different one. Scanners, and the
- * token-value structures they return, look like this.
- *
- * The return value from the scanner is always a copy of the
- * `t_type' field in the structure.
- */
-struct tokenval {
- int t_type;
- long t_integer, t_inttwo;
- char *t_charptr;
-};
-typedef int (*scanner) (void *private_data, struct tokenval *tv);
-
-/*
- * Token types returned by the scanner, in addition to ordinary
- * ASCII character values, and zero for end-of-string.
- */
-enum { /* token types, other than chars */
- TOKEN_INVALID = -1, /* a placeholder value */
- TOKEN_EOS = 0, /* end of string */
- TOKEN_EQ = '=', TOKEN_GT = '>', TOKEN_LT = '<', /* aliases */
- TOKEN_ID = 256, TOKEN_NUM, TOKEN_REG, TOKEN_INSN, /* major token types */
- TOKEN_ERRNUM, /* numeric constant with error in */
- TOKEN_HERE, TOKEN_BASE, /* $ and $$ */
- TOKEN_SPECIAL, /* BYTE, WORD, DWORD, FAR, NEAR, etc */
- TOKEN_PREFIX, /* A32, O16, LOCK, REPNZ, TIMES, etc */
- TOKEN_SHL, TOKEN_SHR, /* << and >> */
- TOKEN_SDIV, TOKEN_SMOD, /* // and %% */
- TOKEN_GE, TOKEN_LE, TOKEN_NE, /* >=, <= and <> (!= is same as <>) */
- TOKEN_DBL_AND, TOKEN_DBL_OR, TOKEN_DBL_XOR, /* &&, || and ^^ */
- TOKEN_SEG, TOKEN_WRT, /* SEG and WRT */
- TOKEN_FLOAT /* floating-point constant */
-};
-
-typedef struct {
- long segment;
- long offset;
- int known;
-} loc_t;
-
-/*
- * Expression-evaluator datatype. Expressions, within the
- * evaluator, are stored as an array of these beasts, terminated by
- * a record with type==0. Mostly, it's a vector type: each type
- * denotes some kind of a component, and the value denotes the
- * multiple of that component present in the expression. The
- * exception is the WRT type, whose `value' field denotes the
- * segment to which the expression is relative. These segments will
- * be segment-base types, i.e. either odd segment values or SEG_ABS
- * types. So it is still valid to assume that anything with a
- * `value' field of zero is insignificant.
- */
-typedef struct {
- long type; /* a register, or EXPR_xxx */
- long value; /* must be >= 32 bits */
-} nasm_expr;
-
-/*
- * The evaluator can also return hints about which of two registers
- * used in an expression should be the base register. See also the
- * `operand' structure.
- */
-struct eval_hints {
- int base;
- int type;
-};
-
-/*
- * The actual expression evaluator function looks like this. When
- * called, it expects the first token of its expression to already
- * be in `*tv'; if it is not, set tv->t_type to TOKEN_INVALID and
- * it will start by calling the scanner.
- *
- * If a forward reference happens during evaluation, the evaluator
- * must set `*fwref' to TRUE if `fwref' is non-NULL.
- *
- * `critical' is non-zero if the expression may not contain forward
- * references. The evaluator will report its own error if this
- * occurs; if `critical' is 1, the error will be "symbol not
- * defined before use", whereas if `critical' is 2, the error will
- * be "symbol undefined".
- *
- * If `critical' has bit 8 set (in addition to its main value: 0x101
- * and 0x102 correspond to 1 and 2) then an extended expression
- * syntax is recognised, in which relational operators such as =, <
- * and >= are accepted, as well as low-precedence logical operators
- * &&, ^^ and ||.
- *
- * If `hints' is non-NULL, it gets filled in with some hints as to
- * the base register in complex effective addresses.
- */
-#define CRITICAL 0x100
-typedef nasm_expr *(*evalfunc) (scanner sc, void *scprivate, struct tokenval *tv,
- int *fwref, int critical, efunc error,
- struct eval_hints *hints);
-
-/*
- * Special values for expr->type. ASSUMPTION MADE HERE: the number
- * of distinct register names (i.e. possible "type" fields for an
- * expr structure) does not exceed 124 (EXPR_REG_START through
- * EXPR_REG_END).
- */
-#define EXPR_REG_START 1
-#define EXPR_REG_END 124
-#define EXPR_UNKNOWN 125L /* for forward references */
-#define EXPR_SIMPLE 126L
-#define EXPR_WRT 127L
-#define EXPR_SEGBASE 128L
-
-/*
- * Preprocessors ought to look like this:
- */
-typedef struct {
- /*
- * Called at the start of a pass; given a file name, the number
- * of the pass, an error reporting function, an evaluator
- * function, and a listing generator to talk to.
- */
- void (*reset) (FILE *, const char *, int, efunc, evalfunc, ListGen *);
-
- /*
- * Called to fetch a line of preprocessed source. The line
- * returned has been malloc'ed, and so should be freed after
- * use.
- */
- char *(*getline) (void);
-
- /*
- * Called at the end of a pass.
- */
- void (*cleanup) (int);
-} Preproc;
-
-/*
- * ----------------------------------------------------------------
- * Some lexical properties of the NASM source language, included
- * here because they are shared between the parser and preprocessor
- * ----------------------------------------------------------------
- */
-
-/*
- * isidstart matches any character that may start an identifier, and isidchar
- * matches any character that may appear at places other than the start of an
- * identifier. E.g. a period may only appear at the start of an identifier
- * (for local labels), whereas a number may appear anywhere *but* at the
- * start.
- */
-
-#define isidstart(c) ( isalpha(c) || (c)=='_' || (c)=='.' || (c)=='?' \
- || (c)=='@' )
-#define isidchar(c) ( isidstart(c) || isdigit(c) || (c)=='$' || (c)=='#' \
- || (c)=='~' )
-
-/* Ditto for numeric constants. */
-
-#define isnumstart(c) ( isdigit(c) || (c)=='$' )
-#define isnumchar(c) ( isalnum(c) )
-
-/* This returns the numeric value of a given 'digit'. */
-
-#define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
-
-/*
- * Data-type flags that get passed to listing-file routines.
- */
-enum {
- LIST_READ, LIST_MACRO, LIST_MACRO_NOLIST, LIST_INCLUDE,
- LIST_INCBIN, LIST_TIMES
-};
-
-/*
- * -----------------------------------------------------------
- * Format of the `insn' structure returned from `parser.c' and
- * passed into `assemble.c'
- * -----------------------------------------------------------
- */
-
-/*
- * Here we define the operand types. These are implemented as bit
- * masks, since some are subsets of others; e.g. AX in a MOV
- * instruction is a special operand type, whereas AX in other
- * contexts is just another 16-bit register. (Also, consider CL in
- * shift instructions, DX in OUT, etc.)
- */
-
-/* size, and other attributes, of the operand */
-#define BITS8 0x00000001L
-#define BITS16 0x00000002L
-#define BITS32 0x00000004L
-#define BITS64 0x00000008L /* FPU only */
-#define BITS80 0x00000010L /* FPU only */
-#define FAR 0x00000020L /* grotty: this means 16:16 or */
- /* 16:32, like in CALL/JMP */
-#define NEAR 0x00000040L
-#define SHORT 0x00000080L /* and this means what it says :) */
-
-#define SIZE_MASK 0x000000FFL /* all the size attributes */
-#define NON_SIZE (~SIZE_MASK)
-
-#define TO 0x00000100L /* reverse effect in FADD, FSUB &c */
-#define COLON 0x00000200L /* operand is followed by a colon */
-#define STRICT 0x00000400L /* do not optimize this operand */
-
-/* type of operand: memory reference, register, etc. */
-#define MEMORY 0x00204000L
-#define REGISTER 0x00001000L /* register number in 'basereg' */
-#define IMMEDIATE 0x00002000L
-
-#define REGMEM 0x00200000L /* for r/m, ie EA, operands */
-#define REGNORM 0x00201000L /* 'normal' reg, qualifies as EA */
-#define REG8 0x00201001L
-#define REG16 0x00201002L
-#define REG32 0x00201004L
-#define MMXREG 0x00201008L /* MMX registers */
-#define XMMREG 0x00201010L /* XMM Katmai reg */
-#define FPUREG 0x01000000L /* floating point stack registers */
-#define FPU0 0x01000800L /* FPU stack register zero */
-
-/* special register operands: these may be treated differently */
-#define REG_SMASK 0x00070000L /* a mask for the following */
-#define REG_ACCUM 0x00211000L /* accumulator: AL, AX or EAX */
-#define REG_AL 0x00211001L /* REG_ACCUM | BITSxx */
-#define REG_AX 0x00211002L /* ditto */
-#define REG_EAX 0x00211004L /* and again */
-#define REG_COUNT 0x00221000L /* counter: CL, CX or ECX */
-#define REG_CL 0x00221001L /* REG_COUNT | BITSxx */
-#define REG_CX 0x00221002L /* ditto */
-#define REG_ECX 0x00221004L /* another one */
-#define REG_DX 0x00241002L
-#define REG_SREG 0x00081002L /* any segment register */
-#define REG_CS 0x01081002L /* CS */
-#define REG_DESS 0x02081002L /* DS, ES, SS (non-CS 86 registers) */
-#define REG_FSGS 0x04081002L /* FS, GS (386 extended registers) */
-#define REG_SEG67 0x08081002L /* Non-implemented segment registers */
-#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
-#define REG_CREG 0x08101004L /* CRn */
-#define REG_DREG 0x10101004L /* DRn */
-#define REG_TREG 0x20101004L /* TRn */
-
-/* special type of EA */
-#define MEM_OFFS 0x00604000L /* simple [address] offset */
-
-/* special type of immediate operand */
-#define ONENESS 0x00800000L /* so UNITY == IMMEDIATE | ONENESS */
-#define UNITY 0x00802000L /* for shift/rotate instructions */
-#define BYTENESS 0x40000000L /* so SBYTE == IMMEDIATE | BYTENESS */
-#define SBYTE 0x40002000L /* for op r16/32,immediate instrs. */
-
-
-/* Register names automatically generated from regs.dat */
-/*#include "regs.h"*/
-
-enum { /* condition code names */
- C_A, C_AE, C_B, C_BE, C_C, C_E, C_G, C_GE, C_L, C_LE, C_NA, C_NAE,
- C_NB, C_NBE, C_NC, C_NE, C_NG, C_NGE, C_NL, C_NLE, C_NO, C_NP,
- C_NS, C_NZ, C_O, C_P, C_PE, C_PO, C_S, C_Z
-};
-#if 0
-/*
- * Note that because segment registers may be used as instruction
- * prefixes, we must ensure the enumerations for prefixes and
- * register names do not overlap.
- */
-enum { /* instruction prefixes */
- PREFIX_ENUM_START = REG_ENUM_LIMIT,
- P_A16 = PREFIX_ENUM_START, P_A32, P_LOCK, P_O16, P_O32, P_REP, P_REPE,
- P_REPNE, P_REPNZ, P_REPZ, P_TIMES
-};
-#endif
-enum { /* extended operand types */
- EOT_NOTHING, EOT_DB_STRING, EOT_DB_NUMBER
-};
-
-enum { /* special EA flags */
- EAF_BYTEOFFS = 1, /* force offset part to byte size */
- EAF_WORDOFFS = 2, /* force offset part to [d]word size */
- EAF_TIMESTWO = 4 /* really do EAX*2 not EAX+EAX */
-};
-
-enum { /* values for `hinttype' */
- EAH_NOHINT = 0, /* no hint at all - our discretion */
- EAH_MAKEBASE = 1, /* try to make given reg the base */
- EAH_NOTBASE = 2 /* try _not_ to make reg the base */
-};
-
-typedef struct { /* operand to an instruction */
- long type; /* type of operand */
- int addr_size; /* 0 means default; 16; 32 */
- int basereg, indexreg, scale; /* registers and scale involved */
- int hintbase, hinttype; /* hint as to real base register */
- long segment; /* immediate segment, if needed */
- long offset; /* any immediate number */
- long wrt; /* segment base it's relative to */
- int eaflags; /* special EA flags */
- int opflags; /* see OPFLAG_* defines below */
-} operand;
-
-#define OPFLAG_FORWARD 1 /* operand is a forward reference */
-#define OPFLAG_EXTERN 2 /* operand is an external reference */
-
-typedef struct extop { /* extended operand */
- struct extop *next; /* linked list */
- long type; /* defined above */
- char *stringval; /* if it's a string, then here it is */
- int stringlen; /* ... and here's how long it is */
- long segment; /* if it's a number/address, then... */
- long offset; /* ... it's given here ... */
- long wrt; /* ... and here */
-} extop;
-
-#define MAXPREFIX 4
-
-typedef struct { /* an instruction itself */
- char *label; /* the label defined, or NULL */
- int prefixes[MAXPREFIX]; /* instruction prefixes, if any */
- int nprefix; /* number of entries in above */
- int opcode; /* the opcode - not just the string */
- int condition; /* the condition code, if Jcc/SETcc */
- int operands; /* how many operands? 0-3
- * (more if db et al) */
- operand oprs[3]; /* the operands, defined as above */
- extop *eops; /* extended operands */
- int eops_float; /* true if DD and floating */
- long times; /* repeat count (TIMES prefix) */
- int forw_ref; /* is there a forward reference? */
-} insn;
-
-enum geninfo { GI_SWITCH };
-/*
- * ------------------------------------------------------------
- * The data structure defining an output format driver, and the
- * interfaces to the functions therein.
- * ------------------------------------------------------------
- */
-
-struct ofmt {
- /*
- * This is a short (one-liner) description of the type of
- * output generated by the driver.
- */
- const char *fullname;
-
- /*
- * This is a single keyword used to select the driver.
- */
- const char *shortname;
-
- /*
- * this is reserved for out module specific help.
- * It is set to NULL in all the out modules but is not implemented
- * in the main program
- */
- const char *helpstring;
-
- /*
- * this is a pointer to the first element of the debug information
- */
- struct dfmt **debug_formats;
-
- /*
- * and a pointer to the element that is being used
- * note: this is set to the default at compile time and changed if the
- * -F option is selected. If developing a set of new debug formats for
- * an output format, be sure to set this to whatever default you want
- *
- */
- struct dfmt *current_dfmt;
-
- /*
- * This, if non-NULL, is a NULL-terminated list of `char *'s
- * pointing to extra standard macros supplied by the object
- * format (e.g. a sensible initial default value of __SECT__,
- * and user-level equivalents for any format-specific
- * directives).
- */
- const char **stdmac;
-
- /*
- * This procedure is called at the start of an output session.
- * It tells the output format what file it will be writing to,
- * what routine to report errors through, and how to interface
- * to the label manager and expression evaluator if necessary.
- * It also gives it a chance to do other initialisation.
- */
- void (*init) (FILE *fp, efunc error, ldfunc ldef, evalfunc eval);
-
- /*
- * This procedure is called to pass generic information to the
- * object file. The first parameter gives the information type
- * (currently only command line switches)
- * and the second parameter gives the value. This function returns
- * 1 if recognized, 0 if unrecognized
- */
- int (*setinfo)(enum geninfo type, char **string);
-
- /*
- * This procedure is called by assemble() to write actual
- * generated code or data to the object file. Typically it
- * doesn't have to actually _write_ it, just store it for
- * later.
- *
- * The `type' argument specifies the type of output data, and
- * usually the size as well: its contents are described below.
- */
- void (*output) (long segto, const void *data, unsigned long type,
- long segment, long wrt);
-
- /*
- * This procedure is called once for every symbol defined in
- * the module being assembled. It gives the name and value of
- * the symbol, in NASM's terms, and indicates whether it has
- * been declared to be global. Note that the parameter "name",
- * when passed, will point to a piece of static storage
- * allocated inside the label manager - it's safe to keep using
- * that pointer, because the label manager doesn't clean up
- * until after the output driver has.
- *
- * Values of `is_global' are: 0 means the symbol is local; 1
- * means the symbol is global; 2 means the symbol is common (in
- * which case `offset' holds the _size_ of the variable).
- * Anything else is available for the output driver to use
- * internally.
- *
- * This routine explicitly _is_ allowed to call the label
- * manager to define further symbols, if it wants to, even
- * though it's been called _from_ the label manager. That much
- * re-entrancy is guaranteed in the label manager. However, the
- * label manager will in turn call this routine, so it should
- * be prepared to be re-entrant itself.
- *
- * The `special' parameter contains special information passed
- * through from the command that defined the label: it may have
- * been an EXTERN, a COMMON or a GLOBAL. The distinction should
- * be obvious to the output format from the other parameters.
- */
- void (*symdef) (char *name, long segment, long offset, int is_global,
- char *special);
-
- /*
- * This procedure is called when the source code requests a
- * segment change. It should return the corresponding segment
- * _number_ for the name, or NO_SEG if the name is not a valid
- * segment name.
- *
- * It may also be called with NULL, in which case it is to
- * return the _default_ section number for starting assembly in.
- *
- * It is allowed to modify the string it is given a pointer to.
- *
- * It is also allowed to specify a default instruction size for
- * the segment, by setting `*bits' to 16 or 32. Or, if it
- * doesn't wish to define a default, it can leave `bits' alone.
- */
- long (*section) (char *name, int pass, int *bits);
-
- /*
- * This procedure is called to modify the segment base values
- * returned from the SEG operator. It is given a segment base
- * value (i.e. a segment value with the low bit set), and is
- * required to produce in return a segment value which may be
- * different. It can map segment bases to absolute numbers by
- * means of returning SEG_ABS types.
- *
- * It should return NO_SEG if the segment base cannot be
- * determined; the evaluator (which calls this routine) is
- * responsible for throwing an error condition if that occurs
- * in pass two or in a critical expression.
- */
- long (*segbase) (long segment);
-
- /*
- * This procedure is called to allow the output driver to
- * process its own specific directives. When called, it has the
- * directive word in `directive' and the parameter string in
- * `value'. It is called in both assembly passes, and `pass'
- * will be either 1 or 2.
- *
- * This procedure should return zero if it does not _recognise_
- * the directive, so that the main program can report an error.
- * If it recognises the directive but then has its own errors,
- * it should report them itself and then return non-zero. It
- * should also return non-zero if it correctly processes the
- * directive.
- */
- int (*directive) (char *directive, char *value, int pass);
-
- /*
- * This procedure is called before anything else - even before
- * the "init" routine - and is passed the name of the input
- * file from which this output file is being generated. It
- * should return its preferred name for the output file in
- * `outname', if outname[0] is not '\0', and do nothing to
- * `outname' otherwise. Since it is called before the driver is
- * properly initialised, it has to be passed its error handler
- * separately.
- *
- * This procedure may also take its own copy of the input file
- * name for use in writing the output file: it is _guaranteed_
- * that it will be called before the "init" routine.
- *
- * The parameter `outname' points to an area of storage
- * guaranteed to be at least FILENAME_MAX in size.
- */
- void (*filename) (char *inname, char *outname, efunc error);
-
- /*
- * This procedure is called after assembly finishes, to allow
- * the output driver to clean itself up and free its memory.
- * Typically, it will also be the point at which the object
- * file actually gets _written_.
- *
- * One thing the cleanup routine should always do is to close
- * the output file pointer.
- */
- void (*cleanup) (int debuginfo);
-};
-
-/*
- * values for the `type' parameter to an output function. Each one
- * must have the actual number of _bytes_ added to it.
- *
- * Exceptions are OUT_RELxADR, which denote an x-byte relocation
- * which will be a relative jump. For this we need to know the
- * distance in bytes from the start of the relocated record until
- * the end of the containing instruction. _This_ is what is stored
- * in the size part of the parameter, in this case.
- *
- * Also OUT_RESERVE denotes reservation of N bytes of BSS space,
- * and the contents of the "data" parameter is irrelevant.
- *
- * The "data" parameter for the output function points to a "long",
- * containing the address in question, unless the type is
- * OUT_RAWDATA, in which case it points to an "unsigned char"
- * array.
- */
-#define OUT_RAWDATA 0x00000000UL
-#define OUT_ADDRESS 0x10000000UL
-#define OUT_REL2ADR 0x20000000UL
-#define OUT_REL4ADR 0x30000000UL
-#define OUT_RESERVE 0x40000000UL
-#define OUT_TYPMASK 0xF0000000UL
-#define OUT_SIZMASK 0x0FFFFFFFUL
-
-/*
- * ------------------------------------------------------------
- * The data structure defining a debug format driver, and the
- * interfaces to the functions therein.
- * ------------------------------------------------------------
- */
-
-struct dfmt {
-
- /*
- * This is a short (one-liner) description of the type of
- * output generated by the driver.
- */
- const char *fullname;
-
- /*
- * This is a single keyword used to select the driver.
- */
- const char *shortname;
-
-
- /*
- * init - called initially to set up local pointer to object format,
- * void pointer to implementation defined data, file pointer (which
- * probably won't be used, but who knows?), and error function.
- */
- void (*init) (struct ofmt * of, void * id, FILE * fp, efunc error);
-
- /*
- * linenum - called any time there is output with a change of
- * line number or file.
- */
- void (*linenum) (const char * filename, long linenumber, long segto);
-
- /*
- * debug_deflabel - called whenever a label is defined. Parameters
- * are the same as to 'symdef()' in the output format. This function
- * would be called before the output format version.
- */
-
- void (*debug_deflabel) (char * name, long segment, long offset,
- int is_global, char * special);
- /*
- * debug_directive - called whenever a DEBUG directive other than 'LINE'
- * is encountered. 'directive' contains the first parameter to the
- * DEBUG directive, and params contains the rest. For example,
- * 'DEBUG VAR _somevar:int' would translate to a call to this
- * function with 'directive' equal to "VAR" and 'params' equal to
- * "_somevar:int".
- */
- void (*debug_directive) (const char * directive, const char * params);
-
- /*
- * typevalue - called whenever the assembler wishes to register a type
- * for the last defined label. This routine MUST detect if a type was
- * already registered and not re-register it.
- */
- void (*debug_typevalue) (long type);
-
- /*
- * debug_output - called whenever output is required
- * 'type' is the type of info required, and this is format-specific
- */
- void (*debug_output) (int type, void *param);
-
- /*
- * cleanup - called after processing of file is complete
- */
- void (*cleanup) (void);
-
-};
-/*
- * The type definition macros
- * for debugging
- *
- * low 3 bits: reserved
- * next 5 bits: type
- * next 24 bits: number of elements for arrays (0 for labels)
- */
-
-#define TY_UNKNOWN 0x00
-#define TY_LABEL 0x08
-#define TY_BYTE 0x10
-#define TY_WORD 0x18
-#define TY_DWORD 0x20
-#define TY_FLOAT 0x28
-#define TY_QWORD 0x30
-#define TY_TBYTE 0x38
-#define TY_COMMON 0xE0
-#define TY_SEG 0xE8
-#define TY_EXTERN 0xF0
-#define TY_EQU 0xF8
-
-#define TYM_TYPE(x) ((x) & 0xF8)
-#define TYM_ELEMENTS(x) (((x) & 0xFFFFFF00) >> 8)
-
-#define TYS_ELEMENTS(x) ((x) << 8)
-/*
- * -----
- * Other
- * -----
- */
-
-/*
- * This is a useful #define which I keep meaning to use more often:
- * the number of elements of a statically defined array.
- */
-
-#define elements(x) ( sizeof(x) / sizeof(*(x)) )
-
-extern int tasm_compatible_mode;
-
-/*
- * This declaration passes the "pass" number to all other modules
- * "pass0" assumes the values: 0, 0, ..., 0, 1, 2
- * where 0 = optimizing pass
- * 1 = pass 1
- * 2 = pass 2
- */
-
-extern int pass0; /* this is globally known */
-extern int optimizing;
-
-#endif
+++ /dev/null
-/* nasmlib.c library routines for the Netwide Assembler
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-#include "util.h"
-#include <ctype.h>
-
-#include "nasm.h"
-#include "nasmlib.h"
-/*#include "insns.h"*/ /* For MAX_KEYWORD */
-
-#define lib_isnumchar(c) ( isalnum(c) || (c) == '$')
-#define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
-
-long nasm_readnum (char *str, int *error)
-{
- char *r = str, *q;
- long radix;
- unsigned long result, checklimit;
- int digit, last;
- int warn = FALSE;
- int sign = 1;
-
- *error = FALSE;
-
- while (isspace(*r)) r++; /* find start of number */
-
- /*
- * If the number came from make_tok_num (as a result of an %assign), it
- * might have a '-' built into it (rather than in a preceeding token).
- */
- if (*r == '-')
- {
- r++;
- sign = -1;
- }
-
- q = r;
-
- while (lib_isnumchar(*q)) q++; /* find end of number */
-
- /*
- * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
- * ends in Q, it's octal. if it ends in B, it's binary.
- * Otherwise, it's ordinary decimal.
- */
- if (*r=='0' && (r[1]=='x' || r[1]=='X'))
- radix = 16, r += 2;
- else if (*r=='$')
- radix = 16, r++;
- else if (q[-1]=='H' || q[-1]=='h')
- radix = 16 , q--;
- else if (q[-1]=='Q' || q[-1]=='q')
- radix = 8 , q--;
- else if (q[-1]=='B' || q[-1]=='b')
- radix = 2 , q--;
- else
- radix = 10;
-
- /*
- * If this number has been found for us by something other than
- * the ordinary scanners, then it might be malformed by having
- * nothing between the prefix and the suffix. Check this case
- * now.
- */
- if (r >= q) {
- *error = TRUE;
- return 0;
- }
-
- /*
- * `checklimit' must be 2**32 / radix. We can't do that in
- * 32-bit arithmetic, which we're (probably) using, so we
- * cheat: since we know that all radices we use are even, we
- * can divide 2**31 by radix/2 instead.
- */
- checklimit = 0x80000000UL / (radix>>1);
-
- /*
- * Calculate the highest allowable value for the last digit
- * of a 32 bit constant... in radix 10, it is 6, otherwise it is 0
- */
- last = (radix == 10 ? 6 : 0);
-
- result = 0;
- while (*r && r < q) {
- if (*r<'0' || (*r>'9' && *r<'A') || (digit = numvalue(*r)) >= radix)
- {
- *error = TRUE;
- return 0;
- }
- if (result > checklimit ||
- (result == checklimit && digit >= last))
- {
- warn = TRUE;
- }
-
- result = radix * result + digit;
- r++;
- }
-#if 0
- if (warn)
- nasm_malloc_error (ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,
- "numeric constant %s does not fit in 32 bits",
- str);
-#endif
- return result*sign;
-}
-
-long nasm_readstrnum (char *str, int length, int *warn)
-{
- long charconst = 0;
- int i;
-
- *warn = FALSE;
-
- str += length;
- for (i=0; i<length; i++) {
- if (charconst & 0xff000000UL) {
- *warn = TRUE;
- }
- charconst = (charconst<<8) + (unsigned char) *--str;
- }
- return charconst;
-}
-
-static long next_seg;
-
-void nasm_seg_init(void)
-{
- next_seg = 0;
-}
-
-long nasm_seg_alloc(void)
-{
- return (next_seg += 2) - 2;
-}
-
-/*
- * Return TRUE if the argument is a simple scalar. (Or a far-
- * absolute, which counts.)
- */
-int nasm_is_simple (nasm_expr *vect)
-{
- while (vect->type && !vect->value)
- vect++;
- if (!vect->type)
- return 1;
- if (vect->type != EXPR_SIMPLE)
- return 0;
- do {
- vect++;
- } while (vect->type && !vect->value);
- if (vect->type && vect->type < EXPR_SEGBASE+SEG_ABS) return 0;
- return 1;
-}
-
-/*
- * Return TRUE if the argument is a simple scalar, _NOT_ a far-
- * absolute.
- */
-int nasm_is_really_simple (nasm_expr *vect)
-{
- while (vect->type && !vect->value)
- vect++;
- if (!vect->type)
- return 1;
- if (vect->type != EXPR_SIMPLE)
- return 0;
- do {
- vect++;
- } while (vect->type && !vect->value);
- if (vect->type) return 0;
- return 1;
-}
-
-/*
- * Return TRUE if the argument is relocatable (i.e. a simple
- * scalar, plus at most one segment-base, plus possibly a WRT).
- */
-int nasm_is_reloc (nasm_expr *vect)
-{
- while (vect->type && !vect->value) /* skip initial value-0 terms */
- vect++;
- if (!vect->type) /* trivially return TRUE if nothing */
- return 1; /* is present apart from value-0s */
- if (vect->type < EXPR_SIMPLE) /* FALSE if a register is present */
- return 0;
- if (vect->type == EXPR_SIMPLE) { /* skip over a pure number term... */
- do {
- vect++;
- } while (vect->type && !vect->value);
- if (!vect->type) /* ...returning TRUE if that's all */
- return 1;
- }
- if (vect->type == EXPR_WRT) { /* skip over a WRT term... */
- do {
- vect++;
- } while (vect->type && !vect->value);
- if (!vect->type) /* ...returning TRUE if that's all */
- return 1;
- }
- if (vect->value != 0 && vect->value != 1)
- return 0; /* segment base multiplier non-unity */
- do { /* skip over _one_ seg-base term... */
- vect++;
- } while (vect->type && !vect->value);
- if (!vect->type) /* ...returning TRUE if that's all */
- return 1;
- return 0; /* And return FALSE if there's more */
-}
-
-/*
- * Return TRUE if the argument contains an `unknown' part.
- */
-int nasm_is_unknown(nasm_expr *vect)
-{
- while (vect->type && vect->type < EXPR_UNKNOWN)
- vect++;
- return (vect->type == EXPR_UNKNOWN);
-}
-
-/*
- * Return TRUE if the argument contains nothing but an `unknown'
- * part.
- */
-int nasm_is_just_unknown(nasm_expr *vect)
-{
- while (vect->type && !vect->value)
- vect++;
- return (vect->type == EXPR_UNKNOWN);
-}
-
-/*
- * Return the scalar part of a relocatable vector. (Including
- * simple scalar vectors - those qualify as relocatable.)
- */
-long nasm_reloc_value (nasm_expr *vect)
-{
- while (vect->type && !vect->value)
- vect++;
- if (!vect->type) return 0;
- if (vect->type == EXPR_SIMPLE)
- return vect->value;
- else
- return 0;
-}
-
-/*
- * Return the segment number of a relocatable vector, or NO_SEG for
- * simple scalars.
- */
-long nasm_reloc_seg (nasm_expr *vect)
-{
- while (vect->type && (vect->type == EXPR_WRT || !vect->value))
- vect++;
- if (vect->type == EXPR_SIMPLE) {
- do {
- vect++;
- } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
- }
- if (!vect->type)
- return NO_SEG;
- else
- return vect->type - EXPR_SEGBASE;
-}
-
-/*
- * Return the WRT segment number of a relocatable vector, or NO_SEG
- * if no WRT part is present.
- */
-long nasm_reloc_wrt (nasm_expr *vect)
-{
- while (vect->type && vect->type < EXPR_WRT)
- vect++;
- if (vect->type == EXPR_WRT) {
- return vect->value;
- } else
- return NO_SEG;
-}
-
-/*
- * Binary search.
- */
-int nasm_bsi (char *string, const char **array, int size)
-{
- int i = -1, j = size; /* always, i < index < j */
- while (j-i >= 2) {
- int k = (i+j)/2;
- int l = strcmp(string, array[k]);
- if (l<0) /* it's in the first half */
- j = k;
- else if (l>0) /* it's in the second half */
- i = k;
- else /* we've got it :) */
- return k;
- }
- return -1; /* we haven't got it :( */
-}
-
-static char *file_name = NULL;
-static long line_number = 0;
-
-char *nasm_src_set_fname(char *newname)
-{
- char *oldname = file_name;
- file_name = newname;
- return oldname;
-}
-
-long nasm_src_set_linnum(long newline)
-{
- long oldline = line_number;
- line_number = newline;
- return oldline;
-}
-
-long nasm_src_get_linnum(void)
-{
- return line_number;
-}
-
-int nasm_src_get(long *xline, char **xname)
-{
- if (!file_name || !*xname || strcmp(*xname, file_name))
- {
- nasm_free(*xname);
- *xname = file_name ? nasm_strdup(file_name) : NULL;
- *xline = line_number;
- return -2;
- }
- if (*xline != line_number)
- {
- long tmp = line_number - *xline;
- *xline = line_number;
- return tmp;
- }
- return 0;
-}
-
-void nasm_quote(char **str)
-{
- int ln=strlen(*str);
- char q=(*str)[0];
- char *p;
- if (ln>1 && (*str)[ln-1]==q && (q=='"' || q=='\''))
- return;
- q = '"';
- if (strchr(*str,q))
- q = '\'';
- p = nasm_malloc(ln+3);
- strcpy(p+1, *str);
- nasm_free(*str);
- p[ln+1] = p[0] = q;
- p[ln+2] = 0;
- *str = p;
-}
-
-char *nasm_strcat(char *one, char *two)
-{
- char *rslt;
- int l1=strlen(one);
- rslt = nasm_malloc(l1+strlen(two)+1);
- strcpy(rslt, one);
- strcpy(rslt+l1, two);
- return rslt;
-}
+++ /dev/null
-/* nasmlib.h header file for nasmlib.c
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-
-#ifndef YASM_NASMLIB_H
-#define YASM_NASMLIB_H
-
-/*
- * Wrappers around malloc, realloc and free. nasm_malloc will
- * fatal-error and die rather than return NULL; nasm_realloc will
- * do likewise, and will also guarantee to work right on being
- * passed a NULL pointer; nasm_free will do nothing if it is passed
- * a NULL pointer.
- */
-#define nasm_malloc yasm_xmalloc
-#define nasm_realloc yasm_xrealloc
-#define nasm_free(p) yasm_xfree(p)
-#define nasm_strdup yasm__xstrdup
-#define nasm_strndup yasm__xstrndup
-#define nasm_stricmp yasm__strcasecmp
-#define nasm_strnicmp yasm__strncasecmp
-
-/*
- * Convert a string into a number, using NASM number rules. Sets
- * `*error' to TRUE if an error occurs, and FALSE otherwise.
- */
-long nasm_readnum(char *str, int *error);
-
-/*
- * Convert a character constant into a number. Sets
- * `*warn' to TRUE if an overflow occurs, and FALSE otherwise.
- * str points to and length covers the middle of the string,
- * without the quotes.
- */
-long nasm_readstrnum(char *str, int length, int *warn);
-
-/*
- * seg_init: Initialise the segment-number allocator.
- * seg_alloc: allocate a hitherto unused segment number.
- */
-void nasm_seg_init(void);
-long nasm_seg_alloc(void);
-
-#ifdef YASM_NASM_H
-/*
- * Library routines to manipulate expression data types.
- */
-int nasm_is_reloc(nasm_expr *);
-int nasm_is_simple(nasm_expr *);
-int nasm_is_really_simple (nasm_expr *);
-int nasm_is_unknown(nasm_expr *);
-int nasm_is_just_unknown(nasm_expr *);
-long nasm_reloc_value(nasm_expr *);
-long nasm_reloc_seg(nasm_expr *);
-long nasm_reloc_wrt(nasm_expr *);
-#endif
-
-/*
- * Binary search routine. Returns index into `array' of an entry
- * matching `string', or <0 if no match. `array' is taken to
- * contain `size' elements.
- */
-int nasm_bsi (char *string, const char **array, int size);
-
-
-char *nasm_src_set_fname(char *newname);
-long nasm_src_set_linnum(long newline);
-long nasm_src_get_linnum(void);
-/*
- * src_get may be used if you simply want to know the source file and line.
- * It is also used if you maintain private status about the source location
- * It return 0 if the information was the same as the last time you
- * checked, -1 if the name changed and (new-old) if just the line changed.
- */
-int nasm_src_get(long *xline, char **xname);
-
-void nasm_quote(char **str);
-char *nasm_strcat(char *one, char *two);
-
-#endif
+++ /dev/null
-; Standard macro set for NASM -*- nasm -*-
-
-; Macros to make NASM ignore some TASM directives before the first include
-; directive.
-
- %idefine IDEAL
- %idefine JUMPS
- %idefine P386
- %idefine P486
- %idefine P586
- %idefine END
-
-; This is a magic token which indicates the end of the TASM macros
-*END*TASM*MACROS*
-
-; Note that although some user-level forms of directives are defined
-; here, not all of them are: the user-level form of a format-specific
-; directive should be defined in the module for that directive.
-
-; These two need to be defined, though the actual definitions will
-; be constantly updated during preprocessing.
-%define __FILE__
-%define __LINE__
-
-%define __SECT__ ; it ought to be defined, even if as nothing
-
-%imacro section 1+.nolist
-%define __SECT__ [section %1]
- __SECT__
-%endmacro
-%imacro segment 1+.nolist
-%define __SECT__ [segment %1]
- __SECT__
-%endmacro
-
-%imacro absolute 1+.nolist
-%define __SECT__ [absolute %1]
- __SECT__
-%endmacro
-
-%imacro struc 1.nolist
-%push struc
-%define %$strucname %1
-[absolute 0]
-%$strucname: ; allow definition of `.member' to work sanely
-%endmacro
-%imacro endstruc 0.nolist
-%{$strucname}_size:
-%pop
-__SECT__
-%endmacro
-
-%imacro istruc 1.nolist
-%push istruc
-%define %$strucname %1
-%$strucstart:
-%endmacro
-%imacro at 1-2+.nolist
- times %1-($-%$strucstart) db 0
- %2
-%endmacro
-%imacro iend 0.nolist
- times %{$strucname}_size-($-%$strucstart) db 0
-%pop
-%endmacro
-
-%imacro align 1-2+.nolist nop
- times ($$-$) & ((%1)-1) %2
-%endmacro
-%imacro alignb 1-2+.nolist resb 1
- times ($$-$) & ((%1)-1) %2
-%endmacro
-
-%imacro extern 1-*.nolist
-%rep %0
-[extern %1]
-%rotate 1
-%endrep
-%endmacro
-
-%imacro bits 1+.nolist
-[bits %1]
-%endmacro
-
-%imacro use16 0.nolist
-[bits 16]
-%endmacro
-%imacro use32 0.nolist
-[bits 32]
-%endmacro
-
-%imacro global 1-*.nolist
-%rep %0
-[global %1]
-%rotate 1
-%endrep
-%endmacro
-
-%imacro common 1-*.nolist
-%rep %0
-[common %1]
-%rotate 1
-%endrep
-%endmacro
-
-%imacro cpu 1+.nolist
-[cpu %1]
-%endmacro
-
-
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-raw.la
-
-yasm_raw_la_SOURCES = \
- src/preprocs/raw/raw-preproc.c
-yasm_raw_la_LDFLAGS = -module -avoid-version
-yasm_raw_la_LIBADD = libyasm.la
-yasm_LDADD += -dlpreopen yasm-raw.la
+++ /dev/null
-/*
- * Raw preprocessor (preforms NO preprocessing)
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-#include "linemgr.h"
-
-#include "preproc.h"
-
-
-static int is_interactive;
-static FILE *in;
-static yasm_linemgr *cur_lm;
-
-int isatty(int);
-
-static void
-raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
-{
- in = f;
- cur_lm = lm;
- /*@-unrecog@*/
- is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
- /*@=unrecog@*/
-}
-
-static void
-raw_preproc_cleanup(void)
-{
-}
-
-static size_t
-raw_preproc_input(char *buf, size_t max_size)
-{
- int c = '*';
- size_t n;
-
- if (is_interactive) {
- for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++)
- buf[n] = (char)c;
- if (c == '\n')
- buf[n++] = (char)c;
- if (c == EOF && ferror(in))
- yasm__error(cur_lm->get_current(),
- N_("error when reading from file"));
- } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
- yasm__error(cur_lm->get_current(), N_("error when reading from file"));
-
- return n;
-}
-
-/* Define preproc structure -- see preproc.h for details */
-yasm_preproc yasm_raw_LTX_preproc = {
- "Disable preprocessing",
- "raw",
- raw_preproc_initialize,
- raw_preproc_cleanup,
- raw_preproc_input
-};
+++ /dev/null
-# $IdPath$
-
-lib_LTLIBRARIES += yasm-yapp.la
-
-yasm_yapp_la_SOURCES = \
- src/preprocs/yapp/yapp-preproc.h \
- src/preprocs/yapp/yapp-preproc.c \
- src/preprocs/yapp/yapp-token.h \
- src/preprocs/yapp/yapp-token.l
-yasm_yapp_la_LDFLAGS = -module -avoid-version
-yasm_yapp_la_LIBADD = libyasm.la
-yasm_LDADD += -dlopen yasm-yapp.la
-
-BUILT_SOURCES += \
- yapp-token.c
-
-CLEANFILES += \
- yapp-token.c
-
-include src/preprocs/yapp/tests/Makefile.inc
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- src/preprocs/yapp/tests/yapp_test.sh
-
-EXTRA_DIST += \
- src/preprocs/yapp/tests/Makefile.inc \
- src/preprocs/yapp/tests/yapp_test.sh \
- src/preprocs/yapp/tests/raw.asm \
- src/preprocs/yapp/tests/raw.pre \
- src/preprocs/yapp/tests/comment.asm \
- src/preprocs/yapp/tests/comment.pre \
- src/preprocs/yapp/tests/define.asm \
- src/preprocs/yapp/tests/define.pre \
- src/preprocs/yapp/tests/ddefine.asm \
- src/preprocs/yapp/tests/ddefine.pre \
- src/preprocs/yapp/tests/rdefine.asm \
- src/preprocs/yapp/tests/rdefine.pre \
- src/preprocs/yapp/tests/pdefine.asm \
- src/preprocs/yapp/tests/pdefine.pre \
- src/preprocs/yapp/tests/ifdef.asm \
- src/preprocs/yapp/tests/ifdef.pre \
- src/preprocs/yapp/tests/include.asm \
- src/preprocs/yapp/tests/include.pre \
- src/preprocs/yapp/tests/rinclude.asm \
- src/preprocs/yapp/tests/rinclude.pre \
- src/preprocs/yapp/tests/params.asm \
- src/preprocs/yapp/tests/params.pre
+++ /dev/null
-; mov ax, 4 ; asdfasdf
- mov ax, 4 ; asdfasdf
+++ /dev/null
-%line 2+1 -
- mov ax, 4
+++ /dev/null
-%define foo 5
-%define bar baz
- mov ax, [foo+bar]
-%define baz bzzt
-%define bzzt 9
- mov ax, baz+bar
+++ /dev/null
-%line 3+1 -
- mov ax, [5+baz]
-
-
- mov ax, 9+9
+++ /dev/null
-%define foo 5
-%define bar baz
- mov ax, [foo+bar]
-%define baz bzzt
+++ /dev/null
-%line 3+1 -
- mov ax, [5+baz]
-
+++ /dev/null
-%ifdef foo
- mov ax, foo
-%endif
-%ifdef bar
- mov ax, bar
-%endif
-%define foo 5
-%ifdef foo
- mov ax, foo
-%endif
-%ifdef bar
- mov ax, bar
-%endif
+++ /dev/null
-%line 9+1 -
- mov ax, 5
-
-
-%line 14+1 -
+++ /dev/null
- mov ax, 5
-%include "./src/preprocs/yapp/tests/raw.asm"
- mov ax, 6
-%include "./src/preprocs/yapp/tests/raw.asm"
- mov ax, 7
+++ /dev/null
-%line 1+1 -
- mov ax, 5
-%line 1+1 ./src/preprocs/yapp/tests/raw.asm
- mov ax, raw
-%line 3+1 -
- mov ax, 6
-%line 1+1 ./src/preprocs/yapp/tests/raw.asm
- mov ax, raw
-%line 5+1 -
- mov ax, 7
+++ /dev/null
-%define foo(a, b) (a)+(b)
- foo((a+b,c),(d*e,f))
+++ /dev/null
-%line 2+1 -
- ((a+b,c))+((d*e,f))
+++ /dev/null
-%define foo(bar) bar+1
-%define foo(bar, baz) bar-baz
- mov ax, foo
- mov ax, foo(5)
- mov ax, foo(5, 3)
- mov ax, foo(5, 6, 7)
+++ /dev/null
-%line 3+1 -
- mov ax, foo
- mov ax, 5+1
- mov ax, 5-3
- mov ax, foo(5, 6, 7)
+++ /dev/null
- mov ax, raw
+++ /dev/null
-%line 1+1 -
- mov ax, raw
+++ /dev/null
-%define recursion endless
-%define endless recursion
- mov ax, 5
- mov ax, endless
-%define recurse recurse
- mov ax, recurse
+++ /dev/null
-%line 3+1 -
- mov ax, 5
- mov ax, endless
-
- mov ax, recurse
+++ /dev/null
-%ifndef recurse
-%define recurse
-%include "./src/preprocs/yapp/tests/rinclude.asm"
- mov ax, 5
-%endif
+++ /dev/null
-%line 4+1 -
- mov ax, 5
-
+++ /dev/null
-#! /bin/sh
-# $IdPath$
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-mkdir results >/dev/null 2>&1
-
-#
-# Verify that all test cases match
-# (aside from whitespace for now)
-#
-
-passedct=0
-passedlist=''
-failedct=0
-failedlist=''
-errorct=0
-errorlist=''
-
-YT="yapp_test"
-
-
-for asm in ${srcdir}/src/preprocs/yapp/tests/*.asm
-do
- a=`echo ${asm} | sed 's,^.*/,,;s,.asm$,,'`
- y=${a}.yp
- p=`echo ${asm} | sed 's,.asm$,.pre,'`
-
- echo $ECHO_N "$YT: Testing yapp for ${a} ... $ECHO_C"
- if sed "s,\./,${srcdir}/," ${asm} | ./yasm -e -r yapp |
- sed "s,${srcdir}/,./," > results/${y}; then
- if diff -w ${p} results/${y} > /dev/null; then
- echo "PASS."
- passedct=`expr $passedct + 1`
- passedlist="${passedlist}${a} "
- else
- echo "FAIL."
- failedct=`expr $failedct + 1`
- failedlist="${failedlist}${a} "
- fi
- else
- errorct=`expr $errorct + 1`
- errorlist="${errorlist}${a} "
- fi
-done
-
-ct=`expr $failedct + $passedct + $errorct`
-per=`expr 100 \* $passedct / $ct`
-
-echo "$YT: $per%: Checks: $ct, Failures $failedct, Errors: $errorct"
-#test $passedct -gt 0 && echo "$YT: PASSED $passedct: $passedlist"
-#test $failedct -gt 0 && echo "$YT: FAILED $failedct: $failedlist"
-#test $errorct -gt 0 && echo "$YT: ERRORED $errorct: $errorlist"
-
-exit `expr $failedct + $errorct`
+++ /dev/null
-/* $IdPath$
- * YAPP preprocessor (mimics NASM's preprocessor)
- *
- * Copyright (C) 2001 Michael Urman
- *
- * This file is part of YASM.
- *
- * YASM 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 of the License, or
- * (at your option) any later version.
- *
- * YASM 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
- */
-#include "util.h"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "linemgr.h"
-#include "errwarn.h"
-#include "preproc.h"
-#include "hamt.h"
-
-#include "src/preprocs/yapp/yapp-preproc.h"
-#include "src/preprocs/yapp/yapp-token.h"
-
-#define ydebug(x) /* printf x */
-
-static int is_interactive;
-static int saved_length;
-
-static HAMT *macro_table;
-
-static YAPP_Output current_output;
-YYSTYPE yapp_preproc_lval;
-
-/*@dependent@*/ yasm_linemgr *yapp_preproc_linemgr;
-
-int isatty(int);
-
-/* Build source and macro representations */
-static SLIST_HEAD(source_head, source_s) source_head, macro_head, param_head;
-static struct source_s {
- SLIST_ENTRY(source_s) next;
- YAPP_Token token;
-} *src, *source_tail, *macro_tail, *param_tail;
-typedef struct source_s source;
-
-/* don't forget what the nesting level says */
-static SLIST_HEAD(output_head, output_s) output_head;
-static struct output_s {
- SLIST_ENTRY(output_s) next;
- YAPP_Output out;
-} output, *out;
-
-/*****************************************************************************/
-/* macro support - to be moved to a separate file later (?) */
-/*****************************************************************************/
-typedef struct YAPP_Macro_s {
- struct source_head macro_head;
- struct source_head param_head;
- enum {
- YAPP_MACRO = 0,
- YAPP_DEFINE
- } type;
- int args;
- int fillargs;
- int expanding;
-} YAPP_Macro;
-
-YAPP_Macro *
-yapp_macro_insert (char *name, int argc, int fillargs);
-
-void
-yapp_macro_error_exists (YAPP_Macro *v);
-
-void
-yapp_macro_error_sameargname (YAPP_Macro *v);
-
-YAPP_Macro *
-yapp_define_insert (char *name, int argc, int fillargs);
-
-void
-yapp_macro_delete (YAPP_Macro *ym);
-
-static YAPP_Macro *
-yapp_macro_get (const char *key);
-
-struct source_head *
-yapp_define_param_get (HAMT *hamt, const char *key);
-
-static void
-replay_saved_tokens(char *ident,
- struct source_head *from_head,
- struct source_head *to_head,
- source **to_tail);
-
-YAPP_Macro *
-yapp_macro_insert (char *name, int argc, int fillargs)
-{
- YAPP_Macro *ym = yasm_xmalloc(sizeof(YAPP_Macro));
- ym->type = YAPP_MACRO;
- ym->args = argc;
- ym->fillargs = fillargs;
-
- memcpy(&ym->macro_head, ¯o_head, sizeof(macro_head));
-
- SLIST_INIT(¯o_head);
- macro_tail = SLIST_FIRST(¯o_head);
- return ym;
-}
-
-void
-yapp_macro_error_exists (YAPP_Macro *v)
-{
- if (v) yasm__error(cur_lindex, N_("Redefining macro of the same name %d:%d"), v->type, v->args);
-}
-
-void
-yapp_macro_error_sameargname (YAPP_Macro *v)
-{
- if (v) yasm__error(cur_lindex, N_("Duplicate argument names in macro"));
-}
-
-YAPP_Macro *
-yapp_define_insert (char *name, int argc, int fillargs)
-{
- int zero = 0;
- char *mungename = name;
- YAPP_Macro *ym;
-
- ym = yapp_macro_get(name);
- if (ym) {
- if ((argc >= 0 && ym->args < 0)
- || (argc < 0 && ym->args >= 0))
- {
- yasm__warning(YASM_WARN_PREPROC, cur_lindex, N_("Attempted %%define both with and without parameters"));
- return NULL;
- }
- }
- else if (argc >= 0)
- {
- /* insert placeholder for paramlisted defines */
- ym = yasm_xmalloc(sizeof(YAPP_Macro));
- ym->type = YAPP_DEFINE;
- ym->args = argc;
- ym->fillargs = fillargs;
- ym->expanding = 0;
- HAMT_insert(macro_table, name, (void *)ym, &zero, (void (*)(void *))yapp_macro_error_exists);
- }
-
- /* now for the real one */
- ym = yasm_xmalloc(sizeof(YAPP_Macro));
- ym->type = YAPP_DEFINE;
- ym->args = argc;
- ym->fillargs = fillargs;
- ym->expanding = 0;
-
- if (argc>=0) {
- mungename = yasm_xmalloc(strlen(name)+8);
- sprintf(mungename, "%s(%d)", name, argc);
- }
-
- ydebug(("YAPP: +Inserting macro %s\n", mungename));
-
- memcpy(&ym->macro_head, ¯o_head, sizeof(macro_head));
- memcpy(&ym->param_head, ¶m_head, sizeof(param_head));
-
- HAMT_insert(macro_table, mungename, (void *)ym, &zero, (void (*)(void *))yapp_macro_error_exists);
-
- SLIST_INIT(¯o_head);
- SLIST_INIT(¶m_head);
-
- macro_tail = SLIST_FIRST(¯o_head);
- param_tail = SLIST_FIRST(¶m_head);
-
- return ym;
-}
-
-void
-yapp_macro_delete (YAPP_Macro *ym)
-{
- while (!SLIST_EMPTY(&ym->macro_head)) {
- source *s = SLIST_FIRST(&ym->macro_head);
- yasm_xfree(s);
- SLIST_REMOVE_HEAD(&ym->macro_head, next);
- }
- yasm_xfree(ym);
-}
-
-static YAPP_Macro *
-yapp_macro_get (const char *key)
-{
- return (YAPP_Macro *)HAMT_search(macro_table, key);
-}
-
-struct source_head *
-yapp_define_param_get (HAMT *hamt, const char *key)
-{
- return (struct source_head *)HAMT_search(hamt, key);
-}
-
-/*****************************************************************************/
-
-void
-append_processed_token(source *tok, struct source_head *to_head, source **to_tail);
-
-void
-append_token(int token, struct source_head *to_head, source **to_tail);
-
-int
-append_to_return(struct source_head *to_head, source **to_tail);
-
-int
-eat_through_return(struct source_head *to_head, source **to_tail);
-
-int
-yapp_get_ident(const char *synlvl);
-
-void
-copy_token(YAPP_Token *tok, struct source_head *to_head, source **to_tail);
-
-void
-expand_macro(char *name,
- struct source_head *from_head,
- struct source_head *to_head,
- source **to_tail);
-
-void
-expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail);
-
-static void
-yapp_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
-{
- is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
- yapp_preproc_linemgr = lm;
- yapp_preproc_current_file = yasm__xstrdup(in_filename);
- yapp_preproc_line_number = 1;
- yapp_lex_initialize(f);
- SLIST_INIT(&output_head);
- SLIST_INIT(&source_head);
- SLIST_INIT(¯o_head);
- SLIST_INIT(¶m_head);
- out = yasm_xmalloc(sizeof(output));
- out->out = current_output = YAPP_OUTPUT;
- SLIST_INSERT_HEAD(&output_head, out, next);
-
- macro_table = HAMT_new(yasm_internal_error_);
-
- source_tail = SLIST_FIRST(&source_head);
- macro_tail = SLIST_FIRST(¯o_head);
- param_tail = SLIST_FIRST(¶m_head);
-
- append_token(LINE, &source_head, &source_tail);
-}
-
-static void
-yapp_preproc_cleanup(void)
-{
- /* TODO: clean up */
-}
-
-/* Generate a new level of if* context
- * if val is true, this module of the current level will be output IFF the
- * surrounding one is.
- */
-static void
-push_if(int val)
-{
- out = yasm_xmalloc(sizeof(output));
- out->out = current_output;
- SLIST_INSERT_HEAD(&output_head, out, next);
-
- switch (current_output)
- {
- case YAPP_OUTPUT:
- current_output = val ? YAPP_OUTPUT : YAPP_NO_OUTPUT;
- break;
-
- case YAPP_NO_OUTPUT:
- case YAPP_OLD_OUTPUT:
- case YAPP_BLOCKED_OUTPUT:
- current_output = YAPP_BLOCKED_OUTPUT;
- break;
- }
- if (current_output != YAPP_OUTPUT) set_inhibit();
-
-}
-
-/* Generate a new module in the current if* context
- * if val is true and this level hasn't had a true, it will be output if the
- * surrounding level is.
- */
-static void
-push_else(int val)
-{
- switch (current_output)
- {
- /* if it was NO, turn to output IFF val is true */
- case YAPP_NO_OUTPUT:
- current_output = val ? YAPP_OUTPUT : YAPP_NO_OUTPUT;
- break;
-
- /* if it was yes, make it OLD */
- case YAPP_OUTPUT:
- current_output = YAPP_OLD_OUTPUT;
- break;
-
- /* leave OLD as OLD, BLOCKED as BLOCKED */
- case YAPP_OLD_OUTPUT:
- case YAPP_BLOCKED_OUTPUT:
- break;
- }
- if (current_output != YAPP_OUTPUT) set_inhibit();
-}
-
-/* Clear the curent if* context level */
-static void
-pop_if(void)
-{
- out = SLIST_FIRST(&output_head);
- current_output = out->out;
- SLIST_REMOVE_HEAD(&output_head, next);
- yasm_xfree(out);
- if (current_output != YAPP_OUTPUT) set_inhibit();
-}
-
-/* undefine a symbol */
-static void
-yapp_undef(const char *key)
-{
- int zero = 0;
- HAMT_insert(macro_table, key, NULL, &zero, (void (*)(void *))yapp_macro_delete);
-}
-
-/* Is a symbol known to YAPP? */
-static int
-yapp_defined(const char *key)
-{
- return yapp_macro_get(key) != NULL;
-}
-
-void
-append_processed_token(source *tok, struct source_head *to_head, source **to_tail)
-{
- ydebug(("YAPP: appended token \"%s\"\n", tok->token.str));
- if (*to_tail) {
- SLIST_INSERT_AFTER(*to_tail, tok, next);
- }
- else {
- SLIST_INSERT_HEAD(to_head, tok, next);
- }
- *to_tail = tok;
- if (to_head == &source_head)
- saved_length += strlen(tok->token.str);
-}
-
-void
-append_token(int token, struct source_head *to_head, source **to_tail)
-{
- if (current_output != YAPP_OUTPUT) {
- ydebug(("YAPP: append_token while not YAPP_OUTPUT\n"));
- return;
- }
-
- /* attempt to condense LINES together or newlines onto LINES */
- if ((*to_tail) && (*to_tail)->token.type == LINE
- && (token == '\n' || token == LINE))
- {
- yasm_xfree ((*to_tail)->token.str);
- (*to_tail)->token.str = yasm_xmalloc(23+strlen(yapp_preproc_current_file));
- sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
- }
- else {
- src = yasm_xmalloc(sizeof(source));
- src->token.type = token;
- switch (token)
- {
- case INTNUM:
- src->token.str = yasm__xstrdup(yapp_preproc_lval.int_str_val.str);
- src->token.val.int_val = yapp_preproc_lval.int_str_val.val;
- break;
-
- case FLTNUM:
- src->token.str = yasm__xstrdup(yapp_preproc_lval.double_str_val.str);
- src->token.val.double_val = yapp_preproc_lval.double_str_val.val;
- break;
-
- case STRING:
- case WHITESPACE:
- src->token.str = yasm__xstrdup(yapp_preproc_lval.str_val);
- break;
-
- case IDENT:
- src->token.str = yasm__xstrdup(yapp_preproc_lval.str_val);
- break;
-
- case '+': case '-': case '*': case '/': case '%': case ',': case '\n':
- case '[': case ']': case '(': case ')':
- src->token.str = yasm_xmalloc(2);
- src->token.str[0] = (char)token;
- src->token.str[1] = '\0';
- break;
-
- case LINE:
- /* TODO: consider removing any trailing newline or LINE tokens */
- src->token.str = yasm_xmalloc(23+strlen(yapp_preproc_current_file));
- sprintf(src->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file);
- break;
-
- default:
- yasm_xfree(src);
- return;
- }
- append_processed_token(src, to_head, to_tail);
- }
-}
-
-void
-replay_saved_tokens(char *ident,
- struct source_head *from_head,
- struct source_head *to_head,
- source **to_tail)
-{
- source *item, *after;
- ydebug(("-No, %s didn't match any macro we have\n", ident));
- /* this means a macro expansion failed. stick its name and all the saved
- * tokens into the output stream */
- yapp_preproc_lval.str_val = ident;
- append_token(IDENT, to_head, to_tail);
-
- item = SLIST_FIRST(from_head);
- while (item) {
- after = SLIST_NEXT(item, next);
- SLIST_INSERT_AFTER(*to_tail, item, next);
- *to_tail = item;
- saved_length += strlen(item->token.str);
- item = after;
- }
- SLIST_INIT(from_head);
-}
-
-int
-append_to_return(struct source_head *to_head, source **to_tail)
-{
- int token = yapp_preproc_lex();
- while (token != '\n') {
- ydebug(("YAPP: ATR: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
- if (token == 0)
- return 0;
- append_token(token, to_head, to_tail);
- token = yapp_preproc_lex();
- }
- return '\n';
-}
-
-int
-eat_through_return(struct source_head *to_head, source **to_tail)
-{
- int token;
- while ((token = yapp_preproc_lex()) != '\n') {
- if (token == 0)
- return 0;
- yasm__error(cur_lindex, N_("Skipping possibly valid %%define stuff"));
- }
- append_token('\n', to_head, to_tail);
- return '\n';
-}
-
-int
-yapp_get_ident(const char *synlvl)
-{
- int token = yapp_preproc_lex();
- if (token == WHITESPACE)
- token = yapp_preproc_lex();
- if (token != IDENT) {
- yasm__error(cur_lindex, N_("Identifier expected after %%%s"), synlvl);
- }
- return token;
-}
-
-void
-copy_token(YAPP_Token *tok, struct source_head *to_head, source **to_tail)
-{
- src = yasm_xmalloc(sizeof(source));
- src->token.type = tok->type;
- src->token.str = yasm__xstrdup(tok->str);
-
- append_processed_token(src, to_head, to_tail);
-}
-
-void
-expand_macro(char *name,
- struct source_head *from_head,
- struct source_head *to_head,
- source **to_tail)
-{
- struct source_head replay_head, arg_head;
- source *replay_tail, *arg_tail;
-
- YAPP_Macro *ym = yapp_macro_get(name);
-
- ydebug(("YAPP: +Expand macro %s...\n", name));
-
- if (ym->expanding) yasm_internal_error(N_("Recursively expanding a macro!"));
-
- if (ym->type == YAPP_DEFINE) {
- if (ym->args == -1) {
- /* no parens to deal with */
- ym->expanding = 1;
- expand_token_list(&ym->macro_head, to_head, to_tail);
- ym->expanding = 0;
- }
- else
- {
- char *mungename;
- int token;
- int argc=0;
- int parennest=0;
- HAMT *param_table;
- source *replay, *param;
-
- ydebug(("YAPP: +Expanding multi-arg macro %s...\n", name));
-
- /* Build up both a parameter reference list and a token buffer,
- * because we won't know until we've reached the closing paren if
- * we can actuall expand the macro or not. bleah. */
- /* worse, we can't build the parameter list until we know the
- * parameter names, which we can't look up until we know the
- * number of arguments. sigh */
- /* HMM */
- SLIST_INIT(&replay_head);
- replay_tail = SLIST_FIRST(&replay_head);
-
- /* find out what we got */
- if (from_head) {
- yasm_internal_error(N_("Expanding macro with non-null from_head ugh\n"));
- }
- token = yapp_preproc_lex();
- append_token(token, &replay_head, &replay_tail);
- /* allow one whitespace */
- if (token == WHITESPACE) {
- ydebug(("Ignoring WS between macro and paren\n"));
- token = yapp_preproc_lex();
- append_token(token, &replay_head, &replay_tail);
- }
- if (token != '(') {
- ydebug(("YAPP: -Didn't get to left paren; instead got '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
- replay_saved_tokens(name, &replay_head, to_head, to_tail);
- return;
- }
-
- /* at this point, we've got the left paren. time to get annoyed */
- while (token != ')') {
- token = yapp_preproc_lex();
- append_token(token, &replay_head, &replay_tail);
- /* TODO: handle { } for commas? or is that just macros? */
- switch (token) {
- case '(':
- parennest++;
- break;
-
- case ')':
- if (parennest) {
- parennest--;
- token = ',';
- }
- else {
- argc++;
- }
- break;
-
- case ',':
- if (!parennest)
- argc++;
- break;
-
- case WHITESPACE: case IDENT: case INTNUM: case FLTNUM: case STRING:
- case '+': case '-': case '*': case '/':
- break;
-
- default:
- if (token < 256)
- yasm_internal_error(N_("Unexpected character token in parameter expansion"));
- else
- yasm__error(cur_lindex, N_("Cannot handle preprocessor items inside possible macro invocation"));
- }
- }
-
- /* Now we have the argument count; let's see if it exists */
- mungename = yasm_xmalloc(strlen(name)+8);
- sprintf(mungename, "%s(%d)", name, argc);
- ym = yapp_macro_get(mungename);
- if (!ym)
- {
- ydebug(("YAPP: -Didn't find macro %s\n", mungename));
- replay_saved_tokens(name, &replay_head, to_head, to_tail);
- yasm_xfree(mungename);
- return;
- }
- ydebug(("YAPP: +Found macro %s\n", mungename));
-
- ym->expanding = 1;
-
- /* so the macro exists. build a HAMT parameter table */
- param_table = HAMT_new(yasm_internal_error_);
- /* fill the entries by walking the replay buffer and create
- * "macros". coincidentally, clear the replay buffer. */
-
- /* get to the opening paren */
- replay = SLIST_FIRST(&replay_head);
- while (replay->token.type != '(') {
- ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
- SLIST_REMOVE_HEAD(&replay_head, next);
- yasm_xfree(replay->token.str);
- yasm_xfree(replay);
- replay = SLIST_FIRST(&replay_head);
- }
- ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str));
-
- /* free the open paren */
- SLIST_REMOVE_HEAD(&replay_head, next);
- yasm_xfree(replay->token.str);
- yasm_xfree(replay);
-
- param = SLIST_FIRST(&ym->param_head);
-
- SLIST_INIT(&arg_head);
- arg_tail = SLIST_FIRST(&arg_head);
-
- replay = SLIST_FIRST(&replay_head);
- SLIST_REMOVE_HEAD(&replay_head, next);
- while (parennest || replay) {
- if (replay->token.type == '(') {
- parennest++;
- append_processed_token(replay, &arg_head, &arg_tail);
- ydebug(("YAPP: +add arg token '%c'\n", replay->token.type));
- }
- else if (parennest && replay->token.type == ')') {
- parennest--;
- append_processed_token(replay, &arg_head, &arg_tail);
- ydebug(("YAPP: +add arg token '%c'\n", replay->token.type));
- }
- else if ((!parennest) && (replay->token.type == ','
- || replay->token.type == ')'))
- {
- int zero=0;
- struct source_head *argmacro = yasm_xmalloc(sizeof(struct source_head));
- memcpy(argmacro, &arg_head, sizeof(struct source_head));
- SLIST_INIT(&arg_head);
- arg_tail = SLIST_FIRST(&arg_head);
-
- /* don't save the comma */
- yasm_xfree(replay->token.str);
- yasm_xfree(replay);
-
- HAMT_insert(param_table,
- param->token.str,
- (void *)argmacro,
- &zero,
- (void (*)(void *))yapp_macro_error_sameargname);
- param = SLIST_NEXT(param, next);
- }
- else if (replay->token.type == IDENT
- && yapp_defined(replay->token.str))
- {
- ydebug(("YAPP: +add arg macro '%c' \"%s\"\n", replay->token.type, replay->token.str));
- expand_macro(replay->token.str, &replay_head, &arg_head, &arg_tail);
- }
- else if (arg_tail || replay->token.type != WHITESPACE) {
- ydebug(("YAPP: +else add arg token '%c' \"%s\"\n", replay->token.type, replay->token.str));
- append_processed_token(replay, &arg_head, &arg_tail);
- }
- replay = SLIST_FIRST(&replay_head);
- if (replay) SLIST_REMOVE_HEAD(&replay_head, next);
- }
- if (replay) {
- yasm_xfree(replay->token.str);
- yasm_xfree(replay);
- }
- else if (param) {
- yasm_internal_error(N_("Got to end of arglist before end of replay!"));
- }
- replay = SLIST_FIRST(&replay_head);
- if (replay || param)
- yasm_internal_error(N_("Count and distribution of define args mismatched!"));
-
- /* the param_table is set up without errors, so expansion is ready
- * to go */
- SLIST_FOREACH (replay, &ym->macro_head, next) {
- if (replay->token.type == IDENT) {
-
- /* check local args first */
- struct source_head *paramexp =
- yapp_define_param_get(param_table, replay->token.str);
-
- if (paramexp) {
- expand_token_list(paramexp, to_head, to_tail);
- }
- else {
- /* otherwise, check macros */
- YAPP_Macro *imacro = yapp_macro_get(replay->token.str);
- if (imacro != NULL && !imacro->expanding) {
- expand_macro(replay->token.str, NULL, to_head, to_tail);
- }
- else {
- /* otherwise it's just a vanilla ident */
- copy_token(&replay->token, to_head, to_tail);
- }
- }
- }
- else {
- copy_token(&replay->token, to_head, to_tail);
- }
- }
- ym->expanding = 0;
- }
- }
- else
- yasm_internal_error(N_("Invoking Macros not yet supported"));
-
- ym->expanding = 0;
-}
-
-void
-expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail)
-{
- source *item;
- SLIST_FOREACH (item, paramexp, next) {
- if (item->token.type == IDENT) {
- YAPP_Macro *imacro = yapp_macro_get(item->token.str);
- if (imacro != NULL && !imacro->expanding) {
- expand_macro(item->token.str, NULL, to_head, to_tail);
- }
- else {
- copy_token(&item->token, to_head, to_tail);
- }
- }
- else {
- copy_token(&item->token, to_head, to_tail);
- }
- }
-}
-
-static size_t
-yapp_preproc_input(char *buf, size_t max_size)
-{
- static YAPP_State state = YAPP_STATE_INITIAL;
- int n = 0;
- int token;
- int need_line_directive = 0;
-
- while (saved_length < max_size && state != YAPP_STATE_EOF)
- {
- token = yapp_preproc_lex();
-
- switch (state) {
- case YAPP_STATE_INITIAL:
- switch (token)
- {
- char *s;
- default:
- append_token(token, &source_head, &source_tail);
- /*if (append_to_return()==0) state=YAPP_STATE_EOF;*/
- ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val));
- /*yasm__error(cur_lindex, N_("YAPP got an unhandled token."));*/
- break;
-
- case IDENT:
- ydebug(("YAPP: ident: \"%s\"\n", yapp_preproc_lval.str_val));
- if (yapp_defined(yapp_preproc_lval.str_val)) {
- expand_macro(yapp_preproc_lval.str_val, NULL, &source_head, &source_tail);
- }
- else {
- append_token(token, &source_head, &source_tail);
- }
- break;
-
- case 0:
- state = YAPP_STATE_EOF;
- break;
-
- case '\n':
- append_token(token, &source_head, &source_tail);
- break;
-
- case CLEAR:
- HAMT_delete(macro_table, (void (*)(void *))yapp_macro_delete);
- macro_table = HAMT_new(yasm_internal_error_);
- break;
-
- case DEFINE:
- ydebug(("YAPP: define: "));
- token = yapp_get_ident("define");
- ydebug((" \"%s\"\n", yapp_preproc_lval.str_val));
- s = yasm__xstrdup(yapp_preproc_lval.str_val);
-
- /* three cases: newline or stuff or left paren */
- token = yapp_preproc_lex();
- if (token == '\n') {
- /* no args or content - just insert it */
- yapp_define_insert(s, -1, 0);
- append_token('\n', &source_head, &source_tail);
- }
- else if (token == WHITESPACE) {
- /* no parens */
- if(append_to_return(¯o_head, ¯o_tail)==0) state=YAPP_STATE_EOF;
- else {
- yapp_define_insert(s, -1, 0);
- }
- append_token('\n', &source_head, &source_tail);
- }
- else if (token == '(') {
- /* get all params of the parameter list */
- /* ensure they alternate IDENT and ',' */
- int param_count = 0;
- int last_token = ',';
-
- ydebug((" *Getting arglist for define %s\n", s));
-
- while ((token = yapp_preproc_lex())!=')') {
- ydebug(("YAPP: +read token '%c' \"%s\" for macro %s\n", token, yapp_preproc_lval.str_val, s));
- if (token == WHITESPACE) {
- token = last_token;
- }
- else if (last_token == ',' && token == IDENT) {
- append_token(token, ¶m_head, ¶m_tail);
- param_count++;
- }
- else if (token == 0) {
- state = YAPP_STATE_EOF;
- break;
- }
- else if (last_token == ',' || token != ',')
- yasm__error(cur_lindex, N_("Unexpected token in %%define parameters"));
- last_token = token;
- }
- if (token == ')') {
- /* after paramlist and ')' */
- /* everything is what it's defined to be */
- token = yapp_preproc_lex();
- if (token != WHITESPACE) append_token(token, ¯o_head, ¯o_tail);
- if (append_to_return(¯o_head, ¯o_tail)==0) state=YAPP_STATE_EOF;
- else {
- ydebug(("YAPP: Inserting define macro %s (%d)\n", s, param_count));
- yapp_define_insert(s, param_count, 0);
- }
- }
- append_token('\n', &source_head, &source_tail);
- }
- else {
- yasm_internal_error(N_("%%define ... failed miserably - neither \\n, WS, or ( followed ident"));
- }
- break;
-
- case UNDEF:
- token = yapp_get_ident("undef");
- yapp_undef(yapp_preproc_lval.str_val);
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case IFDEF:
- token = yapp_get_ident("ifdef");
- push_if(yapp_defined(yapp_preproc_lval.str_val));
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case IFNDEF:
- token = yapp_get_ident("ifndef");
- push_if(!yapp_defined(yapp_preproc_lval.str_val));
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case ELSE:
- push_else(1);
- if (current_output == YAPP_OUTPUT) need_line_directive = 1;
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case ELIFDEF:
- token = yapp_get_ident("elifdef");
- push_else(yapp_defined(yapp_preproc_lval.str_val));
- if (current_output == YAPP_OUTPUT) need_line_directive = 1;
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case ELIFNDEF:
- token = yapp_get_ident("elifndef");
- push_else(!yapp_defined(yapp_preproc_lval.str_val));
- if (current_output == YAPP_OUTPUT) need_line_directive = 1;
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case ENDIF:
- /* there's got to be another way to do this: */
- /* only set if going from non-output to output */
- if (current_output != YAPP_OUTPUT) need_line_directive = 1;
- pop_if();
- if (current_output != YAPP_OUTPUT) need_line_directive = 0;
- state = YAPP_STATE_NEED_EOL;
- break;
-
- case INCLUDE:
- case LINE:
- need_line_directive = 1;
- break;
- }
- if (state == YAPP_STATE_NEED_EOL)
- {
- if (eat_through_return(&source_head, &source_tail)==0) state=YAPP_STATE_EOF;
- else state=YAPP_STATE_INITIAL;
- }
- break;
- default:
- yasm__error(cur_lindex, N_("YAPP got into a bad state"));
- }
- if (need_line_directive) {
- append_token(LINE, &source_head, &source_tail);
- need_line_directive = 0;
- }
- }
-
- /* convert saved stuff into output. we either have enough, or are EOF */
- while (n < max_size && saved_length)
- {
- src = SLIST_FIRST(&source_head);
- if (max_size - n >= strlen(src->token.str)) {
- strcpy(buf+n, src->token.str);
- n += strlen(src->token.str);
-
- saved_length -= strlen(src->token.str);
- SLIST_REMOVE_HEAD(&source_head, next);
- yasm_xfree(src->token.str);
- yasm_xfree(src);
- }
- }
-
- return n;
-}
-
-/* Define preproc structure -- see preproc.h for details */
-yasm_preproc yasm_yapp_LTX_preproc = {
- "YAPP preprocessing (NASM style)",
- "yapp",
- yapp_preproc_initialize,
- yapp_preproc_cleanup,
- yapp_preproc_input
-};
+++ /dev/null
-/* $IdPath$
- * YAPP preprocessor (mimics NASM's preprocessor) header file
- *
- * Copyright (C) 2001 Michael Urman
- *
- * This file is part of YASM.
- *
- * YASM 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 of the License, or
- * (at your option) any later version.
- *
- * YASM 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
- *
- */
-
-/* Representation of tokenized file, both for straight source, and macros */
-typedef struct YAPP_Token_s {
- unsigned int type;
- char *str;
- union {
- unsigned int int_val;
- double double_val;
- char *str_val;
- } val;
-} YAPP_Token;
-
-/* internal state of preprocessor's parser */
-typedef enum {
- YAPP_STATE_INITIAL = 0,
- YAPP_STATE_ASSIGN,
- YAPP_STATE_DEFINING_MACRO,
- YAPP_STATE_BUILDING_MACRO,
- YAPP_STATE_NEED_EOL,
- YAPP_STATE_EOF
-} YAPP_State;
-
-/* tracks nested %if* %elif* %else %endif structures */
-typedef enum {
- YAPP_OUTPUT, /* this level+module outputs */
- YAPP_NO_OUTPUT, /* this would never output */
- YAPP_OLD_OUTPUT, /* this level has already output */
- YAPP_BLOCKED_OUTPUT /* the surrounding level is not outputting */
-} YAPP_Output;
-
-void yapp_lex_initialize(FILE *f);
-void set_inhibit(void);
-
-extern /*@dependent@*/ yasm_linemgr *yapp_preproc_linemgr;
-#define cur_lindex (yapp_preproc_linemgr->get_current())
-
+++ /dev/null
-typedef union {
- char *str_val;
- struct {
- char *str;
- unsigned long val;
- } int_str_val;
- struct {
- char *str;
- double val;
- } double_str_val;
-} YYSTYPE;
-#define INTNUM 257
-#define FLTNUM 258
-#define STRING 259
-#define IDENT 260
-#define CLEAR 261
-#define INCLUDE 262
-#define LINE 263
-#define DEFINE 264
-#define UNDEF 265
-#define ASSIGN 266
-#define MACRO 267
-#define ENDMACRO 268
-#define ROTATE 269
-#define REP 270
-#define EXITREP 271
-#define ENDREP 272
-#define IF 273
-#define ELIF 274
-#define ELSE 275
-#define ENDIF 276
-#define IFDEF 277
-#define ELIFDEF 278
-#define IFNDEF 279
-#define ELIFNDEF 280
-#define IFCTX 281
-#define ELIFCTX 282
-#define IFIDN 283
-#define ELIFIDN 284
-#define IFIDNI 285
-#define ELIFIDNI 286
-#define IFID 287
-#define ELIFID 288
-#define IFNUM 289
-#define ELIFNUM 290
-#define IFSTR 291
-#define ELIFSTR 292
-#define ERROR 293
-#define PUSH 294
-#define POP 295
-#define REPL 296
-#define LEFT_OP 297
-#define RIGHT_OP 298
-#define SIGNDIV 299
-#define SIGNMOD 300
-#define UNARYOP 301
-#define WHITESPACE 302
-
-
-extern YYSTYPE yapp_preproc_lval;
-extern char *yapp_preproc_current_file;
-extern int yapp_preproc_line_number;
-
-int yapp_preproc_lex(void);
+++ /dev/null
-/* $IdPath$
- * YAPP lexer
- *
- * Copyright (C) 2001 Michael Urman
- *
- * This file is part of YASM.
- *
- * YASM 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 of the License, or
- * (at your option) any later version.
- *
- * YASM 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
- */
-%{
-#include "util.h"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include <errno.h>
-
-#include "linemgr.h"
-#include "errwarn.h"
-
-#include "src/preprocs/yapp/yapp-preproc.h"
-#include "src/preprocs/yapp/yapp-token.h"
-
-
-#define yylval yapp_preproc_lval
-
-#define malloc yasm_xmalloc
-#define realloc yasm_xrealloc
-
-/* starting size of string buffer */
-#define STRBUF_ALLOC_SIZE 128
-
-/* string buffer used when parsing strings/character constants */
-static char *strbuf = (char *)NULL;
-
-/* length of strbuf (including terminating NULL character) */
-static size_t strbuf_size = 0;
-
-/* include file mumbo jumbo */
-static SLIST_HEAD(include_head, include_s) includes_head;
-struct include_s {
- SLIST_ENTRY(include_s) next;
- YY_BUFFER_STATE include_state;
- char *filename;
- int line_number;
-};
-typedef struct include_s include;
-
-char *yapp_preproc_current_file;
-int yapp_preproc_line_number;
-
-%}
-%option noyywrap
-%option nounput
-%option case-insensitive
-%option prefix="yapp_preproc_"
-%option outfile="lex.yy.c"
-
-%x D
-%x incl
-%x line
-%x inhibit
-
-DIGIT [0-9]
-BINDIGIT [01]
-OCTDIGIT [0-7]
-HEXDIGIT [0-9a-f]
-WS [ \t]
-DIR %[ \t]*
-
-%%
-
- /* standard decimal integer */
-{DIGIT}+ {
- yylval.int_str_val.val = strtoul(yytext, (char **)NULL, 10);
- yylval.int_str_val.str = yytext;
- return INTNUM;
-}
-
- /* 10010011b - binary number */
-{BINDIGIT}+b {
- yylval.int_str_val.val = strtoul(yytext, (char **)NULL, 2);
- yylval.int_str_val.str = yytext;
- return INTNUM;
-}
-
- /* 777q - octal number */
-{OCTDIGIT}+q {
- yylval.int_str_val.val = strtoul(yytext, (char **)NULL, 8);
- yylval.int_str_val.str = yytext;
- return INTNUM;
-}
-
- /* 0AAh form of hexidecimal number */
-0{HEXDIGIT}+h {
- yylval.int_str_val.val = strtoul(yytext+1, (char **)NULL, 16);
- yylval.int_str_val.str = yytext;
- return INTNUM;
-}
-
- /* $0AA and 0xAA forms of hexidecimal number */
-(\$0|0x){HEXDIGIT}+ {
- yylval.int_str_val.val = strtoul(yytext+2, (char **)NULL, 16);
- yylval.int_str_val.str = yytext;
- return INTNUM;
-}
-
- /* floating point value */
-{DIGIT}+\.{DIGIT}*(e[-+]?{DIGIT}+)? {
- yylval.double_str_val.val = strtod(yytext, (char **)NULL);
- yylval.double_str_val.str = yytext;
- return FLTNUM;
-}
-
- /* string/character constant values */
-["'] {
- int inch, count;
- char endch = yytext[0];
-
- strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE);
-
- strbuf_size = STRBUF_ALLOC_SIZE;
- inch = input();
- count = 0;
- while(inch != EOF && inch != endch && inch != '\n') {
- strbuf[count++] = inch;
- if(count >= strbuf_size) {
- strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
- strbuf_size += STRBUF_ALLOC_SIZE;
- }
- inch = input();
- }
-
- if(inch == '\n')
- yasm__error(cur_lindex, N_("unterminated string"));
- else if(inch == EOF)
- yasm__error(cur_lindex, N_("unexpected end of file in string"));
-
- strbuf[count] = '\0';
-
- yylval.str_val = strbuf;
- return STRING;
-}
-
- /* identifiers */
-\.\.[a-z0-9_$#@~.?]+ |
-\.[a-z0-9_$#@~?][a-z0-9_$#@~.?]* |
-[a-z_?][a-z0-9_$#@~.?]* {
- yylval.str_val = yasm__xstrdup(yytext);
- return IDENT;
-}
-
- /* includes - based on flex manual handling of include files */
-<inhibit>{DIR}include[^\n]* ;
-{DIR}include BEGIN(incl);
- /* note the " handling here is a hack that doesn't accept useful
- * things (like spaces, or quotes). fix it later */
-<incl>[ \t"]* /* eat whitespace */
-<incl>[^ \t\n"]* { /* have the filename */
- include *inc;
- FILE *incfile;
- inc = yasm_xmalloc(sizeof(include));
- inc->include_state = YY_CURRENT_BUFFER;
-
- /* FIXME: handle includes that aren't relative */
- incfile = fopen (yytext, "r");
- if(!incfile) {
- yasm__error(cur_lindex, N_("include file `%s': %s"),
- yytext, strerror(errno));
- yasm_xfree(inc);
- }
- else {
- yyin = incfile;
- inc->filename = yapp_preproc_current_file;
- inc->line_number = yapp_preproc_line_number;
- SLIST_INSERT_HEAD(&includes_head, inc, next);
-
- yapp_preproc_line_number = 1;
- yapp_preproc_current_file = yasm__xstrdup(yytext);
- BEGIN(INITIAL);
- yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
- }
- return INCLUDE;
-}
-
- /* end includes - note that it's not in <incl> at the time */
-<<EOF>> {
- if(SLIST_EMPTY(&includes_head)) {
- yyterminate();
- }
- else {
- include *inc;
- inc = SLIST_FIRST(&includes_head);
- yy_delete_buffer (YY_CURRENT_BUFFER);
- yy_switch_to_buffer (inc->include_state);
- yasm_xfree(yapp_preproc_current_file);
- yapp_preproc_current_file = inc->filename;
- yapp_preproc_line_number = inc->line_number + 1;
- SLIST_REMOVE_HEAD(&includes_head, next);
- yasm_xfree(inc);
-
- BEGIN(incl);
- return INCLUDE;
- }
-}
-
-<incl>["]{WS}*\n BEGIN(INITIAL);
-
-
- /* directive: % directive [args] */
-<inhibit>{DIR}clear[^\n] ;
-{DIR}clear return CLEAR;
-
-<inhibit>{DIR}line[^\n] ;
-{DIR}line BEGIN(line);
-<line>{DIGIT}+ yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
-<line>{DIGIT}+{WS}*\n {
- yapp_preproc_line_number = strtoul(yytext, (char **)NULL, 10);
- BEGIN(INITIAL);
- return LINE;
-}
-<line>{WS}+["] ; /* eat space before file */
-<line>[^ \t\n"]* { /* have the filename */
- yasm_xfree(yapp_preproc_current_file);
- yapp_preproc_current_file = yasm__xstrdup(yytext);
-}
-<line>["]{WS}*\n {
- BEGIN(INITIAL);
- return LINE;
-}
-
-{DIR}define return DEFINE;
-{DIR}undef return UNDEF;
-{DIR}assign return ASSIGN;
-{DIR}macro return MACRO;
-{DIR}endmacro return ENDMACRO;
-{DIR}rotate return ROTATE;
-<inhibit>{DIR}define[^\n]* ;
-<inhibit>{DIR}undef[^\n]* ;
-<inhibit>{DIR}assign[^\n]* ;
-<inhibit>{DIR}macro[^\n]* ;
-<inhibit>{DIR}endmacro[^\n]* ;
-<inhibit>{DIR}rotate[^\n]* ;
-
- /* preprocessor loops */
-{DIR}rep return REP;
-{DIR}exitrep return EXITREP;
-{DIR}endrep return ENDREP;
-<inhibit>{DIR}rep[^\n]* ;
-<inhibit>{DIR}exitrep[^\n]* ;
-<inhibit>{DIR}endrep[^\n]* ;
-
-{DIR}if return IF;
-{DIR}elif return ELIF;
-{DIR}else return ELSE;
-{DIR}endif return ENDIF;
-<inhibit>{DIR}if { BEGIN(INITIAL); return IF; }
-<inhibit>{DIR}elif { BEGIN(INITIAL); return ELIF; }
-<inhibit>{DIR}else { BEGIN(INITIAL); return ELSE; }
-<inhibit>{DIR}endif { BEGIN(INITIAL); return ENDIF; }
-
- /* test defines */
-{DIR}ifdef return IFDEF;
-{DIR}elifdef return ELIFDEF;
-{DIR}ifndef return IFNDEF;
-{DIR}elifndef return ELIFNDEF;
-<inhibit>{DIR}ifdef { BEGIN(INITIAL); return IFDEF; }
-<inhibit>{DIR}elifdef { BEGIN(INITIAL); return ELIFDEF; }
-<inhibit>{DIR}ifndef { BEGIN(INITIAL); return IFNDEF; }
-<inhibit>{DIR}elifndef { BEGIN(INITIAL); return ELIFNDEF; }
-
- /* test context stack */
-{DIR}ifctx return IFCTX;
-{DIR}elifctx return ELIFCTX;
-<inhibit>{DIR}ifctx { BEGIN(INITIAL); return IFCTX; }
-<inhibit>{DIR}elifctx { BEGIN(INITIAL); return ELIFCTX; }
-
- /* test exact identity */
-{DIR}ifidn return IFIDN;
-{DIR}elifidn return ELIFIDN;
-{DIR}ifidni return IFIDNI;
-{DIR}elifidni return ELIFIDNI;
-<inhibit>{DIR}ifidn { BEGIN(INITIAL); return IFIDN; }
-<inhibit>{DIR}elifidn { BEGIN(INITIAL); return ELIFIDN; }
-<inhibit>{DIR}ifidni { BEGIN(INITIAL); return IFIDNI; }
-<inhibit>{DIR}elifidni { BEGIN(INITIAL); return ELIFIDNI; }
-
- /* test token types */
-{DIR}ifid return IFID;
-{DIR}elifid return ELIFID;
-{DIR}ifnum return IFNUM;
-{DIR}elifnum return ELIFNUM;
-{DIR}ifstr return IFSTR;
-{DIR}elifstr return ELIFSTR;
-<inhibit>{DIR}ifid { BEGIN(INITIAL); return IFID; }
-<inhibit>{DIR}elifid { BEGIN(INITIAL); return ELIFID; }
-<inhibit>{DIR}ifnum { BEGIN(INITIAL); return IFNUM; }
-<inhibit>{DIR}elifnum { BEGIN(INITIAL); return ELIFNUM; }
-<inhibit>{DIR}ifstr { BEGIN(INITIAL); return IFSTR; }
-<inhibit>{DIR}elifstr { BEGIN(INITIAL); return ELIFSTR; }
-
- /* error reporting */
-<inhibit>{DIR}error[^\n]* ;
-{DIR}error[ ]+.* { yylval.str_val = yytext; return ERROR; }
-
- /* context stack management */
-{DIR}push return PUSH;
-{DIR}pop return POP;
-{DIR}repl return REPL;
-<inhibit>{DIR}push[^\n]* ;
-<inhibit>{DIR}pop[^\n]* ;
-<inhibit>{DIR}repl[^\n]* ;
-
-<inhibit>[^%\n]*\n { yapp_preproc_line_number++; return '\n'; }
-
-;.*\n { yapp_preproc_line_number++; return '\n'; }
-
-{WS}+ { yylval.str_val = yytext; return WHITESPACE; }
-
-{WS}*\n { yapp_preproc_line_number++; return '\n'; }
-
-
-[][+*/,()-] { return yytext[0]; }
-
-<inhibit>. {
- yasm__warning(YASM_WARN_PREPROC, cur_lindex, N_("Unhandled character in <inhibit> `%s'"), yasm__conv_unprint(yytext[0]));
-}
-
-. {
- yasm__warning(YASM_WARN_PREPROC, cur_lindex, N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(yytext[0]));
-}
-
-%%
-
-void
-yapp_lex_initialize(FILE *f)
-{
- SLIST_INIT(&includes_head);
- yyin = f;
-}
-
-void set_inhibit(void)
-{
- BEGIN(inhibit);
-}
+++ /dev/null
-/*
- * Section utility functions
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-#include "section.h"
-#include "objfmt.h"
-
-
-struct yasm_section {
- /*@reldef@*/ STAILQ_ENTRY(yasm_section) link;
-
- enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
- union {
- /* SECTION_GENERAL data */
- struct general {
- /*@owned@*/ char *name; /* strdup()'ed name (given by user) */
-
- /* object-format-specific data */
- /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
- /*@null@*/ /*@owned@*/ void *of_data;
- } general;
- } data;
-
- /*@owned@*/ yasm_expr *start; /* Starting address of section contents */
-
- unsigned long opt_flags; /* storage for optimizer flags */
-
- int res_only; /* allow only resb family of bytecodes? */
-
- yasm_bytecodehead bc; /* the bytecodes for the section's contents */
-};
-
-/*@-compdestroy@*/
-yasm_section *
-yasm_sections_initialize(yasm_sectionhead *headp, yasm_objfmt *of)
-{
- yasm_section *s;
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- /* Initialize linked list */
- STAILQ_INIT(headp);
-
- /* Add an initial "default" section */
- yasm_vp_new(vp, yasm__xstrdup(of->default_section_name), NULL);
- yasm_vps_initialize(&vps);
- yasm_vps_append(&vps, vp);
- s = of->sections_switch(headp, &vps, NULL, 0);
- yasm_vps_delete(&vps);
-
- return s;
-}
-/*@=compdestroy@*/
-
-/*@-onlytrans@*/
-yasm_section *
-yasm_sections_switch_general(yasm_sectionhead *headp, const char *name,
- unsigned long start, int res_only, int *isnew,
- unsigned long lindex)
-{
- yasm_section *s;
-
- /* Search through current sections to see if we already have one with
- * that name.
- */
- STAILQ_FOREACH(s, headp, link) {
- if (s->type == SECTION_GENERAL &&
- strcmp(s->data.general.name, name) == 0) {
- *isnew = 0;
- return s;
- }
- }
-
- /* No: we have to allocate and create a new one. */
-
- /* Okay, the name is valid; now allocate and initialize */
- s = yasm_xcalloc(1, sizeof(yasm_section));
- STAILQ_INSERT_TAIL(headp, s, link);
-
- s->type = SECTION_GENERAL;
- s->data.general.name = yasm__xstrdup(name);
- s->data.general.of = NULL;
- s->data.general.of_data = NULL;
- s->start = yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)),
- lindex);
- yasm_bcs_initialize(&s->bc);
-
- s->opt_flags = 0;
- s->res_only = res_only;
-
- *isnew = 1;
- return s;
-}
-/*@=onlytrans@*/
-
-/*@-onlytrans@*/
-yasm_section *
-yasm_sections_switch_absolute(yasm_sectionhead *headp, yasm_expr *start)
-{
- yasm_section *s;
-
- s = yasm_xcalloc(1, sizeof(yasm_section));
- STAILQ_INSERT_TAIL(headp, s, link);
-
- s->type = SECTION_ABSOLUTE;
- s->start = start;
- yasm_bcs_initialize(&s->bc);
-
- s->opt_flags = 0;
- s->res_only = 1;
-
- return s;
-}
-/*@=onlytrans@*/
-
-int
-yasm_section_is_absolute(yasm_section *sect)
-{
- return (sect->type == SECTION_ABSOLUTE);
-}
-
-unsigned long
-yasm_section_get_opt_flags(const yasm_section *sect)
-{
- return sect->opt_flags;
-}
-
-void
-yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags)
-{
- sect->opt_flags = opt_flags;
-}
-
-void
-yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of, void *of_data)
-{
- /* Check to see if section type supports of_data */
- if (sect->type != SECTION_GENERAL) {
- if (of->section_data_delete)
- of->section_data_delete(of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- return;
- }
-
- /* Delete current of_data if present */
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of2 = sect->data.general.of;
- if (of2->section_data_delete)
- of2->section_data_delete(sect->data.general.of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- }
-
- /* Assign new of_data */
- sect->data.general.of = of;
- sect->data.general.of_data = of_data;
-}
-
-void *
-yasm_section_get_of_data(yasm_section *sect)
-{
- if (sect->type == SECTION_GENERAL)
- return sect->data.general.of_data;
- else
- return NULL;
-}
-
-void
-yasm_sections_delete(yasm_sectionhead *headp)
-{
- yasm_section *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- yasm_section_delete(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
-}
-
-void
-yasm_sections_print(FILE *f, int indent_level, const yasm_sectionhead *headp)
-{
- yasm_section *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- fprintf(f, "%*sSection:\n", indent_level, "");
- yasm_section_print(f, indent_level+1, cur, 1);
- }
-}
-
-int
-yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
- int (*func) (yasm_section *sect, /*@null@*/ void *d))
-{
- yasm_section *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- int retval = func(cur, d);
- if (retval != 0)
- return retval;
- }
- return 0;
-}
-
-/*@-onlytrans@*/
-yasm_section *
-yasm_sections_find_general(yasm_sectionhead *headp, const char *name)
-{
- yasm_section *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- if (cur->type == SECTION_GENERAL &&
- strcmp(cur->data.general.name, name) == 0)
- return cur;
- }
- return NULL;
-}
-/*@=onlytrans@*/
-
-yasm_bytecodehead *
-yasm_section_get_bytecodes(yasm_section *sect)
-{
- return §->bc;
-}
-
-const char *
-yasm_section_get_name(const yasm_section *sect)
-{
- if (sect->type == SECTION_GENERAL)
- return sect->data.general.name;
- return NULL;
-}
-
-void
-yasm_section_set_start(yasm_section *sect, unsigned long start,
- unsigned long lindex)
-{
- yasm_expr_delete(sect->start);
- sect->start =
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)),
- lindex);
-}
-
-const yasm_expr *
-yasm_section_get_start(const yasm_section *sect)
-{
- return sect->start;
-}
-
-void
-yasm_section_delete(yasm_section *sect)
-{
- if (!sect)
- return;
-
- if (sect->type == SECTION_GENERAL) {
- yasm_xfree(sect->data.general.name);
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of = sect->data.general.of;
- if (of->section_data_delete)
- of->section_data_delete(sect->data.general.of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- }
- }
- yasm_expr_delete(sect->start);
- yasm_bcs_delete(§->bc);
- yasm_xfree(sect);
-}
-
-void
-yasm_section_print(FILE *f, int indent_level, const yasm_section *sect,
- int print_bcs)
-{
- if (!sect) {
- fprintf(f, "%*s(none)\n", indent_level, "");
- return;
- }
-
- fprintf(f, "%*stype=", indent_level, "");
- switch (sect->type) {
- case SECTION_GENERAL:
- fprintf(f, "general\n%*sname=%s\n%*sobjfmt data:\n", indent_level,
- "", sect->data.general.name, indent_level, "");
- indent_level++;
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of = sect->data.general.of;
- if (of->section_data_print)
- of->section_data_print(f, indent_level,
- sect->data.general.of_data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level, "");
- } else
- fprintf(f, "%*s(none)\n", indent_level, "");
- indent_level--;
- break;
- case SECTION_ABSOLUTE:
- fprintf(f, "absolute\n");
- break;
- }
-
- fprintf(f, "%*sstart=", indent_level, "");
- yasm_expr_print(f, sect->start);
- fprintf(f, "\n");
-
- if (print_bcs) {
- fprintf(f, "%*sBytecodes:\n", indent_level, "");
- yasm_bcs_print(f, indent_level+1, §->bc);
- }
-}
+++ /dev/null
-/* $IdPath$
- * Section header file
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_SECTION_H
-#define YASM_SECTION_H
-
-/*@dependent@*/ yasm_section *yasm_sections_initialize(yasm_sectionhead *headp,
- yasm_objfmt *of);
-
-/*@dependent@*/ yasm_section *yasm_sections_switch_general
- (yasm_sectionhead *headp, const char *name, unsigned long start,
- int res_only, /*@out@*/ int *isnew, unsigned long lindex);
-
-/*@dependent@*/ yasm_section *yasm_sections_switch_absolute
- (yasm_sectionhead *headp, /*@keep@*/ yasm_expr *start);
-
-int yasm_section_is_absolute(yasm_section *sect);
-
-/* Get and set optimizer flags */
-unsigned long yasm_section_get_opt_flags(const yasm_section *sect);
-void yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags);
-
-void yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of,
- /*@null@*/ /*@only@*/ void *of_data);
-/*@dependent@*/ /*@null@*/ void *yasm_section_get_of_data(yasm_section *sect);
-
-void yasm_sections_delete(yasm_sectionhead *headp);
-
-void yasm_sections_print(FILE *f, int indent_level,
- const yasm_sectionhead *headp);
-
-/* Calls func for each section in the linked list of sections pointed to by
- * headp. The data pointer d is passed to each func call.
- *
- * Stops early (and returns func's return value) if func returns a nonzero
- * value. Otherwise returns 0.
- */
-int yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
- int (*func) (yasm_section *sect,
- /*@null@*/ void *d));
-
-/*@dependent@*/ /*@null@*/ yasm_section *yasm_sections_find_general
- (yasm_sectionhead *headp, const char *name);
-
-/*@dependent@*/ yasm_bytecodehead *yasm_section_get_bytecodes
- (yasm_section *sect);
-
-/*@observer@*/ /*@null@*/ const char *yasm_section_get_name
- (const yasm_section *sect);
-
-void yasm_section_set_start(yasm_section *sect, unsigned long start,
- unsigned long lindex);
-/*@observer@*/ const yasm_expr *yasm_section_get_start
- (const yasm_section *sect);
-
-void yasm_section_delete(/*@only@*/ yasm_section *sect);
-
-void yasm_section_print(FILE *f, int indent_level,
- /*@null@*/ const yasm_section *sect, int print_bcs);
-#endif
+++ /dev/null
-/*
- * strcasecmp() implementation for systems that don't have it or stricmp()
- * or strcmpi().
- *
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * 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 University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-
-#ifdef USE_OUR_OWN_STRCASECMP
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-#include <ctype.h>
-
-int
-yasm__strcasecmp(const char *s1, const char *s2)
-{
- const unsigned char
- *us1 = (const unsigned char *)s1,
- *us2 = (const unsigned char *)s2;
-
- while (tolower(*us1) == tolower(*us2++))
- if (*us1++ == '\0')
- return (0);
- return (tolower(*us1) - tolower(*--us2));
-}
-
-int
-yasm__strncasecmp(const char *s1, const char *s2, size_t n)
-{
- const unsigned char
- *us1 = (const unsigned char *)s1,
- *us2 = (const unsigned char *)s2;
-
- if (n != 0) {
- do {
- if (tolower(*us1) != tolower(*us2++))
- return (tolower(*us1) - tolower(*--us2));
- if (*us1++ == '\0')
- break;
- } while (--n != 0);
- }
- return (0);
-}
-#endif
+++ /dev/null
-/*
- * Symbol table handling
- *
- * Copyright (C) 2001 Michael Urman, 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#ifdef STDC_HEADERS
-# include <limits.h>
-#endif
-
-#include "hamt.h"
-
-#include "errwarn.h"
-#include "floatnum.h"
-#include "expr.h"
-#include "symrec.h"
-
-#include "bytecode.h"
-#include "section.h"
-#include "objfmt.h"
-
-
-/* DEFINED is set with EXTERN and COMMON below */
-typedef enum {
- SYM_NOSTATUS = 0,
- SYM_USED = 1 << 0, /* for using variables before definition */
- SYM_DEFINED = 1 << 1, /* once it's been defined in the file */
- SYM_VALUED = 1 << 2, /* once its value has been determined */
- SYM_NOTINTABLE = 1 << 3 /* if it's not in sym_table (ex. '$') */
-} sym_status;
-
-typedef enum {
- SYM_UNKNOWN, /* for unknown type (COMMON/EXTERN) */
- SYM_EQU, /* for EQU defined symbols (expressions) */
- SYM_LABEL /* for labels */
-} sym_type;
-
-struct yasm_symrec {
- char *name;
- sym_type type;
- sym_status status;
- yasm_sym_vis visibility;
- unsigned long line; /* symbol was first declared or used on */
- union {
- yasm_expr *expn; /* equ value */
- struct label_s { /* bytecode immediately preceding a label */
- /*@dependent@*/ /*@null@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *bc;
- } label;
- } value;
-
- /* objfmt-specific data */
- /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
- /*@null@*/ /*@owned@*/ void *of_data;
-
- /* storage for optimizer flags */
- unsigned long opt_flags;
-};
-
-/* The symbol table: a hash array mapped trie (HAMT). */
-static /*@only@*/ HAMT *sym_table;
-
-/* Linked list of symbols not in the symbol table. */
-typedef struct non_table_symrec_s {
- /*@reldef@*/ SLIST_ENTRY(non_table_symrec_s) link;
- /*@owned@*/ yasm_symrec *rec;
-} non_table_symrec;
-typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s)
- nontablesymhead;
-static /*@only@*/ nontablesymhead *non_table_syms;
-
-
-void
-yasm_symrec_initialize(void)
-{
- sym_table = HAMT_new(yasm_internal_error_);
- non_table_syms = yasm_xmalloc(sizeof(nontablesymhead));
- SLIST_INIT(non_table_syms);
-}
-
-static void
-symrec_delete_one(/*@only@*/ void *d)
-{
- yasm_symrec *sym = d;
- yasm_xfree(sym->name);
- if (sym->type == SYM_EQU)
- yasm_expr_delete(sym->value.expn);
- if (sym->of_data && sym->of) {
- if (sym->of->symrec_data_delete)
- sym->of->symrec_data_delete(sym->of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific data"));
- }
- yasm_xfree(sym);
-}
-
-static /*@partial@*/ yasm_symrec *
-symrec_new_common(/*@keep@*/ char *name)
-{
- yasm_symrec *rec = yasm_xmalloc(sizeof(yasm_symrec));
- rec->name = name;
- rec->type = SYM_UNKNOWN;
- rec->line = 0;
- rec->visibility = YASM_SYM_LOCAL;
- rec->of = NULL;
- rec->of_data = NULL;
- rec->opt_flags = 0;
- return rec;
-}
-
-static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_in_table(/*@only@*/ char *name)
-{
- yasm_symrec *rec = symrec_new_common(name);
- int replace = 0;
-
- rec->status = SYM_NOSTATUS;
-
- return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one);
-}
-
-static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_not_in_table(/*@only@*/ char *name)
-{
- non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
- sym->rec = symrec_new_common(name);
-
- sym->rec->status = SYM_NOTINTABLE;
-
- SLIST_INSERT_HEAD(non_table_syms, sym, link);
-
- return sym->rec;
-}
-
-/* create a new symrec */
-/*@-freshtrans -mustfree@*/
-static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new(const char *name, int in_table)
-{
- char *symname = yasm__xstrdup(name);
-
- if (in_table)
- return symrec_get_or_new_in_table(symname);
- else
- return symrec_get_or_new_not_in_table(symname);
-}
-/*@=freshtrans =mustfree@*/
-
-/* Call a function with each symrec. Stops early if 0 returned by func.
- Returns 0 if stopped early. */
-int
-yasm_symrec_traverse(void *d, int (*func) (yasm_symrec *sym, void *d))
-{
- return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
-}
-
-yasm_symrec *
-yasm_symrec_use(const char *name, unsigned long lindex)
-{
- yasm_symrec *rec = symrec_get_or_new(name, 1);
- if (rec->line == 0)
- rec->line = lindex; /* set line number of first use */
- rec->status |= SYM_USED;
- return rec;
-}
-
-static /*@dependent@*/ yasm_symrec *
-symrec_define(const char *name, sym_type type, int in_table,
- unsigned long lindex)
-{
- yasm_symrec *rec = symrec_get_or_new(name, in_table);
-
- /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
- if ((rec->status & SYM_DEFINED) ||
- (rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN))) {
- yasm__error(lindex,
- N_("duplicate definition of `%s'; first defined on line %lu"),
- name, rec->line);
- } else {
- rec->line = lindex; /* set line number of definition */
- rec->type = type;
- rec->status |= SYM_DEFINED;
- }
- return rec;
-}
-
-yasm_symrec *
-yasm_symrec_define_equ(const char *name, yasm_expr *e, unsigned long lindex)
-{
- yasm_symrec *rec = symrec_define(name, SYM_EQU, 1, lindex);
- rec->value.expn = e;
- rec->status |= SYM_VALUED;
- return rec;
-}
-
-yasm_symrec *
-yasm_symrec_define_label(const char *name, yasm_section *sect,
- yasm_bytecode *precbc, int in_table,
- unsigned long lindex)
-{
- yasm_symrec *rec = symrec_define(name, SYM_LABEL, in_table, lindex);
- rec->value.label.sect = sect;
- rec->value.label.bc = precbc;
- return rec;
-}
-
-yasm_symrec *
-yasm_symrec_declare(const char *name, yasm_sym_vis vis, unsigned long lindex)
-{
- yasm_symrec *rec = symrec_get_or_new(name, 1);
-
- /* Allowable combinations:
- * Existing State-------------- vis New State-------------------
- * DEFINED GLOBAL COMMON EXTERN GCE DEFINED GLOBAL COMMON EXTERN
- * 0 - 0 0 GCE 0 G C E
- * 0 - 0 1 GE 0 G 0 E
- * 0 - 1 0 GC 0 G C 0
- * X 0 - 1 1
- * 1 - 0 0 G 1 G 0 0
- * X 1 - - 1
- * X 1 - 1 -
- */
- if ((vis == YASM_SYM_GLOBAL) ||
- (!(rec->status & SYM_DEFINED) &&
- (!(rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN)) ||
- ((rec->visibility & YASM_SYM_COMMON) && (vis == YASM_SYM_COMMON)) ||
- ((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
- rec->visibility |= vis;
- else
- yasm__error(lindex,
- N_("duplicate definition of `%s'; first defined on line %lu"),
- name, rec->line);
- return rec;
-}
-
-const char *
-yasm_symrec_get_name(const yasm_symrec *sym)
-{
- return sym->name;
-}
-
-yasm_sym_vis
-yasm_symrec_get_visibility(const yasm_symrec *sym)
-{
- return sym->visibility;
-}
-
-const yasm_expr *
-yasm_symrec_get_equ(const yasm_symrec *sym)
-{
- if (sym->type == SYM_EQU)
- return sym->value.expn;
- return (const yasm_expr *)NULL;
-}
-
-int
-yasm_symrec_get_label(const yasm_symrec *sym,
- yasm_symrec_get_label_sectionp *sect,
- yasm_symrec_get_label_bytecodep *precbc)
-{
- if (sym->type != SYM_LABEL) {
- *sect = (yasm_symrec_get_label_sectionp)0xDEADBEEF;
- *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
- return 0;
- }
- *sect = sym->value.label.sect;
- *precbc = sym->value.label.bc;
- return 1;
-}
-
-unsigned long
-yasm_symrec_get_opt_flags(const yasm_symrec *sym)
-{
- return sym->opt_flags;
-}
-
-void
-yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags)
-{
- sym->opt_flags = opt_flags;
-}
-
-void *
-yasm_symrec_get_of_data(yasm_symrec *sym)
-{
- return sym->of_data;
-}
-
-void
-yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of, void *of_data)
-{
- if (sym->of_data && sym->of) {
- if (sym->of->symrec_data_delete)
- sym->of->symrec_data_delete(sym->of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific data"));
- }
- sym->of = of;
- sym->of_data = of_data;
-}
-
-static unsigned long firstundef_line;
-static int
-symrec_parser_finalize_checksym(yasm_symrec *sym,
- /*@unused@*/ /*@null@*/ void *d)
-{
- /* error if a symbol is used but never defined or extern/common declared */
- if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
- !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
- yasm__error(sym->line, N_("undefined symbol `%s' (first use)"),
- sym->name);
- if (sym->line < firstundef_line)
- firstundef_line = sym->line;
- }
-
- return 1;
-}
-
-void
-yasm_symrec_parser_finalize(void)
-{
- firstundef_line = ULONG_MAX;
- yasm_symrec_traverse(NULL, symrec_parser_finalize_checksym);
- if (firstundef_line < ULONG_MAX)
- yasm__error(firstundef_line,
- N_(" (Each undefined symbol is reported only once.)"));
-}
-
-void
-yasm_symrec_cleanup(void)
-{
- HAMT_delete(sym_table, symrec_delete_one);
-
- while (!SLIST_EMPTY(non_table_syms)) {
- non_table_symrec *sym = SLIST_FIRST(non_table_syms);
- SLIST_REMOVE_HEAD(non_table_syms, link);
- symrec_delete_one(sym->rec);
- yasm_xfree(sym);
- }
- yasm_xfree(non_table_syms);
-}
-
-typedef struct symrec_print_data {
- FILE *f;
- int indent_level;
-} symrec_print_data;
-
-/*@+voidabstract@*/
-static int
-symrec_print_wrapper(yasm_symrec *sym, /*@null@*/ void *d)
-{
- symrec_print_data *data = (symrec_print_data *)d;
- assert(data != NULL);
- fprintf(data->f, "%*sSymbol `%s'\n", data->indent_level, "", sym->name);
- yasm_symrec_print(data->f, data->indent_level+1, sym);
- return 1;
-}
-
-void
-yasm_symrec_print_all(FILE *f, int indent_level)
-{
- symrec_print_data data;
- data.f = f;
- data.indent_level = indent_level;
- yasm_symrec_traverse(&data, symrec_print_wrapper);
-}
-/*@=voidabstract@*/
-
-void
-yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym)
-{
- switch (sym->type) {
- case SYM_UNKNOWN:
- fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
- break;
- case SYM_EQU:
- fprintf(f, "%*s_EQU_\n", indent_level, "");
- fprintf(f, "%*sExpn=", indent_level, "");
- yasm_expr_print(f, sym->value.expn);
- fprintf(f, "\n");
- break;
- case SYM_LABEL:
- fprintf(f, "%*s_Label_\n%*sSection:\n", indent_level, "",
- indent_level, "");
- yasm_section_print(f, indent_level+1, sym->value.label.sect, 0);
- if (!sym->value.label.bc)
- fprintf(f, "%*sFirst bytecode\n", indent_level, "");
- else {
- fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
- yasm_bc_print(f, indent_level+1, sym->value.label.bc);
- }
- break;
- }
-
- fprintf(f, "%*sStatus=", indent_level, "");
- if (sym->status == SYM_NOSTATUS)
- fprintf(f, "None\n");
- else {
- if (sym->status & SYM_USED)
- fprintf(f, "Used,");
- if (sym->status & SYM_DEFINED)
- fprintf(f, "Defined,");
- if (sym->status & SYM_VALUED)
- fprintf(f, "Valued,");
- if (sym->status & SYM_NOTINTABLE)
- fprintf(f, "Not in Table,");
- fprintf(f, "\n");
- }
-
- fprintf(f, "%*sVisibility=", indent_level, "");
- if (sym->visibility == YASM_SYM_LOCAL)
- fprintf(f, "Local\n");
- else {
- if (sym->visibility & YASM_SYM_GLOBAL)
- fprintf(f, "Global,");
- if (sym->visibility & YASM_SYM_COMMON)
- fprintf(f, "Common,");
- if (sym->visibility & YASM_SYM_EXTERN)
- fprintf(f, "Extern,");
- fprintf(f, "\n");
- }
-
- if (sym->of_data && sym->of) {
- fprintf(f, "%*sObject format-specific data:\n", indent_level, "");
- if (sym->of->symrec_data_print)
- sym->of->symrec_data_print(f, indent_level+1, sym->of_data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level+1, "");
- }
-
- fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
-}
+++ /dev/null
-/* $IdPath$
- * Symbol table handling header file
- *
- * Copyright (C) 2001 Michael Urman, 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.
- *
- * 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.
- */
-#ifndef YASM_SYMREC_H
-#define YASM_SYMREC_H
-
-void yasm_symrec_initialize(void);
-
-/*@dependent@*/ yasm_symrec *yasm_symrec_use(const char *name,
- unsigned long lindex);
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_equ
- (const char *name, /*@keep@*/ yasm_expr *e, unsigned long lindex);
-/* in_table specifies if the label should be inserted into the symbol table.
- * All labels are memory managed internally.
- */
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_label
- (const char *name, /*@dependent@*/ /*@null@*/ yasm_section *sect,
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc, int in_table,
- unsigned long lindex);
-/*@dependent@*/ yasm_symrec *yasm_symrec_declare
- (const char *name, yasm_sym_vis vis, unsigned long lindex);
-
-/*@observer@*/ const char *yasm_symrec_get_name(const yasm_symrec *sym);
-yasm_sym_vis yasm_symrec_get_visibility(const yasm_symrec *sym);
-
-/*@observer@*/ /*@null@*/ const yasm_expr *yasm_symrec_get_equ
- (const yasm_symrec *sym);
-/* Returns 0 if not a label or if EXTERN/COMMON (not defined in the file) */
-typedef /*@dependent@*/ /*@null@*/ yasm_section *
- yasm_symrec_get_label_sectionp;
-typedef /*@dependent@*/ /*@null@*/ yasm_bytecode *
- yasm_symrec_get_label_bytecodep;
-int yasm_symrec_get_label(const yasm_symrec *sym,
- /*@out@*/ yasm_symrec_get_label_sectionp *sect,
- /*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
-
-/* Get and set optimizer flags */
-unsigned long yasm_symrec_get_opt_flags(const yasm_symrec *sym);
-void yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags);
-
-/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_of_data(yasm_symrec *sym);
-
-/* Caution: deletes any existing of_data */
-void yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of,
- /*@only@*/ /*@null@*/ void *of_data);
-
-int /*@alt void@*/ yasm_symrec_traverse
- (/*@null@*/ void *d, int (*func) (yasm_symrec *sym, /*@null@*/ void *d));
-
-void yasm_symrec_parser_finalize(void);
-
-void yasm_symrec_cleanup(void);
-
-void yasm_symrec_print_all(FILE *f, int indent_level);
-
-void yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym);
-#endif
+++ /dev/null
-# $IdPath$
-
-TESTS += \
- bitvect_test \
- floatnum_test
-
-noinst_PROGRAMS += \
- bitvect_test \
- floatnum_test
-
-bitvect_test_CFLAGS =
-bitvect_test_SOURCES = \
- src/tests/bitvect_test.c \
- $(CHECKFILES)
-bitvect_test_LDFLAGS =
-bitvect_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
-
-#bytecode_test_CFLAGS =
-#bytecode_test_SOURCES = \
-# src/tests/bytecode_test.c \
-# $(YASMPARSERFILES) \
-# $(YASMPREPROCFILES) \
-# $(YASMOPTIMIZERFILES) \
-# $(YASMOBJFMTFILES) \
-# $(YASMARCHFILES) \
-# $(CHECKFILES)
-#bytecode_test_LDFLAGS =
-#bytecode_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
-
-floatnum_test_CFLAGS =
-floatnum_test_SOURCES = \
- src/tests/floatnum_test.c \
- $(CHECKFILES)
-floatnum_test_LDFLAGS =
-floatnum_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
-
-#memexpr_test_CFLAGS =
-#memexpr_test_SOURCES = \
-# src/tests/memexpr_test.c \
-# $(YASMPARSERFILES) \
-# $(YASMPREPROCFILES) \
-# $(YASMOPTIMIZERFILES) \
-# $(YASMOBJFMTFILES) \
-# $(YASMARCHFILES) \
-# $(CHECKFILES)
-#memexpr_test_LDFLAGS =
-#memexpr_test_LDADD = libyasm.la @LIBLTDL@ @LIBOBJS@ $(INTLLIBS) @LIBADD_DL@
+++ /dev/null
-/* $IdPath$
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-#endif
-
-#include <stdio.h>
-
-#include "check.h"
-
-#include "bitvect.h"
-
-START_TEST(test_boot)
-{
- fail_unless(BitVector_Boot() == ErrCode_Ok, "failed to Boot()");
-}
-END_TEST
-
-typedef struct Val_s {
- const char *ascii;
- unsigned char result[10]; /* 80 bit result, little endian */
-} Val;
-
-Val oct_small_vals[] = {
- { "0",
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
- { "1",
- {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
- { "77",
- {0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
-};
-
-Val oct_large_vals[] = {
- { "7654321076543210",
- {0x88, 0xC6, 0xFA, 0x88, 0xC6, 0xFA, 0x00, 0x00, 0x00, 0x00}
- },
- { "12634727612534126530214",
- {0x8C, 0xB0, 0x5A, 0xE1, 0xAA, 0xF8, 0x3A, 0x67, 0x05, 0x00}
- },
- { "61076543210",
- {0x88, 0xC6, 0xFA, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
-};
-
-wordptr testval;
-
-static void
-num_family_setup(void)
-{
- BitVector_Boot();
- testval = BitVector_Create(80, FALSE);
-}
-
-static void
-num_family_teardown(void)
-{
- BitVector_Destroy(testval);
-}
-
-static char result_msg[1024];
-
-static int
-num_check(Val *val)
-{
- unsigned char ascii[64], *result;
- unsigned int len;
- int i;
- int ret = 0;
-
- strcpy((char *)ascii, val->ascii);
- strcpy(result_msg, "parser failure");
- if(BitVector_from_Oct(testval, ascii) != ErrCode_Ok)
- return 1;
-
- result = BitVector_Block_Read(testval, &len);
-
- for (i=0; i<10; i++)
- if (result[i] != val->result[i])
- ret = 1;
-
- if (ret) {
- strcpy(result_msg, val->ascii);
- for (i=0; i<10; i++)
- sprintf((char *)ascii+3*i, "%02x ", result[i]);
- strcat(result_msg, ": ");
- strcat(result_msg, (char *)ascii);
- }
- free(result);
-
- return ret;
-}
-
-START_TEST(test_oct_small_num)
-{
- Val *vals = oct_small_vals;
- int i, num = sizeof(oct_small_vals)/sizeof(Val);
-
- for (i=0; i<num; i++)
- fail_unless(num_check(&vals[i]) == 0, result_msg);
-}
-END_TEST
-
-START_TEST(test_oct_large_num)
-{
- Val *vals = oct_large_vals;
- int i, num = sizeof(oct_large_vals)/sizeof(Val);
-
- for (i=0; i<num; i++)
- fail_unless(num_check(&vals[i]) == 0, result_msg);
-}
-END_TEST
-
-static Suite *
-bitvect_suite(void)
-{
- Suite *s = suite_create("BitVector");
- TCase *tc_boot = tcase_create("Boot");
- TCase *tc_from_oct = tcase_create("from_Oct");
-
- suite_add_tcase(s, tc_boot);
- tcase_add_test(tc_boot, test_boot);
-
- suite_add_tcase(s, tc_from_oct);
- tcase_add_test(tc_from_oct, test_oct_small_num);
- tcase_add_test(tc_from_oct, test_oct_large_num);
- tcase_set_fixture(tc_from_oct, num_family_setup, num_family_teardown);
-
- return s;
-}
-
-int
-main(void)
-{
- int nf;
- Suite *s = bitvect_suite();
- SRunner *sr = srunner_create(s);
- srunner_run_all(sr, CRNORMAL);
- nf = srunner_ntests_failed(sr);
- srunner_free(sr);
- suite_free(s);
- return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
+++ /dev/null
-/* $IdPath$
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-
-#include "check.h"
-
-#include "bytecode.h"
-#include "bc-int.h"
-#include "arch.h"
-#include "x86arch.h"
-
-START_TEST(test_x86_ea_new_reg)
-{
- effaddr *ea;
- x86_effaddr_data *ead;
- int i;
-
- /* Test with NULL */
- ea = x86_ea_new_reg(1);
- fail_unless(ea != NULL, "Should die if out of memory (not return NULL)");
-
- /* Test structure values function should set */
- fail_unless(ea->len == 0, "len should be 0");
- ead = ea_get_data(ea);
- fail_unless(ead->segment == 0, "Should be no segment override");
- fail_unless(ead->valid_modrm == 1, "Mod/RM should be valid");
- fail_unless(ead->need_modrm == 1, "Mod/RM should be needed");
- fail_unless(ead->valid_sib == 0, "SIB should be invalid");
- fail_unless(ead->need_sib == 0, "SIB should not be needed");
-
- free(ea);
-
- /* Exhaustively test generated Mod/RM byte with register values */
- for(i=0; i<8; i++) {
- ea = x86_ea_new_reg(i);
- ead = ea_get_data(ea);
- fail_unless(ead->modrm == (0xC0 | (i & 0x07)),
- "Invalid Mod/RM byte generated");
- free(ea);
- }
-}
-END_TEST
-
-static Suite *
-bytecode_suite(void)
-{
- Suite *s = suite_create("bytecode");
- TCase *tc_conversion = tcase_create("Conversion");
-
- suite_add_tcase(s, tc_conversion);
- tcase_add_test(tc_conversion, test_x86_ea_new_reg);
-
- return s;
-}
-
-int
-main(void)
-{
- int nf;
- Suite *s = bytecode_suite();
- SRunner *sr = srunner_create(s);
- srunner_run_all(sr, CRNORMAL);
- nf = srunner_ntests_failed(sr);
- srunner_free(sr);
- suite_free(s);
- return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
+++ /dev/null
-/* $IdPath$
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-#endif
-
-#include <stdio.h>
-
-#include "check.h"
-
-#include "floatnum.c"
-
-/* constants describing parameters of internal floating point format.
- * (these should match those in src/floatnum.c !)
- */
-#define MANT_BITS 80
-#define MANT_BYTES 10
-
-typedef struct Init_Entry_s {
- /* input ASCII value */
- const char *ascii;
-
- /* correct output from ASCII conversion */
- unsigned char mantissa[MANT_BYTES]; /* little endian mantissa - first
- byte is not checked for
- correctness. */
- unsigned short exponent; /* bias 32767 exponent */
- unsigned char sign;
- unsigned char flags;
-
- /* correct output conversions - these should be *exact* matches */
- int ret32;
- unsigned char result32[4];
- int ret64;
- unsigned char result64[8];
- int ret80;
- unsigned char result80[10];
-} Init_Entry;
-
-/* Values used for normalized tests */
-static Init_Entry normalized_vals[] = {
- { "3.141592653589793",
- {0xc6,0x0d,0xe9,0xbd,0x68,0x21,0xa2,0xda,0x0f,0xc9},0x8000,0,0,
- 0, {0xdb,0x0f,0x49,0x40},
- 0, {0x18,0x2d,0x44,0x54,0xfb,0x21,0x09,0x40},
- 0, {0xe9,0xbd,0x68,0x21,0xa2,0xda,0x0f,0xc9,0x00,0x40}
- },
- { "-3.141592653589793",
- {0xc6,0x0d,0xe9,0xbd,0x68,0x21,0xa2,0xda,0x0f,0xc9},0x8000,1,0,
- 0, {0xdb,0x0f,0x49,0xc0},
- 0, {0x18,0x2d,0x44,0x54,0xfb,0x21,0x09,0xc0},
- 0, {0xe9,0xbd,0x68,0x21,0xa2,0xda,0x0f,0xc9,0x00,0xc0}
- },
- { "1.e16",
- {0x00,0x00,0x00,0x00,0x00,0x04,0xbf,0xc9,0x1b,0x8e},0x8034,0,0,
- 0, {0xca,0x1b,0x0e,0x5a},
- 0, {0x00,0x80,0xe0,0x37,0x79,0xc3,0x41,0x43},
- 0, {0x00,0x00,0x00,0x04,0xbf,0xc9,0x1b,0x8e,0x34,0x40}
- },
- { "1.6e-20",
- {0xf6,0xd3,0xee,0x7b,0xda,0x74,0x50,0xa0,0x1d,0x97},0x7fbd,0,0,
- 0, {0xa0,0x1d,0x97,0x1e},
- 0, {0x4f,0x9b,0x0e,0x0a,0xb4,0xe3,0xd2,0x3b},
- 0, {0xef,0x7b,0xda,0x74,0x50,0xa0,0x1d,0x97,0xbd,0x3f}
- },
- { "-5876.",
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xb7},0x800b,1,0,
- 0, {0x00,0xa0,0xb7,0xc5},
- 0, {0x00,0x00,0x00,0x00,0x00,0xf4,0xb6,0xc0},
- 0, {0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xb7,0x0b,0xc0}
- },
-};
-
-/* Still normalized values, but edge cases of various sizes, testing underflow/
- * overflow checks as well.
- */
-static Init_Entry normalized_edgecase_vals[] = {
- /* 32-bit edges */
- { "1.1754943508222875e-38",
- {0xd5,0xf2,0x82,0xff,0xff,0xff,0xff,0xff,0xff,0xff},0x7f80,0,0,
- 0, {0x00,0x00,0x80,0x00},
- 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38},
- 0, {0x83,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x3f}
- },
- { "3.4028234663852886e+38",
- {0x21,0x35,0x0a,0x00,0x00,0x00,0x00,0xff,0xff,0xff},0x807e,0,0,
- 0, {0xff,0xff,0x7f,0x7f},
- 0, {0x00,0x00,0x00,0xe0,0xff,0xff,0xef,0x47},
- 0, {0x0a,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x7e,0x40}
- },
- /* 64-bit edges */
- { "2.2250738585072014E-308",
- {0x26,0x18,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7c01,0,0,
- -1, {0x00,0x00,0x00,0x00},
- 0, {0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00},
- 0, {0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x3c}
- },
- { "1.7976931348623157E+308",
- {0x26,0x6b,0xac,0xf7,0xff,0xff,0xff,0xff,0xff,0xff},0x83fe,0,0,
- 1, {0x00,0x00,0x80,0x7f},
- 0, {0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x7f},
- 0, {0xac,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x43}
- },
- /* 80-bit edges */
-/* { "3.3621E-4932",
- {},,0,0,
- -1, {0x00,0x00,0x00,0x00},
- -1, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- 0, {}
- },
- { "1.1897E+4932",
- {},,0,0,
- 1, {0x00,0x00,0x80,0x7f},
- 1, {},
- 0, {}
- },*/
- /* internal format edges */
-/* {
- },
- {
- },*/
-};
-
-static yasm_floatnum *flt;
-
-/* failure messages */
-static char ret_msg[1024], result_msg[1024];
-
-static void
-new_setup(Init_Entry *vals, int i)
-{
- flt = yasm_floatnum_new(vals[i].ascii);
- strcpy(result_msg, vals[i].ascii);
- strcat(result_msg, ": incorrect ");
-}
-
-static int
-new_check_flt(Init_Entry *val)
-{
- unsigned char *mantissa;
- int i, result = 0;
- unsigned int len;
-
- mantissa = BitVector_Block_Read(flt->mantissa, &len);
- for (i=1;i<MANT_BYTES;i++) /* don't compare first byte */
- if (mantissa[i] != val->mantissa[i])
- result = 1;
- free(mantissa);
- if (result) {
- strcat(result_msg, "mantissa");
- return 1;
- }
-
- if (flt->exponent != val->exponent) {
- strcat(result_msg, "exponent");
- return 1;
- }
- if (flt->sign != val->sign) {
- strcat(result_msg, "sign");
- return 1;
- }
- if (flt->flags != val->flags) {
- strcat(result_msg, "flags");
- return 1;
- }
- return 0;
-}
-
-START_TEST(test_new_normalized)
-{
- Init_Entry *vals = normalized_vals;
- int i, num = sizeof(normalized_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- new_setup(vals, i);
- fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
- yasm_floatnum_delete(flt);
- }
-}
-END_TEST
-
-START_TEST(test_new_normalized_edgecase)
-{
- Init_Entry *vals = normalized_edgecase_vals;
- int i, num = sizeof(normalized_edgecase_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- new_setup(vals, i);
- fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
- yasm_floatnum_delete(flt);
- }
-}
-END_TEST
-
-static void
-get_family_setup(void)
-{
- flt = malloc(sizeof(yasm_floatnum));
- flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
-}
-
-static void
-get_family_teardown(void)
-{
- BitVector_Destroy(flt->mantissa);
- free(flt);
-}
-
-static void
-get_common_setup(Init_Entry *vals, int i)
-{
- /* set up flt */
- BitVector_Block_Store(flt->mantissa, vals[i].mantissa, MANT_BYTES);
- flt->sign = vals[i].sign;
- flt->exponent = vals[i].exponent;
- flt->flags = vals[i].flags;
-
- /* set failure messages */
- strcpy(ret_msg, vals[i].ascii);
- strcat(ret_msg, ": incorrect return value");
- strcpy(result_msg, vals[i].ascii);
- strcat(result_msg, ": incorrect result generated");
-}
-#if 0
-static void
-append_get_return_value(int val)
-{
- char str[64];
- sprintf(str, ": %d", val);
- strcat(ret_msg, str);
-}
-#endif
-static int
-get_common_check_result(int len, const unsigned char *val,
- const unsigned char *correct)
-{
- char str[64];
- int i;
- int result = 0;
-
- for (i=0;i<len;i++)
- if (val[i] != correct[i])
- result = 1;
-
- if (result) {
- for (i=0; i<len; i++)
- sprintf(str+3*i, "%02x ", val[i]);
- strcat(result_msg, ": ");
- strcat(result_msg, str);
- }
-
- return result;
-}
-
-/*
- * get_single tests
- */
-
-START_TEST(test_get_single_normalized)
-{
- unsigned char outval[4];
- Init_Entry *vals = normalized_vals;
- int i, num = sizeof(normalized_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 4) == vals[i].ret32,
- ret_msg);
- fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
- result_msg);
- }
-}
-END_TEST
-
-START_TEST(test_get_single_normalized_edgecase)
-{
- unsigned char outval[4];
- Init_Entry *vals = normalized_edgecase_vals;
- int i, num = sizeof(normalized_edgecase_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 4) == vals[i].ret32,
- ret_msg);
- fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
- result_msg);
- }
-}
-END_TEST
-
-/*
- * get_double tests
- */
-
-START_TEST(test_get_double_normalized)
-{
- unsigned char outval[8];
- Init_Entry *vals = normalized_vals;
- int i, num = sizeof(normalized_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 8) == vals[i].ret64,
- ret_msg);
- fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
- result_msg);
- }
-}
-END_TEST
-
-START_TEST(test_get_double_normalized_edgecase)
-{
- unsigned char outval[8];
- Init_Entry *vals = normalized_edgecase_vals;
- int i, num = sizeof(normalized_edgecase_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 8) == vals[i].ret64,
- ret_msg);
- fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
- result_msg);
- }
-}
-END_TEST
-
-/*
- * get_extended tests
- */
-
-START_TEST(test_get_extended_normalized)
-{
- unsigned char outval[10];
- Init_Entry *vals = normalized_vals;
- int i, num = sizeof(normalized_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 10) == vals[i].ret80,
- ret_msg);
- fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
- result_msg);
- }
-}
-END_TEST
-
-START_TEST(test_get_extended_normalized_edgecase)
-{
- unsigned char outval[10];
- Init_Entry *vals = normalized_edgecase_vals;
- int i, num = sizeof(normalized_edgecase_vals)/sizeof(Init_Entry);
-
- for (i=0; i<num; i++) {
- get_common_setup(vals, i);
- fail_unless(yasm_floatnum_get_sized(flt, outval, 10) == vals[i].ret80,
- ret_msg);
- fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
- result_msg);
- }
-}
-END_TEST
-
-static Suite *
-floatnum_suite(void)
-{
- Suite *s = suite_create("floatnum");
- TCase *tc_new = tcase_create("new");
- TCase *tc_get_single = tcase_create("get_single");
- TCase *tc_get_double = tcase_create("get_double");
- TCase *tc_get_extended = tcase_create("get_extended");
-
- suite_add_tcase(s, tc_new);
- tcase_add_test(tc_new, test_new_normalized);
- tcase_add_test(tc_new, test_new_normalized_edgecase);
-
- suite_add_tcase(s, tc_get_single);
- tcase_add_test(tc_get_single, test_get_single_normalized);
- tcase_add_test(tc_get_single, test_get_single_normalized_edgecase);
- tcase_set_fixture(tc_get_single, get_family_setup, get_family_teardown);
-
- suite_add_tcase(s, tc_get_double);
- tcase_add_test(tc_get_double, test_get_double_normalized);
- tcase_add_test(tc_get_double, test_get_double_normalized_edgecase);
- tcase_set_fixture(tc_get_double, get_family_setup, get_family_teardown);
-
- suite_add_tcase(s, tc_get_extended);
- tcase_add_test(tc_get_extended, test_get_extended_normalized);
- tcase_add_test(tc_get_extended, test_get_extended_normalized_edgecase);
- tcase_set_fixture(tc_get_extended, get_family_setup, get_family_teardown);
-
- return s;
-}
-
-int
-main(void)
-{
- int nf;
- Suite *s = floatnum_suite();
- SRunner *sr = srunner_create(s);
- BitVector_Boot();
- yasm_floatnum_initialize();
- srunner_run_all(sr, CRNORMAL);
- nf = srunner_ntests_failed(sr);
- srunner_free(sr);
- suite_free(s);
- return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
+++ /dev/null
-/* $IdPath$
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-
-#include "check.h"
-
-#include "bitvect.h"
-
-#include "errwarn.h"
-
-#include "expr.h"
-#include "intnum.h"
-#include "floatnum.h"
-
-#include "bytecode.h"
-#include "arch.h"
-#include "x86arch.h"
-
-typedef enum {
- REG_AX = 0,
- REG_CX = 1,
- REG_DX = 2,
- REG_BX = 3,
- REG_SP = 4,
- REG_BP = 5,
- REG_SI = 6,
- REG_DI = 7
-} reg16type;
-
-/* Memory expression building functions.
- * These try to exactly match how a parser will build up the expr for _in,
- * and exactly what the output expr should be for _out.
- */
-
-/* [5] */
-static expr *
-gen_5_in(void)
-{
- return expr_new_ident(ExprInt(intnum_new_uint(5)));
-}
-#define gen_5_out gen_5_in
-/* [1.2] */
-static expr *
-gen_1pt2_in(void)
-{
- return expr_new_ident(ExprFloat(floatnum_new("1.2")));
-}
-/* No _out, it's invalid */
-/* [ecx] */
-static expr *
-gen_ecx_in(void)
-{
- return expr_new_ident(ExprReg(REG_CX, 32));
-}
-#define gen_ecx_out NULL
-/* [di] */
-static expr *
-gen_di_in(void)
-{
- return expr_new_ident(ExprReg(REG_DI, 16));
-}
-#define gen_di_out NULL
-/* [di-si+si+126] */
-static expr *
-gen_dimsipsip126_in(void)
-{
- return expr_new_tree(
- expr_new_tree(
- expr_new_tree(
- expr_new_ident(ExprReg(REG_DI, 16)),
- EXPR_SUB,
- expr_new_ident(ExprReg(REG_SI, 16))),
- EXPR_ADD,
- expr_new_ident(ExprReg(REG_SI, 16))),
- EXPR_ADD,
- expr_new_ident(ExprInt(intnum_new_uint(126))));
-}
-#define gen_dimsipsip126_out NULL
-/* [bx-(bx-di)+bx-2] */
-static expr *
-gen_bxmqbxmdiqpbxm2_in(void)
-{
- return expr_new_tree(
- expr_new_tree(
- expr_new_tree(
- expr_new_ident(ExprReg(REG_BX, 16)),
- EXPR_SUB,
- expr_new_tree(
- expr_new_ident(ExprReg(REG_BX, 16)),
- EXPR_SUB,
- expr_new_ident(ExprReg(REG_DI, 16)))),
- EXPR_ADD,
- expr_new_ident(ExprReg(REG_BX, 16))),
- EXPR_SUB,
- expr_new_ident(ExprInt(intnum_new_uint(2))));
-}
-static expr *
-gen_bxmqbxmdiqpbxm2_out(void)
-{
- return expr_new_ident(ExprInt(intnum_new_int(-2)));
-}
-/* [bp] */
-static expr *
-gen_bp_in(void)
-{
- return expr_new_ident(ExprReg(REG_BP, 16));
-}
-#define gen_bp_out NULL
-/* [bp*1+500] */
-static expr *
-gen_bpx1p500_in(void)
-{
- return expr_new_tree(
- expr_new_tree(
- expr_new_ident(ExprReg(REG_BP, 16)),
- EXPR_MUL,
- expr_new_ident(ExprInt(intnum_new_uint(1)))),
- EXPR_ADD,
- expr_new_ident(ExprInt(intnum_new_uint(500))));
-}
-static expr *
-gen_bpx1p500_out(void)
-{
- return expr_new_ident(ExprInt(intnum_new_uint(500)));
-}
-
-typedef struct CheckEA_InOut {
- /* Function to generate input/output expr. */
- expr *(*expr_gen)(void);
- unsigned char addrsize;
- unsigned char bits;
- unsigned char nosplit;
- unsigned char displen;
- unsigned char modrm;
- unsigned char v_modrm;
- unsigned char n_modrm;
- unsigned char sib;
- unsigned char v_sib;
- unsigned char n_sib;
-} CheckEA_InOut;
-
-typedef struct CheckEA_Entry {
- const char *ascii; /* Text description of input */
- CheckEA_InOut in; /* Input Parameter Values */
- int retval; /* Return value */
- CheckEA_InOut out; /* Correct output Parameter Values
- (N/A if retval=0) */
-} CheckEA_Entry;
-
-/* Values used for tests */
-static CheckEA_Entry bits16_vals[] = {
- {
- "[5]",
- {gen_5_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0}
- },
- {
- "a16 [5]",
- {gen_5_in , 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0}
- },
- {
- "a32 [5]",
- {gen_5_in , 32, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1}
- },
- {
- "[word 5]",
- {gen_5_in , 0, 16, 0, 2, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0}
- },
- {
- "[dword 5]",
- {gen_5_in , 0, 16, 0, 4, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1}
- },
- {
- "a16 [dword 5]",
- {gen_5_in, 16, 16, 0, 4, 0, 0, 1, 0, 0, 0xff},
- 0,
- {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- },
- /* should error */
- {
- "[di+1.2]",
- {gen_1pt2_in, 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 0,
- {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- },
- {
- "[ecx]",
- {gen_ecx_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_ecx_out, 32, 16, 0, 0, 0x01, 1, 1, 0, 0, 0}
- },
- /* should error */
- {
- "a16 [ecx]",
- {gen_ecx_in, 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 0,
- {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- },
- {
- "[di]",
- {gen_di_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_di_out, 16, 16, 0, 0, 0x05, 1, 1, 0, 0, 0}
- },
- {
- "[di-si+si+126]",
- {gen_dimsipsip126_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_dimsipsip126_out, 16, 16, 0, 1, 0x45, 1, 1, 0, 0, 0}
- },
- {
- "[bx-(bx-di)+bx-2]",
- {gen_bxmqbxmdiqpbxm2_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_bxmqbxmdiqpbxm2_out, 16, 16, 0, 1, 0x41, 1, 1, 0, 0, 0}
- },
- {
- "[bp]",
- {gen_bp_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_bp_out, 16, 16, 0, 1, 0x46, 1, 1, 0, 0, 0}
- },
- {
- "[bp*1+500]",
- {gen_bpx1p500_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff},
- 1,
- {gen_bpx1p500_out, 16, 16, 0, 2, 0x86, 1, 1, 0, 0, 0}
- },
-};
-
-/* input expression */
-expr *expn;
-
-/* failure messages */
-static char result_msg[1024];
-
-int error_triggered;
-
-/* Replace errwarn functions */
-void InternalError_(const char *file, unsigned int line, const char *msg)
-{
- exit(EXIT_FAILURE);
-}
-
-void
-Fatal(fatal_num num)
-{
- exit(EXIT_FAILURE);
-}
-
-void
-Error(const char *msg, ...)
-{
- error_triggered = 1;
-}
-
-void
-Warning(const char *msg, ...)
-{
-}
-
-void
-ErrorAt(const char *filename, unsigned long line, const char *fmt, ...)
-{
- error_triggered = 1;
-}
-
-void
-WarningAt(const char *filename, unsigned long line, const char *fmt, ...)
-{
-}
-
-static int
-x86_checkea_check(CheckEA_Entry *val)
-{
- CheckEA_InOut chk = val->in; /* local structure copy of inputs */
- int retval;
-
- error_triggered = 0;
-
- /* execute function and check return value */
- retval = x86_expr_checkea(&expn, &chk.addrsize, chk.bits, chk.nosplit,
- &chk.displen, &chk.modrm, &chk.v_modrm,
- &chk.n_modrm, &chk.sib, &chk.v_sib, &chk.n_sib);
- if (retval != val->retval) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "return value", val->retval, retval);
- return 1;
- }
-
- /* If returned 0 (failure), check to see if ErrorAt() was called */
- if (retval == 0) {
- if (error_triggered == 0) {
- sprintf(result_msg, "%s: didn't call ErrorAt() and returned 0",
- val->ascii);
- return 1;
- }
-
- return 0; /* don't check other return values */
- }
-
- /* check expr result */
- /* TODO */
-
- /* Check other outputs */
- if (chk.addrsize != val->out.addrsize) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "addrsize", (int)val->out.addrsize,
- (int)chk.addrsize);
- return 1;
- }
- if (chk.displen != val->out.displen) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "displen", (int)val->out.displen,
- (int)chk.displen);
- return 1;
- }
- if (chk.modrm != val->out.modrm) {
- sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)",
- val->ascii, "modrm", (int)val->out.modrm, (int)chk.modrm);
- return 1;
- }
- if (chk.v_modrm != val->out.v_modrm) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "v_modrm", (int)val->out.v_modrm,
- (int)chk.v_modrm);
- return 1;
- }
- if (chk.n_modrm != val->out.n_modrm) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "n_modrm", (int)val->out.n_modrm,
- (int)chk.n_modrm);
- return 1;
- }
- if (chk.sib != val->out.sib) {
- sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)",
- val->ascii, "sib", (int)val->out.sib, (int)chk.sib);
- return 1;
- }
- if (chk.v_sib != val->out.v_sib) {
- sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)",
- val->ascii, "v_sib", (int)val->out.v_sib, (int)chk.v_sib);
- return 1;
- }
- if (chk.n_sib != val->out.n_sib) {
- sprintf(result_msg, "%s: incorrect %s (expected %x, got %x)",
- val->ascii, "n_sib", (int)val->out.n_sib, (int)chk.n_sib);
- return 1;
- }
- return 0;
-}
-
-START_TEST(test_x86_checkea_bits16)
-{
- CheckEA_Entry *vals = bits16_vals;
- int i, num = sizeof(bits16_vals)/sizeof(CheckEA_Entry);
-
- for (i=0; i<num; i++) {
- expn = vals[i].in.expr_gen();
- fail_unless(x86_checkea_check(&vals[i]) == 0, result_msg);
- expr_delete(expn);
- }
-}
-END_TEST
-
-static Suite *
-memexpr_suite(void)
-{
- Suite *s = suite_create("memexpr");
- TCase *tc_x86_checkea = tcase_create("x86_checkea");
-
- suite_add_tcase(s, tc_x86_checkea);
- tcase_add_test(tc_x86_checkea, test_x86_checkea_bits16);
-
- return s;
-}
-
-int
-main(void)
-{
- int nf;
- Suite *s = memexpr_suite();
- SRunner *sr = srunner_create(s);
- BitVector_Boot();
- srunner_run_all(sr, CRNORMAL);
- nf = srunner_ntests_failed(sr);
- srunner_free(sr);
- suite_free(s);
- return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
+++ /dev/null
-/* $IdPath$
- * Includes standard headers and defines prototypes for replacement functions
- * if needed. This is the *only* header file which should include other
- * header files!
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_UTIL_H
-#define YASM_UTIL_H
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-#if !defined(lint)
-# define NDEBUG
-#endif
-
-#ifdef STDC_HEADERS
-# include <stddef.h>
-# include <stdlib.h>
-# include <string.h>
-# include <assert.h>
-# include <stdarg.h>
-#endif
-
-#if defined(lint)
-#define _(String) String
-#else
-# ifdef HAVE_LOCALE_H
-# include <locale.h>
-# endif
-
-# ifdef ENABLE_NLS
-# include <libintl.h>
-# define _(String) gettext(String)
-# else
-# define gettext(Msgid) (Msgid)
-# define dgettext(Domainname, Msgid) (Msgid)
-# define dcgettext(Domainname, Msgid, Category) (Msgid)
-# define textdomain(Domainname) while (0) /* nothing */
-# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
-# define _(String) (String)
-# endif
-#endif
-
-#ifdef gettext_noop
-# define N_(String) gettext_noop(String)
-#else
-# define N_(String) (String)
-#endif
-
-#if !defined(HAVE_MERGESORT) || defined(lint)
-int mergesort(void *base, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *));
-#endif
-
-#if !defined(HAVE_STRSEP) || defined(lint)
-/*@null@*/ char *strsep(char **stringp, const char *delim);
-#endif
-
-#ifdef HAVE_STRCASECMP
-# define yasm__strcasecmp(x, y) strcasecmp(x, y)
-# define yasm__strncasecmp(x, y) strncasecmp(x, y)
-#else
-# ifdef HAVE_STRICMP
-# define yasm__strcasecmp(x, y) stricmp(x, y)
-# define yasm__strncasecmp(x, y) strnicmp(x, y)
-# elif HAVE_STRCMPI
-# define yasm__strcasecmp(x, y) strcmpi(x, y)
-# define yasm__strncasecmp(x, y) strncmpi(x, y)
-# else
-# define USE_OUR_OWN_STRCASECMP
-# endif
-#endif
-
-#if defined(USE_OUR_OWN_STRCASECMP) || defined(lint)
-int yasm__strcasecmp(const char *s1, const char *s2);
-int yasm__strncasecmp(const char *s1, const char *s2, size_t n);
-#endif
-
-#if !defined(HAVE_TOASCII) || defined(lint)
-# define toascii(c) ((c) & 0x7F)
-#endif
-
-#include "compat-queue.h"
-
-#ifdef HAVE_SYS_CDEFS_H
-# include <sys/cdefs.h>
-#endif
-
-#ifdef __RCSID
-# define RCSID(s) __RCSID(s)
-#else
-# ifdef __GNUC__
-# ifdef __ELF__
-# define RCSID(s) __asm__(".ident\t\"" s "\"")
-# else
-# define RCSID(s) static const char rcsid[] = s
-# endif
-# else
-# define RCSID(s) static const char rcsid[] = s
-# endif
-#endif
-
-#ifdef WITH_DMALLOC
-# include <dmalloc.h>
-
-#define yasm__xstrdup(str) xstrdup(str)
-#define yasm_xmalloc(size) xmalloc(size)
-#define yasm_xcalloc(count, size) xcalloc(count, size)
-#define yasm_xrealloc(ptr, size) xrealloc(ptr, size)
-#define yasm_xfree(ptr) xfree(ptr)
-
-#else
-/* strdup() implementation with error checking (using xmalloc). */
-/*@only@*/ char *yasm__xstrdup(const char *str);
-
-/* Error-checking memory allocation routines. Default implementations in
- * xmalloc.c.
- */
-extern /*@only@*/ /*@out@*/ void * (*yasm_xmalloc) (size_t size);
-extern /*@only@*/ void * (*yasm_xcalloc) (size_t nelem, size_t elsize);
-extern /*@only@*/ void * (*yasm_xrealloc)
- (/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ void *oldmem, size_t size)
- /*@modifies oldmem@*/;
-extern void (*yasm_xfree) (/*@only@*/ /*@out@*/ /*@null@*/ void *p)
- /*@modifies p@*/;
-
-#endif
-
-/*@only@*/ char *yasm__xstrndup(const char *str, size_t len);
-
-/* Bit-counting: used primarily by HAMT but also in a few other places. */
-#define SK5 0x55555555
-#define SK3 0x33333333
-#define SKF0 0x0F0F0F0F
-#define BitCount(d, s) do { \
- d = s; \
- d -= (d>>1) & SK5; \
- d = (d & SK3) + ((d>>2) & SK3); \
- d = (d & SKF0) + ((d>>4) & SKF0); \
- d += d>>16; \
- d += d>>8; \
- } while (0)
-
-/* Get the number of elements in an array. */
-#ifndef NELEMS
-#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
-#endif
-
-#include "coretype.h"
-
-#include "valparam.h"
-
-#endif
+++ /dev/null
-/*
- * Value/Parameter type functions
- *
- * Copyright (C) 2001 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.
- *
- * 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"
-/*@unused@*/ RCSID("$IdPath$");
-
-#include "expr.h"
-
-
-void
-yasm_vps_delete(yasm_valparamhead *headp)
-{
- yasm_valparam *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- if (cur->val)
- yasm_xfree(cur->val);
- if (cur->param)
- yasm_expr_delete(cur->param);
- yasm_xfree(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
-}
-
-void
-yasm_vps_print(FILE *f, const yasm_valparamhead *headp)
-{
- const yasm_valparam *vp;
-
- if(!headp) {
- fprintf(f, "(none)");
- return;
- }
-
- yasm_vps_foreach(vp, headp) {
- if (vp->val)
- fprintf(f, "(\"%s\",", vp->val);
- else
- fprintf(f, "((nil),");
- if (vp->param)
- yasm_expr_print(f, vp->param);
- else
- fprintf(f, "(nil)");
- fprintf(f, ")");
- if (yasm_vps_next(vp))
- fprintf(f, ",");
- }
-}
+++ /dev/null
-/* $IdPath$
- * Value/Parameter type definition
- *
- * Copyright (C) 2001 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.
- *
- * 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.
- */
-#ifndef YASM_VALPARAM_H
-#define YASM_VALPARAM_H
-
-typedef struct yasm_valparam {
- /*@reldef@*/ STAILQ_ENTRY(yasm_valparam) link;
- /*@owned@*/ /*@null@*/ char *val;
- /*@owned@*/ /*@null@*/ yasm_expr *param;
-} yasm_valparam;
-typedef /*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam)
- yasm_valparamhead;
-
-void yasm_vp_new(/*@out@*/ yasm_valparam *r, /*@keep@*/ const char *v,
- /*@keep@*/ yasm_expr *p);
-#define yasm_vp_new(r, v, p) do { \
- r = yasm_xmalloc(sizeof(yasm_valparam)); \
- r->val = v; \
- r->param = p; \
- } while(0)
-
-/* void yasm_vps_initialize(//@out@// yasm_valparamhead *headp); */
-#define yasm_vps_initialize(headp) STAILQ_INIT(headp)
-void yasm_vps_delete(yasm_valparamhead *headp);
-void yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
-#define yasm_vps_append(headp, vp) do { \
- if (vp) \
- STAILQ_INSERT_TAIL(headp, vp, link); \
- } while(0)
-
-/* //@null@// //@dependent@// yasm_valparam *yasm_vps_first
- (yasm_valparamhead *headp); */
-#define yasm_vps_first(headp) STAILQ_FIRST(headp)
-
-/* //@null@// //@dependent@// yasm_valparam *yasm_vps_next
- (yasm_valparam *cur); */
-#define yasm_vps_next(cur) STAILQ_NEXT(cur, link)
-
-#define yasm_vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
-
-void yasm_vps_print(FILE *f, /*@null@*/ const yasm_valparamhead *headp);
-
-#endif
+++ /dev/null
-/*
- * Memory allocation routines with error checking. Idea from GNU libiberty.
- *
- * Copyright (C) 2001 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.
- *
- * 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("$IdPath$");
-
-#include "errwarn.h"
-
-
-#ifndef WITH_DMALLOC
-
-static /*@only@*/ /*@out@*/ void *def_xmalloc(size_t size);
-static /*@only@*/ void *def_xcalloc(size_t nelem, size_t elsize);
-static /*@only@*/ void *def_xrealloc
- (/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ void *oldmem, size_t size)
- /*@modifies oldmem@*/;
-static void def_xfree(/*@only@*/ /*@out@*/ /*@null@*/ void *p)
- /*@modifies p@*/;
-
-/* storage for global function pointers */
-/*@only@*/ /*@out@*/ void * (*yasm_xmalloc) (size_t size) = def_xmalloc;
-/*@only@*/ void * (*yasm_xcalloc) (size_t nelem, size_t elsize) = def_xcalloc;
-/*@only@*/ void * (*yasm_xrealloc)
- (/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ void *oldmem, size_t size)
- /*@modifies oldmem@*/ = def_xrealloc;
-void (*yasm_xfree) (/*@only@*/ /*@out@*/ /*@null@*/ void *p)
- /*@modifies p@*/ = def_xfree;
-
-
-static void *
-def_xmalloc(size_t size)
-{
- void *newmem;
-
- if (size == 0)
- size = 1;
- newmem = malloc(size);
- if (!newmem)
- yasm_fatal(N_("out of memory"));
-
- return newmem;
-}
-
-static void *
-def_xcalloc(size_t nelem, size_t elsize)
-{
- void *newmem;
-
- if (nelem == 0 || elsize == 0)
- nelem = elsize = 1;
-
- newmem = calloc(nelem, elsize);
- if (!newmem)
- yasm_fatal(N_("out of memory"));
-
- return newmem;
-}
-
-static void *
-def_xrealloc(void *oldmem, size_t size)
-{
- void *newmem;
-
- if (size == 0)
- size = 1;
- if (!oldmem)
- newmem = malloc(size);
- else
- newmem = realloc(oldmem, size);
- if (!newmem)
- yasm_fatal(N_("out of memory"));
-
- return newmem;
-}
-
-static void
-def_xfree(void *p)
-{
- if (!p)
- return;
- free(p);
-}
-
-#endif
+++ /dev/null
-/*
- * strdup() implementation with error checking (using xmalloc).
- *
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * 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 University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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("$IdPath$");
-
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-
-#ifndef STDC_HEADERS
-size_t strlen(const char *);
-# ifndef HAVE_MEMCPY
-void bcopy(const void *, void *, size_t);
-# define memcpy(d, s, n) bcopy((s), (d), (n))
-# else
-void memcpy(void *, const void *, size_t);
-# endif
-#endif
-
-#ifndef WITH_DMALLOC
-
-char *
-yasm__xstrdup(const char *str)
-{
- size_t len;
- char *copy;
-
- len = strlen(str) + 1;
- copy = yasm_xmalloc(len);
- memcpy(copy, str, len);
- return (copy);
-}
-#endif
-
-char *
-yasm__xstrndup(const char *str, size_t len)
-{
- char *copy;
-
- copy = yasm_xmalloc(len+1);
- memcpy(copy, str, len);
- copy[len] = '\0';
- return (copy);
-}