From 8b564fbaa412dc40ddc95dff4dd1fb3d465db9b9 Mon Sep 17 00:00:00 2001 From: Peter Johnson <peter@tortall.net> Date: Thu, 13 Mar 2003 06:55:46 +0000 Subject: [PATCH] Split src into frontends, libyasm, and modules (forced commit after repo-copy). svn path=/trunk/yasm/; revision=847 --- Makefile.am | 10 +- configure.ac | 2 +- frontends/Makefile.inc | 6 + frontends/yasm/Makefile.inc | 79 +- frontends/yasm/yasm-module.c | 2 +- frontends/yasm/yasm-options.c | 2 +- frontends/yasm/yasm.c | 4 +- libyasm/Makefile.inc | 111 +- libyasm/tests/Makefile.inc | 4 +- modules/Makefile.inc | 76 +- modules/arch/Makefile.inc | 4 +- modules/arch/x86/Makefile.inc | 20 +- modules/arch/x86/tests/Makefile.inc | 110 +- modules/arch/x86/tests/x86_test.sh | 2 +- modules/arch/x86/x86id.re | 2 +- modules/dbgfmts/Makefile.inc | 4 +- modules/dbgfmts/null/Makefile.inc | 2 +- modules/objfmts/Makefile.inc | 12 +- modules/objfmts/bin/Makefile.inc | 6 +- modules/objfmts/bin/tests/Makefile.inc | 48 +- modules/objfmts/bin/tests/bin_test.sh | 2 +- modules/objfmts/coff/Makefile.inc | 6 +- modules/objfmts/coff/tests/Makefile.inc | 12 +- modules/objfmts/coff/tests/coff_test.sh | 2 +- modules/objfmts/dbg/Makefile.inc | 2 +- modules/optimizers/Makefile.inc | 4 +- modules/optimizers/basic/Makefile.inc | 2 +- modules/parsers/Makefile.inc | 4 +- modules/parsers/nasm/Makefile.inc | 18 +- modules/parsers/nasm/nasm-bison.y | 4 +- modules/parsers/nasm/nasm-token.re | 4 +- modules/parsers/nasm/tests/Makefile.inc | 16 +- modules/parsers/nasm/tests/nasm_test.sh | 2 +- modules/preprocs/Makefile.inc | 12 +- modules/preprocs/nasm/Makefile.inc | 26 +- modules/preprocs/raw/Makefile.inc | 2 +- modules/preprocs/yapp/Makefile.inc | 10 +- modules/preprocs/yapp/tests/Makefile.inc | 46 +- modules/preprocs/yapp/tests/include.asm | 4 +- modules/preprocs/yapp/tests/include.pre | 4 +- modules/preprocs/yapp/tests/rinclude.asm | 2 +- modules/preprocs/yapp/tests/yapp_test.sh | 2 +- modules/preprocs/yapp/yapp-preproc.c | 4 +- modules/preprocs/yapp/yapp-token.l | 4 +- po/POTFILES.in | 45 +- src/.indent.pro | 59 - src/Makefile.inc | 77 - src/arch.c | 176 - src/arch.h | 240 -- src/arch/Makefile.inc | 6 - src/arch/x86/Makefile.inc | 29 - src/arch/x86/README | 2 - src/arch/x86/tests/Makefile.inc | 60 - src/arch/x86/tests/addbyte.asm | 4 - src/arch/x86/tests/addbyte.errwarn | 0 src/arch/x86/tests/addbyte.hex | 13 - src/arch/x86/tests/addrop-err.asm | 2 - src/arch/x86/tests/addrop-err.errwarn | 1 - src/arch/x86/tests/addrop.asm | 25 - src/arch/x86/tests/addrop.errwarn | 0 src/arch/x86/tests/addrop.hex | 87 - src/arch/x86/tests/cpubasic-err.asm | 2 - src/arch/x86/tests/cpubasic-err.errwarn | 1 - src/arch/x86/tests/div-err.asm | 7 - src/arch/x86/tests/div-err.errwarn | 4 - src/arch/x86/tests/effaddr.asm | 7 - src/arch/x86/tests/effaddr.errwarn | 0 src/arch/x86/tests/effaddr.hex | 16 - src/arch/x86/tests/genopcode.asm | 175 - src/arch/x86/tests/genopcode.errwarn | 0 src/arch/x86/tests/genopcode.hex | 491 --- src/arch/x86/tests/lds-err.asm | 6 - src/arch/x86/tests/lds-err.errwarn | 4 - src/arch/x86/tests/loopadsz.asm | 7 - src/arch/x86/tests/loopadsz.errwarn | 0 src/arch/x86/tests/loopadsz.hex | 12 - src/arch/x86/tests/mem64-err.asm | 7 - src/arch/x86/tests/mem64-err.errwarn | 5 - src/arch/x86/tests/mem64.asm | 22 - src/arch/x86/tests/mem64.errwarn | 0 src/arch/x86/tests/mem64.hex | 111 - src/arch/x86/tests/negequ.asm | 8 - src/arch/x86/tests/negequ.errwarn | 0 src/arch/x86/tests/negequ.hex | 12 - src/arch/x86/tests/nomem64-err.asm | 19 - src/arch/x86/tests/nomem64-err.errwarn | 25 - src/arch/x86/tests/nomem64.asm | 13 - src/arch/x86/tests/nomem64.errwarn | 0 src/arch/x86/tests/nomem64.hex | 43 - src/arch/x86/tests/opersize.asm | 17 - src/arch/x86/tests/opersize.errwarn | 0 src/arch/x86/tests/opersize.hex | 30 - src/arch/x86/tests/opsize-err.asm | 3 - src/arch/x86/tests/opsize-err.errwarn | 1 - src/arch/x86/tests/ret.asm | 7 - src/arch/x86/tests/ret.errwarn | 0 src/arch/x86/tests/ret.hex | 19 - src/arch/x86/tests/segmov.asm | 9 - src/arch/x86/tests/segmov.errwarn | 0 src/arch/x86/tests/segmov.hex | 29 - src/arch/x86/tests/shift.asm | 6 - src/arch/x86/tests/shift.errwarn | 0 src/arch/x86/tests/shift.hex | 8 - src/arch/x86/tests/x86_test.sh | 4 - src/arch/x86/tests/x86label.asm | 2 - src/arch/x86/tests/x86label.errwarn | 0 src/arch/x86/tests/x86label.hex | 2 - src/arch/x86/x86arch.c | 237 -- src/arch/x86/x86arch.h | 205 - src/arch/x86/x86bc.c | 1044 ----- src/arch/x86/x86expr.c | 949 ----- src/arch/x86/x86id.re | 3577 ---------------- src/bc-int.h | 69 - src/bitvect.c | 3816 ----------------- src/bitvect.h | 394 -- src/bytecode.c | 985 ----- src/bytecode.h | 195 - src/compat-queue.h | 502 --- src/coretype.h | 137 - src/dbgfmt.h | 50 - src/dbgfmts/Makefile.inc | 6 - src/dbgfmts/null/Makefile.inc | 9 - src/dbgfmts/null/null-dbgfmt.c | 39 - src/errwarn.c | 362 -- src/errwarn.h | 94 - src/expr-int.h | 87 - src/expr.c | 1194 ------ src/expr.h | 116 - src/file.c | 79 - src/file.h | 174 - src/floatnum.c | 720 ---- src/floatnum.h | 68 - src/hamt.c | 351 -- src/hamt.h | 71 - src/intnum.c | 650 --- src/intnum.h | 80 - src/linemgr.c | 279 -- src/linemgr.h | 84 - src/main.c | 768 ---- src/module.c | 154 - src/module.h | 51 - src/objfmt.h | 126 - src/objfmts/Makefile.inc | 10 - src/objfmts/bin/Makefile.inc | 14 - src/objfmts/bin/bin-objfmt.c | 505 --- src/objfmts/bin/tests/Makefile.inc | 29 - src/objfmts/bin/tests/abs.asm | 5 - src/objfmts/bin/tests/abs.errwarn | 0 src/objfmts/bin/tests/abs.hex | 5 - src/objfmts/bin/tests/bin_test.sh | 4 - src/objfmts/bin/tests/bintest.asm | 56 - src/objfmts/bin/tests/bintest.errwarn | 0 src/objfmts/bin/tests/bintest.hex | 65 - src/objfmts/bin/tests/float-err.asm | 12 - src/objfmts/bin/tests/float-err.errwarn | 8 - src/objfmts/bin/tests/float.asm | 8 - src/objfmts/bin/tests/float.errwarn | 0 src/objfmts/bin/tests/float.hex | 44 - src/objfmts/bin/tests/integer-warn.asm | 6 - src/objfmts/bin/tests/integer-warn.errwarn | 2 - src/objfmts/bin/tests/integer-warn.hex | 25 - src/objfmts/bin/tests/integer.asm | 8 - src/objfmts/bin/tests/integer.errwarn | 0 src/objfmts/bin/tests/integer.hex | 25 - src/objfmts/bin/tests/reserve-err.asm | 15 - src/objfmts/bin/tests/reserve-err.errwarn | 6 - src/objfmts/bin/tests/reserve.asm | 14 - src/objfmts/bin/tests/reserve.errwarn | 4 - src/objfmts/bin/tests/reserve.hex | 233 - src/objfmts/coff/Makefile.inc | 14 - src/objfmts/coff/coff-objfmt.c | 930 ---- src/objfmts/coff/tests/Makefile.inc | 11 - src/objfmts/coff/tests/coff_test.sh | 4 - src/objfmts/coff/tests/cofftest.asm | 82 - src/objfmts/coff/tests/cofftest.c | 34 - src/objfmts/coff/tests/cofftest.errwarn | 0 src/objfmts/coff/tests/cofftest.hex | 660 --- src/objfmts/dbg/Makefile.inc | 9 - src/objfmts/dbg/dbg-objfmt.c | 258 -- src/objfmts/elf/elf32.h | 155 - src/objfmts/elf/elf_common.h | 248 -- src/optimizer.h | 48 - src/optimizers/Makefile.inc | 6 - src/optimizers/basic/Makefile.inc | 9 - src/optimizers/basic/basic-optimizer.c | 251 -- src/options.c | 180 - src/options.h | 72 - src/parser.h | 65 - src/parsers/Makefile.inc | 6 - src/parsers/nasm/Makefile.inc | 33 - src/parsers/nasm/nasm-bison.y | 663 --- src/parsers/nasm/nasm-defs.h | 85 - src/parsers/nasm/nasm-parser.c | 101 - src/parsers/nasm/nasm-parser.h | 57 - src/parsers/nasm/nasm-token.re | 564 --- src/parsers/nasm/tests/Makefile.inc | 13 - src/parsers/nasm/tests/equlocal.asm | 7 - src/parsers/nasm/tests/equlocal.errwarn | 0 src/parsers/nasm/tests/equlocal.hex | 3 - src/parsers/nasm/tests/nasm_test.sh | 4 - src/parsers/nasm/tests/newsect.asm | 10 - src/parsers/nasm/tests/newsect.errwarn | 0 src/parsers/nasm/tests/newsect.hex | 4 - src/preproc.h | 56 - src/preprocs/Makefile.inc | 10 - src/preprocs/nasm/Makefile.inc | 28 - src/preprocs/nasm/macros.pl | 48 - src/preprocs/nasm/nasm-eval.c | 823 ---- src/preprocs/nasm/nasm-eval.h | 28 - src/preprocs/nasm/nasm-pp.c | 4455 -------------------- src/preprocs/nasm/nasm-pp.h | 20 - src/preprocs/nasm/nasm-preproc.c | 188 - src/preprocs/nasm/nasm.h | 847 ---- src/preprocs/nasm/nasmlib.c | 370 -- src/preprocs/nasm/nasmlib.h | 84 - src/preprocs/nasm/standard.mac | 110 - src/preprocs/raw/Makefile.inc | 9 - src/preprocs/raw/raw-preproc.c | 84 - src/preprocs/yapp/Makefile.inc | 20 - src/preprocs/yapp/tests/Makefile.inc | 28 - src/preprocs/yapp/tests/comment.asm | 2 - src/preprocs/yapp/tests/comment.pre | 2 - src/preprocs/yapp/tests/ddefine.asm | 6 - src/preprocs/yapp/tests/ddefine.pre | 5 - src/preprocs/yapp/tests/define.asm | 4 - src/preprocs/yapp/tests/define.pre | 3 - src/preprocs/yapp/tests/ifdef.asm | 13 - src/preprocs/yapp/tests/ifdef.pre | 5 - src/preprocs/yapp/tests/include.asm | 5 - src/preprocs/yapp/tests/include.pre | 10 - src/preprocs/yapp/tests/params.asm | 2 - src/preprocs/yapp/tests/params.pre | 2 - src/preprocs/yapp/tests/pdefine.asm | 6 - src/preprocs/yapp/tests/pdefine.pre | 5 - src/preprocs/yapp/tests/raw.asm | 1 - src/preprocs/yapp/tests/raw.pre | 2 - src/preprocs/yapp/tests/rdefine.asm | 6 - src/preprocs/yapp/tests/rdefine.pre | 5 - src/preprocs/yapp/tests/rinclude.asm | 5 - src/preprocs/yapp/tests/rinclude.pre | 3 - src/preprocs/yapp/tests/yapp_test.sh | 60 - src/preprocs/yapp/yapp-preproc.c | 954 ----- src/preprocs/yapp/yapp-preproc.h | 58 - src/preprocs/yapp/yapp-token.h | 64 - src/preprocs/yapp/yapp-token.l | 356 -- src/section.c | 347 -- src/section.h | 83 - src/strcasecmp.c | 74 - src/symrec.c | 457 -- src/symrec.h | 80 - src/tests/Makefile.inc | 47 - src/tests/bitvect_test.c | 173 - src/tests/bytecode_test.c | 90 - src/tests/floatnum_test.c | 435 -- src/tests/memexpr_test.c | 422 -- src/util.h | 179 - src/valparam.c | 74 - src/valparam.h | 67 - src/xmalloc.c | 107 - src/xstrdup.c | 74 - 260 files changed, 304 insertions(+), 37268 deletions(-) create mode 100644 frontends/Makefile.inc delete mode 100644 src/.indent.pro delete mode 100644 src/Makefile.inc delete mode 100644 src/arch.c delete mode 100644 src/arch.h delete mode 100644 src/arch/Makefile.inc delete mode 100644 src/arch/x86/Makefile.inc delete mode 100644 src/arch/x86/README delete mode 100644 src/arch/x86/tests/Makefile.inc delete mode 100644 src/arch/x86/tests/addbyte.asm delete mode 100644 src/arch/x86/tests/addbyte.errwarn delete mode 100644 src/arch/x86/tests/addbyte.hex delete mode 100644 src/arch/x86/tests/addrop-err.asm delete mode 100644 src/arch/x86/tests/addrop-err.errwarn delete mode 100644 src/arch/x86/tests/addrop.asm delete mode 100644 src/arch/x86/tests/addrop.errwarn delete mode 100644 src/arch/x86/tests/addrop.hex delete mode 100644 src/arch/x86/tests/cpubasic-err.asm delete mode 100644 src/arch/x86/tests/cpubasic-err.errwarn delete mode 100644 src/arch/x86/tests/div-err.asm delete mode 100644 src/arch/x86/tests/div-err.errwarn delete mode 100644 src/arch/x86/tests/effaddr.asm delete mode 100644 src/arch/x86/tests/effaddr.errwarn delete mode 100644 src/arch/x86/tests/effaddr.hex delete mode 100644 src/arch/x86/tests/genopcode.asm delete mode 100644 src/arch/x86/tests/genopcode.errwarn delete mode 100644 src/arch/x86/tests/genopcode.hex delete mode 100644 src/arch/x86/tests/lds-err.asm delete mode 100644 src/arch/x86/tests/lds-err.errwarn delete mode 100644 src/arch/x86/tests/loopadsz.asm delete mode 100644 src/arch/x86/tests/loopadsz.errwarn delete mode 100644 src/arch/x86/tests/loopadsz.hex delete mode 100644 src/arch/x86/tests/mem64-err.asm delete mode 100644 src/arch/x86/tests/mem64-err.errwarn delete mode 100644 src/arch/x86/tests/mem64.asm delete mode 100644 src/arch/x86/tests/mem64.errwarn delete mode 100644 src/arch/x86/tests/mem64.hex delete mode 100644 src/arch/x86/tests/negequ.asm delete mode 100644 src/arch/x86/tests/negequ.errwarn delete mode 100644 src/arch/x86/tests/negequ.hex delete mode 100644 src/arch/x86/tests/nomem64-err.asm delete mode 100644 src/arch/x86/tests/nomem64-err.errwarn delete mode 100644 src/arch/x86/tests/nomem64.asm delete mode 100644 src/arch/x86/tests/nomem64.errwarn delete mode 100644 src/arch/x86/tests/nomem64.hex delete mode 100644 src/arch/x86/tests/opersize.asm delete mode 100644 src/arch/x86/tests/opersize.errwarn delete mode 100644 src/arch/x86/tests/opersize.hex delete mode 100644 src/arch/x86/tests/opsize-err.asm delete mode 100644 src/arch/x86/tests/opsize-err.errwarn delete mode 100644 src/arch/x86/tests/ret.asm delete mode 100644 src/arch/x86/tests/ret.errwarn delete mode 100644 src/arch/x86/tests/ret.hex delete mode 100644 src/arch/x86/tests/segmov.asm delete mode 100644 src/arch/x86/tests/segmov.errwarn delete mode 100644 src/arch/x86/tests/segmov.hex delete mode 100644 src/arch/x86/tests/shift.asm delete mode 100644 src/arch/x86/tests/shift.errwarn delete mode 100644 src/arch/x86/tests/shift.hex delete mode 100755 src/arch/x86/tests/x86_test.sh delete mode 100644 src/arch/x86/tests/x86label.asm delete mode 100644 src/arch/x86/tests/x86label.errwarn delete mode 100644 src/arch/x86/tests/x86label.hex delete mode 100644 src/arch/x86/x86arch.c delete mode 100644 src/arch/x86/x86arch.h delete mode 100644 src/arch/x86/x86bc.c delete mode 100644 src/arch/x86/x86expr.c delete mode 100644 src/arch/x86/x86id.re delete mode 100644 src/bc-int.h delete mode 100644 src/bitvect.c delete mode 100644 src/bitvect.h delete mode 100644 src/bytecode.c delete mode 100644 src/bytecode.h delete mode 100644 src/compat-queue.h delete mode 100644 src/coretype.h delete mode 100644 src/dbgfmt.h delete mode 100644 src/dbgfmts/Makefile.inc delete mode 100644 src/dbgfmts/null/Makefile.inc delete mode 100644 src/dbgfmts/null/null-dbgfmt.c delete mode 100644 src/errwarn.c delete mode 100644 src/errwarn.h delete mode 100644 src/expr-int.h delete mode 100644 src/expr.c delete mode 100644 src/expr.h delete mode 100644 src/file.c delete mode 100644 src/file.h delete mode 100644 src/floatnum.c delete mode 100644 src/floatnum.h delete mode 100644 src/hamt.c delete mode 100644 src/hamt.h delete mode 100644 src/intnum.c delete mode 100644 src/intnum.h delete mode 100644 src/linemgr.c delete mode 100644 src/linemgr.h delete mode 100644 src/main.c delete mode 100644 src/module.c delete mode 100644 src/module.h delete mode 100644 src/objfmt.h delete mode 100644 src/objfmts/Makefile.inc delete mode 100644 src/objfmts/bin/Makefile.inc delete mode 100644 src/objfmts/bin/bin-objfmt.c delete mode 100644 src/objfmts/bin/tests/Makefile.inc delete mode 100644 src/objfmts/bin/tests/abs.asm delete mode 100644 src/objfmts/bin/tests/abs.errwarn delete mode 100644 src/objfmts/bin/tests/abs.hex delete mode 100755 src/objfmts/bin/tests/bin_test.sh delete mode 100644 src/objfmts/bin/tests/bintest.asm delete mode 100644 src/objfmts/bin/tests/bintest.errwarn delete mode 100644 src/objfmts/bin/tests/bintest.hex delete mode 100644 src/objfmts/bin/tests/float-err.asm delete mode 100644 src/objfmts/bin/tests/float-err.errwarn delete mode 100644 src/objfmts/bin/tests/float.asm delete mode 100644 src/objfmts/bin/tests/float.errwarn delete mode 100644 src/objfmts/bin/tests/float.hex delete mode 100644 src/objfmts/bin/tests/integer-warn.asm delete mode 100644 src/objfmts/bin/tests/integer-warn.errwarn delete mode 100644 src/objfmts/bin/tests/integer-warn.hex delete mode 100644 src/objfmts/bin/tests/integer.asm delete mode 100644 src/objfmts/bin/tests/integer.errwarn delete mode 100644 src/objfmts/bin/tests/integer.hex delete mode 100644 src/objfmts/bin/tests/reserve-err.asm delete mode 100644 src/objfmts/bin/tests/reserve-err.errwarn delete mode 100644 src/objfmts/bin/tests/reserve.asm delete mode 100644 src/objfmts/bin/tests/reserve.errwarn delete mode 100644 src/objfmts/bin/tests/reserve.hex delete mode 100644 src/objfmts/coff/Makefile.inc delete mode 100644 src/objfmts/coff/coff-objfmt.c delete mode 100644 src/objfmts/coff/tests/Makefile.inc delete mode 100755 src/objfmts/coff/tests/coff_test.sh delete mode 100644 src/objfmts/coff/tests/cofftest.asm delete mode 100644 src/objfmts/coff/tests/cofftest.c delete mode 100644 src/objfmts/coff/tests/cofftest.errwarn delete mode 100644 src/objfmts/coff/tests/cofftest.hex delete mode 100644 src/objfmts/dbg/Makefile.inc delete mode 100644 src/objfmts/dbg/dbg-objfmt.c delete mode 100644 src/objfmts/elf/elf32.h delete mode 100644 src/objfmts/elf/elf_common.h delete mode 100644 src/optimizer.h delete mode 100644 src/optimizers/Makefile.inc delete mode 100644 src/optimizers/basic/Makefile.inc delete mode 100644 src/optimizers/basic/basic-optimizer.c delete mode 100644 src/options.c delete mode 100644 src/options.h delete mode 100644 src/parser.h delete mode 100644 src/parsers/Makefile.inc delete mode 100644 src/parsers/nasm/Makefile.inc delete mode 100644 src/parsers/nasm/nasm-bison.y delete mode 100644 src/parsers/nasm/nasm-defs.h delete mode 100644 src/parsers/nasm/nasm-parser.c delete mode 100644 src/parsers/nasm/nasm-parser.h delete mode 100644 src/parsers/nasm/nasm-token.re delete mode 100644 src/parsers/nasm/tests/Makefile.inc delete mode 100644 src/parsers/nasm/tests/equlocal.asm delete mode 100644 src/parsers/nasm/tests/equlocal.errwarn delete mode 100644 src/parsers/nasm/tests/equlocal.hex delete mode 100755 src/parsers/nasm/tests/nasm_test.sh delete mode 100644 src/parsers/nasm/tests/newsect.asm delete mode 100644 src/parsers/nasm/tests/newsect.errwarn delete mode 100644 src/parsers/nasm/tests/newsect.hex delete mode 100644 src/preproc.h delete mode 100644 src/preprocs/Makefile.inc delete mode 100644 src/preprocs/nasm/Makefile.inc delete mode 100644 src/preprocs/nasm/macros.pl delete mode 100644 src/preprocs/nasm/nasm-eval.c delete mode 100644 src/preprocs/nasm/nasm-eval.h delete mode 100644 src/preprocs/nasm/nasm-pp.c delete mode 100644 src/preprocs/nasm/nasm-pp.h delete mode 100644 src/preprocs/nasm/nasm-preproc.c delete mode 100644 src/preprocs/nasm/nasm.h delete mode 100644 src/preprocs/nasm/nasmlib.c delete mode 100644 src/preprocs/nasm/nasmlib.h delete mode 100644 src/preprocs/nasm/standard.mac delete mode 100644 src/preprocs/raw/Makefile.inc delete mode 100644 src/preprocs/raw/raw-preproc.c delete mode 100644 src/preprocs/yapp/Makefile.inc delete mode 100644 src/preprocs/yapp/tests/Makefile.inc delete mode 100644 src/preprocs/yapp/tests/comment.asm delete mode 100644 src/preprocs/yapp/tests/comment.pre delete mode 100644 src/preprocs/yapp/tests/ddefine.asm delete mode 100644 src/preprocs/yapp/tests/ddefine.pre delete mode 100644 src/preprocs/yapp/tests/define.asm delete mode 100644 src/preprocs/yapp/tests/define.pre delete mode 100644 src/preprocs/yapp/tests/ifdef.asm delete mode 100644 src/preprocs/yapp/tests/ifdef.pre delete mode 100644 src/preprocs/yapp/tests/include.asm delete mode 100644 src/preprocs/yapp/tests/include.pre delete mode 100644 src/preprocs/yapp/tests/params.asm delete mode 100644 src/preprocs/yapp/tests/params.pre delete mode 100644 src/preprocs/yapp/tests/pdefine.asm delete mode 100644 src/preprocs/yapp/tests/pdefine.pre delete mode 100644 src/preprocs/yapp/tests/raw.asm delete mode 100644 src/preprocs/yapp/tests/raw.pre delete mode 100644 src/preprocs/yapp/tests/rdefine.asm delete mode 100644 src/preprocs/yapp/tests/rdefine.pre delete mode 100644 src/preprocs/yapp/tests/rinclude.asm delete mode 100644 src/preprocs/yapp/tests/rinclude.pre delete mode 100755 src/preprocs/yapp/tests/yapp_test.sh delete mode 100644 src/preprocs/yapp/yapp-preproc.c delete mode 100644 src/preprocs/yapp/yapp-preproc.h delete mode 100644 src/preprocs/yapp/yapp-token.h delete mode 100644 src/preprocs/yapp/yapp-token.l delete mode 100644 src/section.c delete mode 100644 src/section.h delete mode 100644 src/strcasecmp.c delete mode 100644 src/symrec.c delete mode 100644 src/symrec.h delete mode 100644 src/tests/Makefile.inc delete mode 100644 src/tests/bitvect_test.c delete mode 100644 src/tests/bytecode_test.c delete mode 100644 src/tests/floatnum_test.c delete mode 100644 src/tests/memexpr_test.c delete mode 100644 src/util.h delete mode 100644 src/valparam.c delete mode 100644 src/valparam.h delete mode 100644 src/xmalloc.c delete mode 100644 src/xstrdup.c diff --git a/Makefile.am b/Makefile.am index 709f006e..136a1dab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = libltdl m4 po . AM_YFLAGS = -d AM_CFLAGS = @MORE_CFLAGS@ AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ + -I$(top_srcdir)/libyasm \ -I$(top_srcdir)/check \ @INCLTDL@ @@ -27,11 +27,15 @@ CLEANFILES = configure.lineno 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 \ diff --git a/configure.ac b/configure.ac index 615bd9a4..84890fc8 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ PERL_VERSION=5.004 # 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]) diff --git a/frontends/Makefile.inc b/frontends/Makefile.inc new file mode 100644 index 00000000..6bebbb88 --- /dev/null +++ b/frontends/Makefile.inc @@ -0,0 +1,6 @@ +# $IdPath$ + +EXTRA_DIST += \ + frontends/yasm/Makefile.inc + +include frontends/yasm/Makefile.inc diff --git a/frontends/yasm/Makefile.inc b/frontends/yasm/Makefile.inc index 6b7b6dd5..bc80cb77 100644 --- a/frontends/yasm/Makefile.inc +++ b/frontends/yasm/Makefile.inc @@ -1,77 +1,8 @@ # $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 diff --git a/frontends/yasm/yasm-module.c b/frontends/yasm/yasm-module.c index 33f920b1..de2c3c5f 100644 --- a/frontends/yasm/yasm-module.c +++ b/frontends/yasm/yasm-module.c @@ -29,7 +29,7 @@ #include "ltdl.h" -#include "module.h" +#include "yasm-module.h" #include "objfmt.h" #include "parser.h" diff --git a/frontends/yasm/yasm-options.c b/frontends/yasm/yasm-options.c index 50d49113..b8e18f33 100644 --- a/frontends/yasm/yasm-options.c +++ b/frontends/yasm/yasm-options.c @@ -30,7 +30,7 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); -#include "options.h" +#include "yasm-options.h" #include "errwarn.h" diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index f0ff6044..308bea0a 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -28,12 +28,12 @@ /*@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" diff --git a/libyasm/Makefile.inc b/libyasm/Makefile.inc index 6b7b6dd5..d8926280 100644 --- a/libyasm/Makefile.inc +++ b/libyasm/Makefile.inc @@ -1,77 +1,50 @@ # $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 diff --git a/libyasm/tests/Makefile.inc b/libyasm/tests/Makefile.inc index a4e6a792..ac4b6125 100644 --- a/libyasm/tests/Makefile.inc +++ b/libyasm/tests/Makefile.inc @@ -10,7 +10,7 @@ noinst_PROGRAMS += \ 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@ @@ -29,7 +29,7 @@ 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@ diff --git a/modules/Makefile.inc b/modules/Makefile.inc index 6b7b6dd5..46571884 100644 --- a/modules/Makefile.inc +++ b/modules/Makefile.inc @@ -1,61 +1,11 @@ # $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 @@ -65,13 +15,9 @@ 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 +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 diff --git a/modules/arch/Makefile.inc b/modules/arch/Makefile.inc index 4dbbbfcf..c0816a10 100644 --- a/modules/arch/Makefile.inc +++ b/modules/arch/Makefile.inc @@ -1,6 +1,6 @@ # $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 diff --git a/modules/arch/x86/Makefile.inc b/modules/arch/x86/Makefile.inc index 453750fc..187e1afd 100644 --- a/modules/arch/x86/Makefile.inc +++ b/modules/arch/x86/Makefile.inc @@ -3,17 +3,17 @@ 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 @@ -22,8 +22,8 @@ CLEANFILES += \ 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 diff --git a/modules/arch/x86/tests/Makefile.inc b/modules/arch/x86/tests/Makefile.inc index ecda81a9..54d0400a 100644 --- a/modules/arch/x86/tests/Makefile.inc +++ b/modules/arch/x86/tests/Makefile.inc @@ -1,60 +1,60 @@ # $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 diff --git a/modules/arch/x86/tests/x86_test.sh b/modules/arch/x86/tests/x86_test.sh index 861387a4..f2d69000 100755 --- a/modules/arch/x86/tests/x86_test.sh +++ b/modules/arch/x86/tests/x86_test.sh @@ -1,4 +1,4 @@ #! /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 $? diff --git a/modules/arch/x86/x86id.re b/modules/arch/x86/x86id.re index f25ec2bd..becb9ddc 100644 --- a/modules/arch/x86/x86id.re +++ b/modules/arch/x86/x86id.re @@ -38,7 +38,7 @@ RCSID("$IdPath$"); #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" diff --git a/modules/dbgfmts/Makefile.inc b/modules/dbgfmts/Makefile.inc index 74e9facf..5e660084 100644 --- a/modules/dbgfmts/Makefile.inc +++ b/modules/dbgfmts/Makefile.inc @@ -1,6 +1,6 @@ # $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 diff --git a/modules/dbgfmts/null/Makefile.inc b/modules/dbgfmts/null/Makefile.inc index 45a5bcfd..bb1b5922 100644 --- a/modules/dbgfmts/null/Makefile.inc +++ b/modules/dbgfmts/null/Makefile.inc @@ -3,7 +3,7 @@ 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 diff --git a/modules/objfmts/Makefile.inc b/modules/objfmts/Makefile.inc index fa33c47b..dc191c0f 100644 --- a/modules/objfmts/Makefile.inc +++ b/modules/objfmts/Makefile.inc @@ -1,10 +1,10 @@ # $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 diff --git a/modules/objfmts/bin/Makefile.inc b/modules/objfmts/bin/Makefile.inc index 1dcf3ef5..96a84298 100644 --- a/modules/objfmts/bin/Makefile.inc +++ b/modules/objfmts/bin/Makefile.inc @@ -3,12 +3,12 @@ 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 diff --git a/modules/objfmts/bin/tests/Makefile.inc b/modules/objfmts/bin/tests/Makefile.inc index af6d6fdc..c33bef8a 100644 --- a/modules/objfmts/bin/tests/Makefile.inc +++ b/modules/objfmts/bin/tests/Makefile.inc @@ -1,29 +1,29 @@ # $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 diff --git a/modules/objfmts/bin/tests/bin_test.sh b/modules/objfmts/bin/tests/bin_test.sh index d4e70a59..33f8df86 100755 --- a/modules/objfmts/bin/tests/bin_test.sh +++ b/modules/objfmts/bin/tests/bin_test.sh @@ -1,4 +1,4 @@ #! /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 $? diff --git a/modules/objfmts/coff/Makefile.inc b/modules/objfmts/coff/Makefile.inc index 01147933..fe3ec27c 100644 --- a/modules/objfmts/coff/Makefile.inc +++ b/modules/objfmts/coff/Makefile.inc @@ -3,12 +3,12 @@ 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 diff --git a/modules/objfmts/coff/tests/Makefile.inc b/modules/objfmts/coff/tests/Makefile.inc index 01a30682..c63c6cf1 100644 --- a/modules/objfmts/coff/tests/Makefile.inc +++ b/modules/objfmts/coff/tests/Makefile.inc @@ -1,11 +1,11 @@ # $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 diff --git a/modules/objfmts/coff/tests/coff_test.sh b/modules/objfmts/coff/tests/coff_test.sh index a4ff0bae..e1e6d4d4 100755 --- a/modules/objfmts/coff/tests/coff_test.sh +++ b/modules/objfmts/coff/tests/coff_test.sh @@ -1,4 +1,4 @@ #! /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 $? diff --git a/modules/objfmts/dbg/Makefile.inc b/modules/objfmts/dbg/Makefile.inc index aad12707..8ebf9605 100644 --- a/modules/objfmts/dbg/Makefile.inc +++ b/modules/objfmts/dbg/Makefile.inc @@ -3,7 +3,7 @@ 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 diff --git a/modules/optimizers/Makefile.inc b/modules/optimizers/Makefile.inc index 4701072b..6d4615ce 100644 --- a/modules/optimizers/Makefile.inc +++ b/modules/optimizers/Makefile.inc @@ -1,6 +1,6 @@ # $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 diff --git a/modules/optimizers/basic/Makefile.inc b/modules/optimizers/basic/Makefile.inc index 62dcb249..7f018057 100644 --- a/modules/optimizers/basic/Makefile.inc +++ b/modules/optimizers/basic/Makefile.inc @@ -3,7 +3,7 @@ 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 diff --git a/modules/parsers/Makefile.inc b/modules/parsers/Makefile.inc index e92cd255..3f55bcbf 100644 --- a/modules/parsers/Makefile.inc +++ b/modules/parsers/Makefile.inc @@ -1,6 +1,6 @@ # $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 diff --git a/modules/parsers/nasm/Makefile.inc b/modules/parsers/nasm/Makefile.inc index 43ac6c89..09cfb434 100644 --- a/modules/parsers/nasm/Makefile.inc +++ b/modules/parsers/nasm/Makefile.inc @@ -3,18 +3,18 @@ #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 \ @@ -27,7 +27,7 @@ CLEANFILES += \ 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 diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index bdca60ee..7446e546 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -48,8 +48,8 @@ RCSID("$IdPath$"); #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 *); diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index 8cbaf1f1..6cd9725d 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -42,8 +42,8 @@ RCSID("$IdPath$"); #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" diff --git a/modules/parsers/nasm/tests/Makefile.inc b/modules/parsers/nasm/tests/Makefile.inc index b35160b5..b161c203 100644 --- a/modules/parsers/nasm/tests/Makefile.inc +++ b/modules/parsers/nasm/tests/Makefile.inc @@ -1,13 +1,13 @@ # $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 diff --git a/modules/parsers/nasm/tests/nasm_test.sh b/modules/parsers/nasm/tests/nasm_test.sh index 90a6e89f..50b285bb 100755 --- a/modules/parsers/nasm/tests/nasm_test.sh +++ b/modules/parsers/nasm/tests/nasm_test.sh @@ -1,4 +1,4 @@ #! /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 $? diff --git a/modules/preprocs/Makefile.inc b/modules/preprocs/Makefile.inc index 0fae8c09..0431d42e 100644 --- a/modules/preprocs/Makefile.inc +++ b/modules/preprocs/Makefile.inc @@ -1,10 +1,10 @@ # $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 diff --git a/modules/preprocs/nasm/Makefile.inc b/modules/preprocs/nasm/Makefile.inc index 8881b877..d3c41670 100644 --- a/modules/preprocs/nasm/Makefile.inc +++ b/modules/preprocs/nasm/Makefile.inc @@ -3,25 +3,25 @@ #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 diff --git a/modules/preprocs/raw/Makefile.inc b/modules/preprocs/raw/Makefile.inc index 4124f396..454992f3 100644 --- a/modules/preprocs/raw/Makefile.inc +++ b/modules/preprocs/raw/Makefile.inc @@ -3,7 +3,7 @@ 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 diff --git a/modules/preprocs/yapp/Makefile.inc b/modules/preprocs/yapp/Makefile.inc index 7d1039c3..4351e373 100644 --- a/modules/preprocs/yapp/Makefile.inc +++ b/modules/preprocs/yapp/Makefile.inc @@ -3,10 +3,10 @@ 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 @@ -17,4 +17,4 @@ BUILT_SOURCES += \ CLEANFILES += \ yapp-token.c -include src/preprocs/yapp/tests/Makefile.inc +include modules/preprocs/yapp/tests/Makefile.inc diff --git a/modules/preprocs/yapp/tests/Makefile.inc b/modules/preprocs/yapp/tests/Makefile.inc index 187ea306..7f3e2c0b 100644 --- a/modules/preprocs/yapp/tests/Makefile.inc +++ b/modules/preprocs/yapp/tests/Makefile.inc @@ -1,28 +1,28 @@ # $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 diff --git a/modules/preprocs/yapp/tests/include.asm b/modules/preprocs/yapp/tests/include.asm index 7372f0f0..08b1b487 100644 --- a/modules/preprocs/yapp/tests/include.asm +++ b/modules/preprocs/yapp/tests/include.asm @@ -1,5 +1,5 @@ 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 diff --git a/modules/preprocs/yapp/tests/include.pre b/modules/preprocs/yapp/tests/include.pre index 418078c0..ea172aca 100644 --- a/modules/preprocs/yapp/tests/include.pre +++ b/modules/preprocs/yapp/tests/include.pre @@ -1,10 +1,10 @@ %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 diff --git a/modules/preprocs/yapp/tests/rinclude.asm b/modules/preprocs/yapp/tests/rinclude.asm index 988fd521..43f3efea 100644 --- a/modules/preprocs/yapp/tests/rinclude.asm +++ b/modules/preprocs/yapp/tests/rinclude.asm @@ -1,5 +1,5 @@ %ifndef recurse %define recurse -%include "./src/preprocs/yapp/tests/rinclude.asm" +%include "./modules/preprocs/yapp/tests/rinclude.asm" mov ax, 5 %endif diff --git a/modules/preprocs/yapp/tests/yapp_test.sh b/modules/preprocs/yapp/tests/yapp_test.sh index 6c1c6e63..28e42ea8 100755 --- a/modules/preprocs/yapp/tests/yapp_test.sh +++ b/modules/preprocs/yapp/tests/yapp_test.sh @@ -25,7 +25,7 @@ errorlist='' 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 diff --git a/modules/preprocs/yapp/yapp-preproc.c b/modules/preprocs/yapp/yapp-preproc.c index f425aa59..edd9bf30 100644 --- a/modules/preprocs/yapp/yapp-preproc.c +++ b/modules/preprocs/yapp/yapp-preproc.c @@ -27,8 +27,8 @@ #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 */ diff --git a/modules/preprocs/yapp/yapp-token.l b/modules/preprocs/yapp/yapp-token.l index 82fd52be..6055a9a2 100644 --- a/modules/preprocs/yapp/yapp-token.l +++ b/modules/preprocs/yapp/yapp-token.l @@ -28,8 +28,8 @@ #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 diff --git a/po/POTFILES.in b/po/POTFILES.in index 4ea3a84b..0978c3af 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,28 +4,31 @@ # # $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 diff --git a/src/.indent.pro b/src/.indent.pro deleted file mode 100644 index 88e4b3d9..00000000 --- a/src/.indent.pro +++ /dev/null @@ -1,59 +0,0 @@ -/* 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 diff --git a/src/Makefile.inc b/src/Makefile.inc deleted file mode 100644 index 6b7b6dd5..00000000 --- a/src/Makefile.inc +++ /dev/null @@ -1,77 +0,0 @@ -# $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 diff --git a/src/arch.c b/src/arch.c deleted file mode 100644 index 03b96b85..00000000 --- a/src/arch.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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); -} diff --git a/src/arch.h b/src/arch.h deleted file mode 100644 index ad99f188..00000000 --- a/src/arch.h +++ /dev/null @@ -1,240 +0,0 @@ -/* $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 diff --git a/src/arch/Makefile.inc b/src/arch/Makefile.inc deleted file mode 100644 index 4dbbbfcf..00000000 --- a/src/arch/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# $IdPath$ - -EXTRA_DIST += \ - src/arch/x86/Makefile.inc - -include src/arch/x86/Makefile.inc diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc deleted file mode 100644 index 453750fc..00000000 --- a/src/arch/x86/Makefile.inc +++ /dev/null @@ -1,29 +0,0 @@ -# $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 diff --git a/src/arch/x86/README b/src/arch/x86/README deleted file mode 100644 index ec2c7a27..00000000 --- a/src/arch/x86/README +++ /dev/null @@ -1,2 +0,0 @@ -Architecture to support Intel IA-32, AMD x86-64, and other extensions and -derivatives of the x86 instruction set. diff --git a/src/arch/x86/tests/Makefile.inc b/src/arch/x86/tests/Makefile.inc deleted file mode 100644 index ecda81a9..00000000 --- a/src/arch/x86/tests/Makefile.inc +++ /dev/null @@ -1,60 +0,0 @@ -# $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 diff --git a/src/arch/x86/tests/addbyte.asm b/src/arch/x86/tests/addbyte.asm deleted file mode 100644 index 285a3a9a..00000000 --- a/src/arch/x86/tests/addbyte.asm +++ /dev/null @@ -1,4 +0,0 @@ -add ax,5 -add ax,byte 5 -add bx,5 -add bx,byte 5 diff --git a/src/arch/x86/tests/addbyte.errwarn b/src/arch/x86/tests/addbyte.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/addbyte.hex b/src/arch/x86/tests/addbyte.hex deleted file mode 100644 index ccd24471..00000000 --- a/src/arch/x86/tests/addbyte.hex +++ /dev/null @@ -1,13 +0,0 @@ -05 -05 -00 -83 -c0 -05 -81 -c3 -05 -00 -83 -c3 -05 diff --git a/src/arch/x86/tests/addrop-err.asm b/src/arch/x86/tests/addrop-err.asm deleted file mode 100644 index 152f4666..00000000 --- a/src/arch/x86/tests/addrop-err.asm +++ /dev/null @@ -1,2 +0,0 @@ -[BITS 32] -a16 idiv byte [dword 0] ; 67 F6 3D 00 00 00 00 diff --git a/src/arch/x86/tests/addrop-err.errwarn b/src/arch/x86/tests/addrop-err.errwarn deleted file mode 100644 index 72040ee7..00000000 --- a/src/arch/x86/tests/addrop-err.errwarn +++ /dev/null @@ -1 +0,0 @@ --:2: invalid effective address (displacement size) diff --git a/src/arch/x86/tests/addrop.asm b/src/arch/x86/tests/addrop.asm deleted file mode 100644 index 81237ebb..00000000 --- a/src/arch/x86/tests/addrop.asm +++ /dev/null @@ -1,25 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/addrop.errwarn b/src/arch/x86/tests/addrop.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/addrop.hex b/src/arch/x86/tests/addrop.hex deleted file mode 100644 index fb47944f..00000000 --- a/src/arch/x86/tests/addrop.hex +++ /dev/null @@ -1,87 +0,0 @@ -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 diff --git a/src/arch/x86/tests/cpubasic-err.asm b/src/arch/x86/tests/cpubasic-err.asm deleted file mode 100644 index d381eeb6..00000000 --- a/src/arch/x86/tests/cpubasic-err.asm +++ /dev/null @@ -1,2 +0,0 @@ -[cpu 8086] -pause diff --git a/src/arch/x86/tests/cpubasic-err.errwarn b/src/arch/x86/tests/cpubasic-err.errwarn deleted file mode 100644 index c278d28d..00000000 --- a/src/arch/x86/tests/cpubasic-err.errwarn +++ /dev/null @@ -1 +0,0 @@ --:2: invalid combination of opcode and operands diff --git a/src/arch/x86/tests/div-err.asm b/src/arch/x86/tests/div-err.asm deleted file mode 100644 index 0afd8cc4..00000000 --- a/src/arch/x86/tests/div-err.asm +++ /dev/null @@ -1,7 +0,0 @@ -div byte si -div word si -div dword si -div byte esi -div word esi -div dword esi - diff --git a/src/arch/x86/tests/div-err.errwarn b/src/arch/x86/tests/div-err.errwarn deleted file mode 100644 index 4b6340e7..00000000 --- a/src/arch/x86/tests/div-err.errwarn +++ /dev/null @@ -1,4 +0,0 @@ --:1: cannot override register size --:3: cannot override register size --:4: cannot override register size --:5: cannot override register size diff --git a/src/arch/x86/tests/effaddr.asm b/src/arch/x86/tests/effaddr.asm deleted file mode 100644 index aff78669..00000000 --- a/src/arch/x86/tests/effaddr.asm +++ /dev/null @@ -1,7 +0,0 @@ -[bits 32] -mov ax,[eax+ebx+ecx-eax] -mov ax,[eax+ecx+ebx-eax] -label -dd 5 -label2 -mov ax,[eax+ebx*(label2-label)] diff --git a/src/arch/x86/tests/effaddr.errwarn b/src/arch/x86/tests/effaddr.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/effaddr.hex b/src/arch/x86/tests/effaddr.hex deleted file mode 100644 index de1b74fc..00000000 --- a/src/arch/x86/tests/effaddr.hex +++ /dev/null @@ -1,16 +0,0 @@ -66 -8b -04 -0b -66 -8b -04 -19 -05 -00 -00 -00 -66 -8b -04 -98 diff --git a/src/arch/x86/tests/genopcode.asm b/src/arch/x86/tests/genopcode.asm deleted file mode 100644 index f37695d3..00000000 --- a/src/arch/x86/tests/genopcode.asm +++ /dev/null @@ -1,175 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/genopcode.errwarn b/src/arch/x86/tests/genopcode.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/genopcode.hex b/src/arch/x86/tests/genopcode.hex deleted file mode 100644 index 4728ca4b..00000000 --- a/src/arch/x86/tests/genopcode.hex +++ /dev/null @@ -1,491 +0,0 @@ -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 diff --git a/src/arch/x86/tests/lds-err.asm b/src/arch/x86/tests/lds-err.asm deleted file mode 100644 index a9c70be4..00000000 --- a/src/arch/x86/tests/lds-err.asm +++ /dev/null @@ -1,6 +0,0 @@ -lds ax,[1] -lds ax,word [1] -lds ax,dword [1] -lds eax,[1] -lds eax,word [1] -lds eax,dword [1] diff --git a/src/arch/x86/tests/lds-err.errwarn b/src/arch/x86/tests/lds-err.errwarn deleted file mode 100644 index 601d1d06..00000000 --- a/src/arch/x86/tests/lds-err.errwarn +++ /dev/null @@ -1,4 +0,0 @@ --: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 diff --git a/src/arch/x86/tests/loopadsz.asm b/src/arch/x86/tests/loopadsz.asm deleted file mode 100644 index 8624a6c0..00000000 --- a/src/arch/x86/tests/loopadsz.asm +++ /dev/null @@ -1,7 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/loopadsz.errwarn b/src/arch/x86/tests/loopadsz.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/loopadsz.hex b/src/arch/x86/tests/loopadsz.hex deleted file mode 100644 index b47e4711..00000000 --- a/src/arch/x86/tests/loopadsz.hex +++ /dev/null @@ -1,12 +0,0 @@ -67 -e2 -fd -67 -e2 -fd -67 -e2 -fd -67 -e2 -fd diff --git a/src/arch/x86/tests/mem64-err.asm b/src/arch/x86/tests/mem64-err.asm deleted file mode 100644 index 40472167..00000000 --- a/src/arch/x86/tests/mem64-err.asm +++ /dev/null @@ -1,7 +0,0 @@ -[bits 64] -mov ax, [word 0] -;a16 mov ax, [0] -mov ax, [ax] -mov eax, [rip+rcx] -mov rbx, [rcx+ebx] -mov ah, [r8] diff --git a/src/arch/x86/tests/mem64-err.errwarn b/src/arch/x86/tests/mem64-err.errwarn deleted file mode 100644 index d8972bbc..00000000 --- a/src/arch/x86/tests/mem64-err.errwarn +++ /dev/null @@ -1,5 +0,0 @@ --: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 diff --git a/src/arch/x86/tests/mem64.asm b/src/arch/x86/tests/mem64.asm deleted file mode 100644 index fd773318..00000000 --- a/src/arch/x86/tests/mem64.asm +++ /dev/null @@ -1,22 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/mem64.errwarn b/src/arch/x86/tests/mem64.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/mem64.hex b/src/arch/x86/tests/mem64.hex deleted file mode 100644 index 691cffdf..00000000 --- a/src/arch/x86/tests/mem64.hex +++ /dev/null @@ -1,111 +0,0 @@ -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 diff --git a/src/arch/x86/tests/negequ.asm b/src/arch/x86/tests/negequ.asm deleted file mode 100644 index cfd27469..00000000 --- a/src/arch/x86/tests/negequ.asm +++ /dev/null @@ -1,8 +0,0 @@ -[bits 32] -off equ -4 -pos equ 4 - -mov [ebp+off], eax -mov [ebp+pos], eax -mov [ebp-off], eax -mov [ebp-pos], eax diff --git a/src/arch/x86/tests/negequ.errwarn b/src/arch/x86/tests/negequ.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/negequ.hex b/src/arch/x86/tests/negequ.hex deleted file mode 100644 index 8f015a28..00000000 --- a/src/arch/x86/tests/negequ.hex +++ /dev/null @@ -1,12 +0,0 @@ -89 -45 -fc -89 -45 -04 -89 -45 -04 -89 -45 -fc diff --git a/src/arch/x86/tests/nomem64-err.asm b/src/arch/x86/tests/nomem64-err.asm deleted file mode 100644 index 6b92797f..00000000 --- a/src/arch/x86/tests/nomem64-err.asm +++ /dev/null @@ -1,19 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/nomem64-err.errwarn b/src/arch/x86/tests/nomem64-err.errwarn deleted file mode 100644 index 8c47ff8d..00000000 --- a/src/arch/x86/tests/nomem64-err.errwarn +++ /dev/null @@ -1,25 +0,0 @@ --: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 diff --git a/src/arch/x86/tests/nomem64.asm b/src/arch/x86/tests/nomem64.asm deleted file mode 100644 index 46d02641..00000000 --- a/src/arch/x86/tests/nomem64.asm +++ /dev/null @@ -1,13 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/nomem64.errwarn b/src/arch/x86/tests/nomem64.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/nomem64.hex b/src/arch/x86/tests/nomem64.hex deleted file mode 100644 index 7174b25c..00000000 --- a/src/arch/x86/tests/nomem64.hex +++ /dev/null @@ -1,43 +0,0 @@ -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 diff --git a/src/arch/x86/tests/opersize.asm b/src/arch/x86/tests/opersize.asm deleted file mode 100644 index f520e357..00000000 --- a/src/arch/x86/tests/opersize.asm +++ /dev/null @@ -1,17 +0,0 @@ -[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 diff --git a/src/arch/x86/tests/opersize.errwarn b/src/arch/x86/tests/opersize.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/opersize.hex b/src/arch/x86/tests/opersize.hex deleted file mode 100644 index f226c756..00000000 --- a/src/arch/x86/tests/opersize.hex +++ /dev/null @@ -1,30 +0,0 @@ -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 diff --git a/src/arch/x86/tests/opsize-err.asm b/src/arch/x86/tests/opsize-err.asm deleted file mode 100644 index 161a7f6f..00000000 --- a/src/arch/x86/tests/opsize-err.asm +++ /dev/null @@ -1,3 +0,0 @@ -mov ax,1 -mov ax,word 1 -mov ax,byte 1 diff --git a/src/arch/x86/tests/opsize-err.errwarn b/src/arch/x86/tests/opsize-err.errwarn deleted file mode 100644 index c8ebb1e4..00000000 --- a/src/arch/x86/tests/opsize-err.errwarn +++ /dev/null @@ -1 +0,0 @@ --:3: invalid combination of opcode and operands diff --git a/src/arch/x86/tests/ret.asm b/src/arch/x86/tests/ret.asm deleted file mode 100644 index ed37bff8..00000000 --- a/src/arch/x86/tests/ret.asm +++ /dev/null @@ -1,7 +0,0 @@ -ret -ret 4 -ret word 2 -retn 6 -retn word 2 -retf 8 -retf word 2 diff --git a/src/arch/x86/tests/ret.errwarn b/src/arch/x86/tests/ret.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/ret.hex b/src/arch/x86/tests/ret.hex deleted file mode 100644 index 1b5e6643..00000000 --- a/src/arch/x86/tests/ret.hex +++ /dev/null @@ -1,19 +0,0 @@ -c3 -c2 -04 -00 -c2 -02 -00 -c2 -06 -00 -c2 -02 -00 -ca -08 -00 -ca -02 -00 diff --git a/src/arch/x86/tests/segmov.asm b/src/arch/x86/tests/segmov.asm deleted file mode 100644 index 4a6eb0a1..00000000 --- a/src/arch/x86/tests/segmov.asm +++ /dev/null @@ -1,9 +0,0 @@ -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] diff --git a/src/arch/x86/tests/segmov.errwarn b/src/arch/x86/tests/segmov.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/segmov.hex b/src/arch/x86/tests/segmov.hex deleted file mode 100644 index 8f5d9691..00000000 --- a/src/arch/x86/tests/segmov.hex +++ /dev/null @@ -1,29 +0,0 @@ -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 diff --git a/src/arch/x86/tests/shift.asm b/src/arch/x86/tests/shift.asm deleted file mode 100644 index eb689a37..00000000 --- a/src/arch/x86/tests/shift.asm +++ /dev/null @@ -1,6 +0,0 @@ -blah equ 1 - -shl al, 1 -shl al, 2-1 -shl al, blah -shl al, 2-blah diff --git a/src/arch/x86/tests/shift.errwarn b/src/arch/x86/tests/shift.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/shift.hex b/src/arch/x86/tests/shift.hex deleted file mode 100644 index ca17b1d7..00000000 --- a/src/arch/x86/tests/shift.hex +++ /dev/null @@ -1,8 +0,0 @@ -d0 -e0 -d0 -e0 -d0 -e0 -d0 -e0 diff --git a/src/arch/x86/tests/x86_test.sh b/src/arch/x86/tests/x86_test.sh deleted file mode 100755 index 861387a4..00000000 --- a/src/arch/x86/tests/x86_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -# $IdPath$ -${srcdir}/out_test.sh x86_test src/arch/x86/tests "x86 arch" "-f bin" "" -exit $? diff --git a/src/arch/x86/tests/x86label.asm b/src/arch/x86/tests/x86label.asm deleted file mode 100644 index 66e01d95..00000000 --- a/src/arch/x86/tests/x86label.asm +++ /dev/null @@ -1,2 +0,0 @@ -and_label: -jmp and_label diff --git a/src/arch/x86/tests/x86label.errwarn b/src/arch/x86/tests/x86label.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/arch/x86/tests/x86label.hex b/src/arch/x86/tests/x86label.hex deleted file mode 100644 index 2debae80..00000000 --- a/src/arch/x86/tests/x86label.hex +++ /dev/null @@ -1,2 +0,0 @@ -eb -fe diff --git a/src/arch/x86/x86arch.c b/src/arch/x86/x86arch.c deleted file mode 100644 index 8c600edb..00000000 --- a/src/arch/x86/x86arch.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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 -}; diff --git a/src/arch/x86/x86arch.h b/src/arch/x86/x86arch.h deleted file mode 100644 index 26cf2fb7..00000000 --- a/src/arch/x86/x86arch.h +++ /dev/null @@ -1,205 +0,0 @@ -/* $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 diff --git a/src/arch/x86/x86bc.c b/src/arch/x86/x86bc.c deleted file mode 100644 index 27fcc75c..00000000 --- a/src/arch/x86/x86bc.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * 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; -} diff --git a/src/arch/x86/x86expr.c b/src/arch/x86/x86expr.c deleted file mode 100644 index 06ff7bf0..00000000 --- a/src/arch/x86/x86expr.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * 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; -} diff --git a/src/arch/x86/x86id.re b/src/arch/x86/x86id.re deleted file mode 100644 index f25ec2bd..00000000 --- a/src/arch/x86/x86id.re +++ /dev/null @@ -1,3577 +0,0 @@ -/* - * 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; - } - */ -} diff --git a/src/bc-int.h b/src/bc-int.h deleted file mode 100644 index c6fbfb8a..00000000 --- a/src/bc-int.h +++ /dev/null @@ -1,69 +0,0 @@ -/* $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 diff --git a/src/bitvect.c b/src/bitvect.c deleted file mode 100644 index bd2a85e7..00000000 --- a/src/bitvect.c +++ /dev/null @@ -1,3816 +0,0 @@ -#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 */ -/* */ -/*****************************************************************************/ diff --git a/src/bitvect.h b/src/bitvect.h deleted file mode 100644 index 56cbcd8d..00000000 --- a/src/bitvect.h +++ /dev/null @@ -1,394 +0,0 @@ -/* $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 diff --git a/src/bytecode.c b/src/bytecode.c deleted file mode 100644 index aa1815a3..00000000 --- a/src/bytecode.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * 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; - } - } -} diff --git a/src/bytecode.h b/src/bytecode.h deleted file mode 100644 index 0e64920e..00000000 --- a/src/bytecode.h +++ /dev/null @@ -1,195 +0,0 @@ -/* $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 diff --git a/src/compat-queue.h b/src/compat-queue.h deleted file mode 100644 index 9ac37b08..00000000 --- a/src/compat-queue.h +++ /dev/null @@ -1,502 +0,0 @@ -/* $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 */ diff --git a/src/coretype.h b/src/coretype.h deleted file mode 100644 index 86ea58b4..00000000 --- a/src/coretype.h +++ /dev/null @@ -1,137 +0,0 @@ -/* $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 diff --git a/src/dbgfmt.h b/src/dbgfmt.h deleted file mode 100644 index d3467689..00000000 --- a/src/dbgfmt.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $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 diff --git a/src/dbgfmts/Makefile.inc b/src/dbgfmts/Makefile.inc deleted file mode 100644 index 74e9facf..00000000 --- a/src/dbgfmts/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# $IdPath$ - -EXTRA_DIST += \ - src/dbgfmts/null/Makefile.inc - -include src/dbgfmts/null/Makefile.inc diff --git a/src/dbgfmts/null/Makefile.inc b/src/dbgfmts/null/Makefile.inc deleted file mode 100644 index 45a5bcfd..00000000 --- a/src/dbgfmts/null/Makefile.inc +++ /dev/null @@ -1,9 +0,0 @@ -# $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 diff --git a/src/dbgfmts/null/null-dbgfmt.c b/src/dbgfmts/null/null-dbgfmt.c deleted file mode 100644 index 74aa6e20..00000000 --- a/src/dbgfmts/null/null-dbgfmt.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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*/ -}; diff --git a/src/errwarn.c b/src/errwarn.c deleted file mode 100644 index 9909a403..00000000 --- a/src/errwarn.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * 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); - } -} diff --git a/src/errwarn.h b/src/errwarn.h deleted file mode 100644 index 4e312522..00000000 --- a/src/errwarn.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $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 diff --git a/src/expr-int.h b/src/expr-int.h deleted file mode 100644 index 81671d85..00000000 --- a/src/expr-int.h +++ /dev/null @@ -1,87 +0,0 @@ -/* $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 diff --git a/src/expr.c b/src/expr.c deleted file mode 100644 index 7fd8c948..00000000 --- a/src/expr.c +++ /dev/null @@ -1,1194 +0,0 @@ -/* - * 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); - } -} diff --git a/src/expr.h b/src/expr.h deleted file mode 100644 index b65cb043..00000000 --- a/src/expr.h +++ /dev/null @@ -1,116 +0,0 @@ -/* $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 diff --git a/src/file.c b/src/file.c deleted file mode 100644 index 46906b22..00000000 --- a/src/file.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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; -} diff --git a/src/file.h b/src/file.h deleted file mode 100644 index f02a1351..00000000 --- a/src/file.h +++ /dev/null @@ -1,174 +0,0 @@ -/* $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 diff --git a/src/floatnum.c b/src/floatnum.c deleted file mode 100644 index bb744e72..00000000 --- a/src/floatnum.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - * 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"); -} diff --git a/src/floatnum.h b/src/floatnum.h deleted file mode 100644 index a181f2a9..00000000 --- a/src/floatnum.h +++ /dev/null @@ -1,68 +0,0 @@ -/* $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 diff --git a/src/hamt.c b/src/hamt.c deleted file mode 100644 index 69e142a9..00000000 --- a/src/hamt.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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]; - } -} - diff --git a/src/hamt.h b/src/hamt.h deleted file mode 100644 index c42cf80f..00000000 --- a/src/hamt.h +++ /dev/null @@ -1,71 +0,0 @@ -/* $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 diff --git a/src/intnum.c b/src/intnum.c deleted file mode 100644 index ea97fcb3..00000000 --- a/src/intnum.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * 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; - } -} diff --git a/src/intnum.h b/src/intnum.h deleted file mode 100644 index eff2dfdf..00000000 --- a/src/intnum.h +++ /dev/null @@ -1,80 +0,0 @@ -/* $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 diff --git a/src/linemgr.c b/src/linemgr.c deleted file mode 100644 index 02507849..00000000 --- a/src/linemgr.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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 -}; diff --git a/src/linemgr.h b/src/linemgr.h deleted file mode 100644 index d08ed70d..00000000 --- a/src/linemgr.h +++ /dev/null @@ -1,84 +0,0 @@ -/* $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 diff --git a/src/main.c b/src/main.c deleted file mode 100644 index f0ff6044..00000000 --- a/src/main.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * 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); -} diff --git a/src/module.c b/src/module.c deleted file mode 100644 index 33f920b1..00000000 --- a/src/module.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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); - } -} diff --git a/src/module.h b/src/module.h deleted file mode 100644 index 35885013..00000000 --- a/src/module.h +++ /dev/null @@ -1,51 +0,0 @@ -/* $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 diff --git a/src/objfmt.h b/src/objfmt.h deleted file mode 100644 index 45522c56..00000000 --- a/src/objfmt.h +++ /dev/null @@ -1,126 +0,0 @@ -/* $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 diff --git a/src/objfmts/Makefile.inc b/src/objfmts/Makefile.inc deleted file mode 100644 index fa33c47b..00000000 --- a/src/objfmts/Makefile.inc +++ /dev/null @@ -1,10 +0,0 @@ -# $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 diff --git a/src/objfmts/bin/Makefile.inc b/src/objfmts/bin/Makefile.inc deleted file mode 100644 index 1dcf3ef5..00000000 --- a/src/objfmts/bin/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ -# $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 diff --git a/src/objfmts/bin/bin-objfmt.c b/src/objfmts/bin/bin-objfmt.c deleted file mode 100644 index 1549131b..00000000 --- a/src/objfmts/bin/bin-objfmt.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * 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*/ -}; diff --git a/src/objfmts/bin/tests/Makefile.inc b/src/objfmts/bin/tests/Makefile.inc deleted file mode 100644 index af6d6fdc..00000000 --- a/src/objfmts/bin/tests/Makefile.inc +++ /dev/null @@ -1,29 +0,0 @@ -# $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 diff --git a/src/objfmts/bin/tests/abs.asm b/src/objfmts/bin/tests/abs.asm deleted file mode 100644 index e34b14a7..00000000 --- a/src/objfmts/bin/tests/abs.asm +++ /dev/null @@ -1,5 +0,0 @@ -[absolute 0f0000000h] -foo: resb 1 -[section .data] -bar dd foo -baz db (foo>>24) diff --git a/src/objfmts/bin/tests/abs.errwarn b/src/objfmts/bin/tests/abs.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/objfmts/bin/tests/abs.hex b/src/objfmts/bin/tests/abs.hex deleted file mode 100644 index a5612f05..00000000 --- a/src/objfmts/bin/tests/abs.hex +++ /dev/null @@ -1,5 +0,0 @@ -00 -00 -00 -f0 -f0 diff --git a/src/objfmts/bin/tests/bin_test.sh b/src/objfmts/bin/tests/bin_test.sh deleted file mode 100755 index d4e70a59..00000000 --- a/src/objfmts/bin/tests/bin_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -# $IdPath$ -${srcdir}/out_test.sh bin_test src/objfmts/bin/tests "bin objfmt" "-f bin" "" -exit $? diff --git a/src/objfmts/bin/tests/bintest.asm b/src/objfmts/bin/tests/bintest.asm deleted file mode 100644 index c434ce94..00000000 --- a/src/objfmts/bin/tests/bintest.asm +++ /dev/null @@ -1,56 +0,0 @@ -; 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] diff --git a/src/objfmts/bin/tests/bintest.errwarn b/src/objfmts/bin/tests/bintest.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/objfmts/bin/tests/bintest.hex b/src/objfmts/bin/tests/bintest.hex deleted file mode 100644 index 3a53e371..00000000 --- a/src/objfmts/bin/tests/bintest.hex +++ /dev/null @@ -1,65 +0,0 @@ -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 diff --git a/src/objfmts/bin/tests/float-err.asm b/src/objfmts/bin/tests/float-err.asm deleted file mode 100644 index 56a766c2..00000000 --- a/src/objfmts/bin/tests/float-err.asm +++ /dev/null @@ -1,12 +0,0 @@ -; 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 diff --git a/src/objfmts/bin/tests/float-err.errwarn b/src/objfmts/bin/tests/float-err.errwarn deleted file mode 100644 index f890432d..00000000 --- a/src/objfmts/bin/tests/float-err.errwarn +++ /dev/null @@ -1,8 +0,0 @@ --: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 diff --git a/src/objfmts/bin/tests/float.asm b/src/objfmts/bin/tests/float.asm deleted file mode 100644 index a2823f35..00000000 --- a/src/objfmts/bin/tests/float.asm +++ /dev/null @@ -1,8 +0,0 @@ -; Tests float handling -dd 5.12 -dq 3.141592653589793 -dt 5653894745.318293470142875104710284019245e335 - -dd -47102940.467103581 -dq -45102571092751092341095.5827509174509178450917845019 -dt -1.e-1000 diff --git a/src/objfmts/bin/tests/float.errwarn b/src/objfmts/bin/tests/float.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/objfmts/bin/tests/float.hex b/src/objfmts/bin/tests/float.hex deleted file mode 100644 index 066fa76e..00000000 --- a/src/objfmts/bin/tests/float.hex +++ /dev/null @@ -1,44 +0,0 @@ -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 diff --git a/src/objfmts/bin/tests/integer-warn.asm b/src/objfmts/bin/tests/integer-warn.asm deleted file mode 100644 index 31c0f410..00000000 --- a/src/objfmts/bin/tests/integer-warn.asm +++ /dev/null @@ -1,6 +0,0 @@ -; Tests warnings with integer constant handling (for output, not parsing) -db 0x51a -dw 0x3875bc -dd 0x35783134affff -dq 0xABCDEF012345678989abb -dt 0xa907bc890d0e907f0134afb8adee diff --git a/src/objfmts/bin/tests/integer-warn.errwarn b/src/objfmts/bin/tests/integer-warn.errwarn deleted file mode 100644 index 09d82f10..00000000 --- a/src/objfmts/bin/tests/integer-warn.errwarn +++ /dev/null @@ -1,2 +0,0 @@ --:5: warning: Numeric constant too large for internal format --:6: warning: Numeric constant too large for internal format diff --git a/src/objfmts/bin/tests/integer-warn.hex b/src/objfmts/bin/tests/integer-warn.hex deleted file mode 100644 index 82c4bfa4..00000000 --- a/src/objfmts/bin/tests/integer-warn.hex +++ /dev/null @@ -1,25 +0,0 @@ -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 diff --git a/src/objfmts/bin/tests/integer.asm b/src/objfmts/bin/tests/integer.asm deleted file mode 100644 index 469887c4..00000000 --- a/src/objfmts/bin/tests/integer.asm +++ /dev/null @@ -1,8 +0,0 @@ -; Tests integer constant handling (for output, not parsing) - -db 0x51 -dw 0x3875 -dd 0x35783134 -dq 0xABCDEF0123456789 -dt 0xa907bc890d0e907f0134 - diff --git a/src/objfmts/bin/tests/integer.errwarn b/src/objfmts/bin/tests/integer.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/objfmts/bin/tests/integer.hex b/src/objfmts/bin/tests/integer.hex deleted file mode 100644 index baad38fd..00000000 --- a/src/objfmts/bin/tests/integer.hex +++ /dev/null @@ -1,25 +0,0 @@ -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 diff --git a/src/objfmts/bin/tests/reserve-err.asm b/src/objfmts/bin/tests/reserve-err.asm deleted file mode 100644 index ad6e31ae..00000000 --- a/src/objfmts/bin/tests/reserve-err.asm +++ /dev/null @@ -1,15 +0,0 @@ -; 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 - diff --git a/src/objfmts/bin/tests/reserve-err.errwarn b/src/objfmts/bin/tests/reserve-err.errwarn deleted file mode 100644 index 25fb790a..00000000 --- a/src/objfmts/bin/tests/reserve-err.errwarn +++ /dev/null @@ -1,6 +0,0 @@ --: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 diff --git a/src/objfmts/bin/tests/reserve.asm b/src/objfmts/bin/tests/reserve.asm deleted file mode 100644 index cd87e216..00000000 --- a/src/objfmts/bin/tests/reserve.asm +++ /dev/null @@ -1,14 +0,0 @@ -; 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 - diff --git a/src/objfmts/bin/tests/reserve.errwarn b/src/objfmts/bin/tests/reserve.errwarn deleted file mode 100644 index fb0d7223..00000000 --- a/src/objfmts/bin/tests/reserve.errwarn +++ /dev/null @@ -1,4 +0,0 @@ --: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 diff --git a/src/objfmts/bin/tests/reserve.hex b/src/objfmts/bin/tests/reserve.hex deleted file mode 100644 index 49dfa566..00000000 --- a/src/objfmts/bin/tests/reserve.hex +++ /dev/null @@ -1,233 +0,0 @@ -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 diff --git a/src/objfmts/coff/Makefile.inc b/src/objfmts/coff/Makefile.inc deleted file mode 100644 index 01147933..00000000 --- a/src/objfmts/coff/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ -# $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 diff --git a/src/objfmts/coff/coff-objfmt.c b/src/objfmts/coff/coff-objfmt.c deleted file mode 100644 index 4ccf66a6..00000000 --- a/src/objfmts/coff/coff-objfmt.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * 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*/ -}; diff --git a/src/objfmts/coff/tests/Makefile.inc b/src/objfmts/coff/tests/Makefile.inc deleted file mode 100644 index 01a30682..00000000 --- a/src/objfmts/coff/tests/Makefile.inc +++ /dev/null @@ -1,11 +0,0 @@ -# $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 diff --git a/src/objfmts/coff/tests/coff_test.sh b/src/objfmts/coff/tests/coff_test.sh deleted file mode 100755 index a4ff0bae..00000000 --- a/src/objfmts/coff/tests/coff_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -# $IdPath$ -${srcdir}/out_test.sh coff_test src/objfmts/coff/tests "coff objfmt" "-f coff" ".o" -exit $? diff --git a/src/objfmts/coff/tests/cofftest.asm b/src/objfmts/coff/tests/cofftest.asm deleted file mode 100644 index 17b93f9e..00000000 --- a/src/objfmts/coff/tests/cofftest.asm +++ /dev/null @@ -1,82 +0,0 @@ -; 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] diff --git a/src/objfmts/coff/tests/cofftest.c b/src/objfmts/coff/tests/cofftest.c deleted file mode 100644 index f7446b8a..00000000 --- a/src/objfmts/coff/tests/cofftest.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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); -} diff --git a/src/objfmts/coff/tests/cofftest.errwarn b/src/objfmts/coff/tests/cofftest.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/objfmts/coff/tests/cofftest.hex b/src/objfmts/coff/tests/cofftest.hex deleted file mode 100644 index c7223f0f..00000000 --- a/src/objfmts/coff/tests/cofftest.hex +++ /dev/null @@ -1,660 +0,0 @@ -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 diff --git a/src/objfmts/dbg/Makefile.inc b/src/objfmts/dbg/Makefile.inc deleted file mode 100644 index aad12707..00000000 --- a/src/objfmts/dbg/Makefile.inc +++ /dev/null @@ -1,9 +0,0 @@ -# $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 diff --git a/src/objfmts/dbg/dbg-objfmt.c b/src/objfmts/dbg/dbg-objfmt.c deleted file mode 100644 index f1134123..00000000 --- a/src/objfmts/dbg/dbg-objfmt.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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 -}; diff --git a/src/objfmts/elf/elf32.h b/src/objfmts/elf/elf32.h deleted file mode 100644 index 2e80f84d..00000000 --- a/src/objfmts/elf/elf32.h +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * 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 */ diff --git a/src/objfmts/elf/elf_common.h b/src/objfmts/elf/elf_common.h deleted file mode 100644 index 7460ea2f..00000000 --- a/src/objfmts/elf/elf_common.h +++ /dev/null @@ -1,248 +0,0 @@ -/*- - * 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 */ diff --git a/src/optimizer.h b/src/optimizer.h deleted file mode 100644 index a0cfb448..00000000 --- a/src/optimizer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $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 diff --git a/src/optimizers/Makefile.inc b/src/optimizers/Makefile.inc deleted file mode 100644 index 4701072b..00000000 --- a/src/optimizers/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# $IdPath$ - -EXTRA_DIST += \ - src/optimizers/basic/Makefile.inc - -include src/optimizers/basic/Makefile.inc diff --git a/src/optimizers/basic/Makefile.inc b/src/optimizers/basic/Makefile.inc deleted file mode 100644 index 62dcb249..00000000 --- a/src/optimizers/basic/Makefile.inc +++ /dev/null @@ -1,9 +0,0 @@ -# $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 diff --git a/src/optimizers/basic/basic-optimizer.c b/src/optimizers/basic/basic-optimizer.c deleted file mode 100644 index b7013f35..00000000 --- a/src/optimizers/basic/basic-optimizer.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 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 -}; diff --git a/src/options.c b/src/options.c deleted file mode 100644 index 50d49113..00000000 --- a/src/options.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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)); -} diff --git a/src/options.h b/src/options.h deleted file mode 100644 index 8be0e287..00000000 --- a/src/options.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $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 diff --git a/src/parser.h b/src/parser.h deleted file mode 100644 index 2b18d63a..00000000 --- a/src/parser.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $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 diff --git a/src/parsers/Makefile.inc b/src/parsers/Makefile.inc deleted file mode 100644 index e92cd255..00000000 --- a/src/parsers/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -# $IdPath$ - -EXTRA_DIST += \ - src/parsers/nasm/Makefile.inc - -include src/parsers/nasm/Makefile.inc diff --git a/src/parsers/nasm/Makefile.inc b/src/parsers/nasm/Makefile.inc deleted file mode 100644 index 43ac6c89..00000000 --- a/src/parsers/nasm/Makefile.inc +++ /dev/null @@ -1,33 +0,0 @@ -# $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 diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y deleted file mode 100644 index bdca60ee..00000000 --- a/src/parsers/nasm/nasm-bison.y +++ /dev/null @@ -1,663 +0,0 @@ -/* - * 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); -} - diff --git a/src/parsers/nasm/nasm-defs.h b/src/parsers/nasm/nasm-defs.h deleted file mode 100644 index c67dae7f..00000000 --- a/src/parsers/nasm/nasm-defs.h +++ /dev/null @@ -1,85 +0,0 @@ -/* $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*/ diff --git a/src/parsers/nasm/nasm-parser.c b/src/parsers/nasm/nasm-parser.c deleted file mode 100644 index 865e56a9..00000000 --- a/src/parsers/nasm/nasm-parser.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 -}; diff --git a/src/parsers/nasm/nasm-parser.h b/src/parsers/nasm/nasm-parser.h deleted file mode 100644 index 68ddcdbc..00000000 --- a/src/parsers/nasm/nasm-parser.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $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 diff --git a/src/parsers/nasm/nasm-token.re b/src/parsers/nasm/nasm-token.re deleted file mode 100644 index 8cbaf1f1..00000000 --- a/src/parsers/nasm/nasm-token.re +++ /dev/null @@ -1,564 +0,0 @@ -/* - * 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; - } - */ -} diff --git a/src/parsers/nasm/tests/Makefile.inc b/src/parsers/nasm/tests/Makefile.inc deleted file mode 100644 index b35160b5..00000000 --- a/src/parsers/nasm/tests/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# $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 diff --git a/src/parsers/nasm/tests/equlocal.asm b/src/parsers/nasm/tests/equlocal.asm deleted file mode 100644 index ca540620..00000000 --- a/src/parsers/nasm/tests/equlocal.asm +++ /dev/null @@ -1,7 +0,0 @@ -blah -.local equ 5 -blah2 -db blah.local -.local -nonlocal equ 6 -je .local diff --git a/src/parsers/nasm/tests/equlocal.errwarn b/src/parsers/nasm/tests/equlocal.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/parsers/nasm/tests/equlocal.hex b/src/parsers/nasm/tests/equlocal.hex deleted file mode 100644 index 0ee1d6e9..00000000 --- a/src/parsers/nasm/tests/equlocal.hex +++ /dev/null @@ -1,3 +0,0 @@ -05 -74 -fe diff --git a/src/parsers/nasm/tests/nasm_test.sh b/src/parsers/nasm/tests/nasm_test.sh deleted file mode 100755 index 90a6e89f..00000000 --- a/src/parsers/nasm/tests/nasm_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh -# $IdPath$ -${srcdir}/out_test.sh nasm_test src/parsers/nasm/tests "nasm-compat parser" "-f bin" "" -exit $? diff --git a/src/parsers/nasm/tests/newsect.asm b/src/parsers/nasm/tests/newsect.asm deleted file mode 100644 index 420e17ca..00000000 --- a/src/parsers/nasm/tests/newsect.asm +++ /dev/null @@ -1,10 +0,0 @@ -[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 diff --git a/src/parsers/nasm/tests/newsect.errwarn b/src/parsers/nasm/tests/newsect.errwarn deleted file mode 100644 index e69de29b..00000000 diff --git a/src/parsers/nasm/tests/newsect.hex b/src/parsers/nasm/tests/newsect.hex deleted file mode 100644 index 7b68ada6..00000000 --- a/src/parsers/nasm/tests/newsect.hex +++ /dev/null @@ -1,4 +0,0 @@ -41 -42 -43 -44 diff --git a/src/preproc.h b/src/preproc.h deleted file mode 100644 index 67d970c9..00000000 --- a/src/preproc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $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 diff --git a/src/preprocs/Makefile.inc b/src/preprocs/Makefile.inc deleted file mode 100644 index 0fae8c09..00000000 --- a/src/preprocs/Makefile.inc +++ /dev/null @@ -1,10 +0,0 @@ -# $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 diff --git a/src/preprocs/nasm/Makefile.inc b/src/preprocs/nasm/Makefile.inc deleted file mode 100644 index 8881b877..00000000 --- a/src/preprocs/nasm/Makefile.inc +++ /dev/null @@ -1,28 +0,0 @@ -# $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 diff --git a/src/preprocs/nasm/macros.pl b/src/preprocs/nasm/macros.pl deleted file mode 100644 index bb217e15..00000000 --- a/src/preprocs/nasm/macros.pl +++ /dev/null @@ -1,48 +0,0 @@ -#!/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); diff --git a/src/preprocs/nasm/nasm-eval.c b/src/preprocs/nasm/nasm-eval.c deleted file mode 100644 index 545f4256..00000000 --- a/src/preprocs/nasm/nasm-eval.c +++ /dev/null @@ -1,823 +0,0 @@ -/* 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; -} diff --git a/src/preprocs/nasm/nasm-eval.h b/src/preprocs/nasm/nasm-eval.h deleted file mode 100644 index 92495937..00000000 --- a/src/preprocs/nasm/nasm-eval.h +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 diff --git a/src/preprocs/nasm/nasm-pp.c b/src/preprocs/nasm/nasm-pp.c deleted file mode 100644 index d5095df0..00000000 --- a/src/preprocs/nasm/nasm-pp.c +++ /dev/null @@ -1,4455 +0,0 @@ -/* -*- 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 -}; diff --git a/src/preprocs/nasm/nasm-pp.h b/src/preprocs/nasm/nasm-pp.h deleted file mode 100644 index 82a1569c..00000000 --- a/src/preprocs/nasm/nasm-pp.h +++ /dev/null @@ -1,20 +0,0 @@ -/* 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 diff --git a/src/preprocs/nasm/nasm-preproc.c b/src/preprocs/nasm/nasm-preproc.c deleted file mode 100644 index e7a2b7e9..00000000 --- a/src/preprocs/nasm/nasm-preproc.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 -}; diff --git a/src/preprocs/nasm/nasm.h b/src/preprocs/nasm/nasm.h deleted file mode 100644 index 890991b9..00000000 --- a/src/preprocs/nasm/nasm.h +++ /dev/null @@ -1,847 +0,0 @@ -/* 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 diff --git a/src/preprocs/nasm/nasmlib.c b/src/preprocs/nasm/nasmlib.c deleted file mode 100644 index 5eb2be1a..00000000 --- a/src/preprocs/nasm/nasmlib.c +++ /dev/null @@ -1,370 +0,0 @@ -/* 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; -} diff --git a/src/preprocs/nasm/nasmlib.h b/src/preprocs/nasm/nasmlib.h deleted file mode 100644 index 9e45f16c..00000000 --- a/src/preprocs/nasm/nasmlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* 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 diff --git a/src/preprocs/nasm/standard.mac b/src/preprocs/nasm/standard.mac deleted file mode 100644 index bbbf90d8..00000000 --- a/src/preprocs/nasm/standard.mac +++ /dev/null @@ -1,110 +0,0 @@ -; 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 - - diff --git a/src/preprocs/raw/Makefile.inc b/src/preprocs/raw/Makefile.inc deleted file mode 100644 index 4124f396..00000000 --- a/src/preprocs/raw/Makefile.inc +++ /dev/null @@ -1,9 +0,0 @@ -# $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 diff --git a/src/preprocs/raw/raw-preproc.c b/src/preprocs/raw/raw-preproc.c deleted file mode 100644 index 49f6e8cf..00000000 --- a/src/preprocs/raw/raw-preproc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 -}; diff --git a/src/preprocs/yapp/Makefile.inc b/src/preprocs/yapp/Makefile.inc deleted file mode 100644 index 7d1039c3..00000000 --- a/src/preprocs/yapp/Makefile.inc +++ /dev/null @@ -1,20 +0,0 @@ -# $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 diff --git a/src/preprocs/yapp/tests/Makefile.inc b/src/preprocs/yapp/tests/Makefile.inc deleted file mode 100644 index 187ea306..00000000 --- a/src/preprocs/yapp/tests/Makefile.inc +++ /dev/null @@ -1,28 +0,0 @@ -# $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 diff --git a/src/preprocs/yapp/tests/comment.asm b/src/preprocs/yapp/tests/comment.asm deleted file mode 100644 index e41966d4..00000000 --- a/src/preprocs/yapp/tests/comment.asm +++ /dev/null @@ -1,2 +0,0 @@ -; mov ax, 4 ; asdfasdf - mov ax, 4 ; asdfasdf diff --git a/src/preprocs/yapp/tests/comment.pre b/src/preprocs/yapp/tests/comment.pre deleted file mode 100644 index 6d0bfdd3..00000000 --- a/src/preprocs/yapp/tests/comment.pre +++ /dev/null @@ -1,2 +0,0 @@ -%line 2+1 - - mov ax, 4 diff --git a/src/preprocs/yapp/tests/ddefine.asm b/src/preprocs/yapp/tests/ddefine.asm deleted file mode 100644 index ae46fc6f..00000000 --- a/src/preprocs/yapp/tests/ddefine.asm +++ /dev/null @@ -1,6 +0,0 @@ -%define foo 5 -%define bar baz - mov ax, [foo+bar] -%define baz bzzt -%define bzzt 9 - mov ax, baz+bar diff --git a/src/preprocs/yapp/tests/ddefine.pre b/src/preprocs/yapp/tests/ddefine.pre deleted file mode 100644 index 5d2f788d..00000000 --- a/src/preprocs/yapp/tests/ddefine.pre +++ /dev/null @@ -1,5 +0,0 @@ -%line 3+1 - - mov ax, [5+baz] - - - mov ax, 9+9 diff --git a/src/preprocs/yapp/tests/define.asm b/src/preprocs/yapp/tests/define.asm deleted file mode 100644 index f9330d39..00000000 --- a/src/preprocs/yapp/tests/define.asm +++ /dev/null @@ -1,4 +0,0 @@ -%define foo 5 -%define bar baz - mov ax, [foo+bar] -%define baz bzzt diff --git a/src/preprocs/yapp/tests/define.pre b/src/preprocs/yapp/tests/define.pre deleted file mode 100644 index b631ba28..00000000 --- a/src/preprocs/yapp/tests/define.pre +++ /dev/null @@ -1,3 +0,0 @@ -%line 3+1 - - mov ax, [5+baz] - diff --git a/src/preprocs/yapp/tests/ifdef.asm b/src/preprocs/yapp/tests/ifdef.asm deleted file mode 100644 index b9d7807e..00000000 --- a/src/preprocs/yapp/tests/ifdef.asm +++ /dev/null @@ -1,13 +0,0 @@ -%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 diff --git a/src/preprocs/yapp/tests/ifdef.pre b/src/preprocs/yapp/tests/ifdef.pre deleted file mode 100644 index 4031163b..00000000 --- a/src/preprocs/yapp/tests/ifdef.pre +++ /dev/null @@ -1,5 +0,0 @@ -%line 9+1 - - mov ax, 5 - - -%line 14+1 - diff --git a/src/preprocs/yapp/tests/include.asm b/src/preprocs/yapp/tests/include.asm deleted file mode 100644 index 7372f0f0..00000000 --- a/src/preprocs/yapp/tests/include.asm +++ /dev/null @@ -1,5 +0,0 @@ - mov ax, 5 -%include "./src/preprocs/yapp/tests/raw.asm" - mov ax, 6 -%include "./src/preprocs/yapp/tests/raw.asm" - mov ax, 7 diff --git a/src/preprocs/yapp/tests/include.pre b/src/preprocs/yapp/tests/include.pre deleted file mode 100644 index 418078c0..00000000 --- a/src/preprocs/yapp/tests/include.pre +++ /dev/null @@ -1,10 +0,0 @@ -%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 diff --git a/src/preprocs/yapp/tests/params.asm b/src/preprocs/yapp/tests/params.asm deleted file mode 100644 index 046775e8..00000000 --- a/src/preprocs/yapp/tests/params.asm +++ /dev/null @@ -1,2 +0,0 @@ -%define foo(a, b) (a)+(b) - foo((a+b,c),(d*e,f)) diff --git a/src/preprocs/yapp/tests/params.pre b/src/preprocs/yapp/tests/params.pre deleted file mode 100644 index dc2cd987..00000000 --- a/src/preprocs/yapp/tests/params.pre +++ /dev/null @@ -1,2 +0,0 @@ -%line 2+1 - - ((a+b,c))+((d*e,f)) diff --git a/src/preprocs/yapp/tests/pdefine.asm b/src/preprocs/yapp/tests/pdefine.asm deleted file mode 100644 index ebde9222..00000000 --- a/src/preprocs/yapp/tests/pdefine.asm +++ /dev/null @@ -1,6 +0,0 @@ -%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) diff --git a/src/preprocs/yapp/tests/pdefine.pre b/src/preprocs/yapp/tests/pdefine.pre deleted file mode 100644 index 553799d9..00000000 --- a/src/preprocs/yapp/tests/pdefine.pre +++ /dev/null @@ -1,5 +0,0 @@ -%line 3+1 - - mov ax, foo - mov ax, 5+1 - mov ax, 5-3 - mov ax, foo(5, 6, 7) diff --git a/src/preprocs/yapp/tests/raw.asm b/src/preprocs/yapp/tests/raw.asm deleted file mode 100644 index 9d5f67f6..00000000 --- a/src/preprocs/yapp/tests/raw.asm +++ /dev/null @@ -1 +0,0 @@ - mov ax, raw diff --git a/src/preprocs/yapp/tests/raw.pre b/src/preprocs/yapp/tests/raw.pre deleted file mode 100644 index 3bf60621..00000000 --- a/src/preprocs/yapp/tests/raw.pre +++ /dev/null @@ -1,2 +0,0 @@ -%line 1+1 - - mov ax, raw diff --git a/src/preprocs/yapp/tests/rdefine.asm b/src/preprocs/yapp/tests/rdefine.asm deleted file mode 100644 index c4b1644b..00000000 --- a/src/preprocs/yapp/tests/rdefine.asm +++ /dev/null @@ -1,6 +0,0 @@ -%define recursion endless -%define endless recursion - mov ax, 5 - mov ax, endless -%define recurse recurse - mov ax, recurse diff --git a/src/preprocs/yapp/tests/rdefine.pre b/src/preprocs/yapp/tests/rdefine.pre deleted file mode 100644 index dfc1bfac..00000000 --- a/src/preprocs/yapp/tests/rdefine.pre +++ /dev/null @@ -1,5 +0,0 @@ -%line 3+1 - - mov ax, 5 - mov ax, endless - - mov ax, recurse diff --git a/src/preprocs/yapp/tests/rinclude.asm b/src/preprocs/yapp/tests/rinclude.asm deleted file mode 100644 index 988fd521..00000000 --- a/src/preprocs/yapp/tests/rinclude.asm +++ /dev/null @@ -1,5 +0,0 @@ -%ifndef recurse -%define recurse -%include "./src/preprocs/yapp/tests/rinclude.asm" - mov ax, 5 -%endif diff --git a/src/preprocs/yapp/tests/rinclude.pre b/src/preprocs/yapp/tests/rinclude.pre deleted file mode 100644 index 63ac7fcd..00000000 --- a/src/preprocs/yapp/tests/rinclude.pre +++ /dev/null @@ -1,3 +0,0 @@ -%line 4+1 - - mov ax, 5 - diff --git a/src/preprocs/yapp/tests/yapp_test.sh b/src/preprocs/yapp/tests/yapp_test.sh deleted file mode 100755 index 6c1c6e63..00000000 --- a/src/preprocs/yapp/tests/yapp_test.sh +++ /dev/null @@ -1,60 +0,0 @@ -#! /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` diff --git a/src/preprocs/yapp/yapp-preproc.c b/src/preprocs/yapp/yapp-preproc.c deleted file mode 100644 index f425aa59..00000000 --- a/src/preprocs/yapp/yapp-preproc.c +++ /dev/null @@ -1,954 +0,0 @@ -/* $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 -}; diff --git a/src/preprocs/yapp/yapp-preproc.h b/src/preprocs/yapp/yapp-preproc.h deleted file mode 100644 index 531d6b10..00000000 --- a/src/preprocs/yapp/yapp-preproc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $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()) - diff --git a/src/preprocs/yapp/yapp-token.h b/src/preprocs/yapp/yapp-token.h deleted file mode 100644 index 43012495..00000000 --- a/src/preprocs/yapp/yapp-token.h +++ /dev/null @@ -1,64 +0,0 @@ -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); diff --git a/src/preprocs/yapp/yapp-token.l b/src/preprocs/yapp/yapp-token.l deleted file mode 100644 index 82fd52be..00000000 --- a/src/preprocs/yapp/yapp-token.l +++ /dev/null @@ -1,356 +0,0 @@ -/* $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); -} diff --git a/src/section.c b/src/section.c deleted file mode 100644 index 861eb045..00000000 --- a/src/section.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 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); - } -} diff --git a/src/section.h b/src/section.h deleted file mode 100644 index ffef79ee..00000000 --- a/src/section.h +++ /dev/null @@ -1,83 +0,0 @@ -/* $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 diff --git a/src/strcasecmp.c b/src/strcasecmp.c deleted file mode 100644 index a7b2a927..00000000 --- a/src/strcasecmp.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 diff --git a/src/symrec.c b/src/symrec.c deleted file mode 100644 index b6ceb1b8..00000000 --- a/src/symrec.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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); -} diff --git a/src/symrec.h b/src/symrec.h deleted file mode 100644 index b8238187..00000000 --- a/src/symrec.h +++ /dev/null @@ -1,80 +0,0 @@ -/* $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 diff --git a/src/tests/Makefile.inc b/src/tests/Makefile.inc deleted file mode 100644 index a4e6a792..00000000 --- a/src/tests/Makefile.inc +++ /dev/null @@ -1,47 +0,0 @@ -# $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@ diff --git a/src/tests/bitvect_test.c b/src/tests/bitvect_test.c deleted file mode 100644 index 6ad5b430..00000000 --- a/src/tests/bitvect_test.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $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; -} diff --git a/src/tests/bytecode_test.c b/src/tests/bytecode_test.c deleted file mode 100644 index 67108764..00000000 --- a/src/tests/bytecode_test.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $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; -} diff --git a/src/tests/floatnum_test.c b/src/tests/floatnum_test.c deleted file mode 100644 index bf18f93a..00000000 --- a/src/tests/floatnum_test.c +++ /dev/null @@ -1,435 +0,0 @@ -/* $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; -} diff --git a/src/tests/memexpr_test.c b/src/tests/memexpr_test.c deleted file mode 100644 index e1db4cc2..00000000 --- a/src/tests/memexpr_test.c +++ /dev/null @@ -1,422 +0,0 @@ -/* $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; -} diff --git a/src/util.h b/src/util.h deleted file mode 100644 index fc0113c7..00000000 --- a/src/util.h +++ /dev/null @@ -1,179 +0,0 @@ -/* $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 diff --git a/src/valparam.c b/src/valparam.c deleted file mode 100644 index 8126712b..00000000 --- a/src/valparam.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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, ","); - } -} diff --git a/src/valparam.h b/src/valparam.h deleted file mode 100644 index af7af9c1..00000000 --- a/src/valparam.h +++ /dev/null @@ -1,67 +0,0 @@ -/* $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 diff --git a/src/xmalloc.c b/src/xmalloc.c deleted file mode 100644 index b8fbe013..00000000 --- a/src/xmalloc.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 diff --git a/src/xstrdup.c b/src/xstrdup.c deleted file mode 100644 index 473554fc..00000000 --- a/src/xstrdup.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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); -} -- 2.40.0