Merge [1579] from trunk.

svn path=/branches/yasm-0.5.x/; revision=1580
diff --git a/Makefile.am b/Makefile.am
index a2d9322..f1c46d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,6 @@
 bin_PROGRAMS =
 dist_man_MANS =
 TESTS =
-TESTS_ENVIRONMENT =
 noinst_PROGRAMS = genstring
 
 check_PROGRAMS = test_hd
@@ -103,13 +102,6 @@
 
 distclean-local:
 	-rm -rf results
-if HAVE_PYTHON
-	-rm -rf build
-endif
-
-all-local: python-build
-install-hook: python-install
-uninstall-hook: python-uninstall
 
 if BUILD_MAN
 MAINTAINERCLEANFILES = $(dist_man_MANS)
diff --git a/Mkfiles/Makefile.dj b/Mkfiles/Makefile.dj
index d022b56..17c2890 100644
--- a/Mkfiles/Makefile.dj
+++ b/Mkfiles/Makefile.dj
@@ -19,12 +19,6 @@
  libyasm/arch.o \
  libyasm/assocdat.o \
  libyasm/bitvect.o \
- libyasm/bc-align.o \
- libyasm/bc-data.o \
- libyasm/bc-incbin.o \
- libyasm/bc-insn.o \
- libyasm/bc-org.o \
- libyasm/bc-reserve.o \
  libyasm/bytecode.o \
  libyasm/errwarn.o \
  libyasm/expr.o \
diff --git a/Mkfiles/Makefile.flat b/Mkfiles/Makefile.flat
index 0724f3d..f7d97cd 100644
--- a/Mkfiles/Makefile.flat
+++ b/Mkfiles/Makefile.flat
@@ -22,12 +22,6 @@
  libyasm/arch.o \
  libyasm/assocdat.o \
  libyasm/bitvect.o \
- libyasm/bc-align.o \
- libyasm/bc-data.o \
- libyasm/bc-incbin.o \
- libyasm/bc-insn.o \
- libyasm/bc-org.o \
- libyasm/bc-reserve.o \
  libyasm/bytecode.o \
  libyasm/errwarn.o \
  libyasm/expr.o \
diff --git a/Mkfiles/dj/config.h b/Mkfiles/dj/config.h
index e5e3f5d..94a7a80 100644
--- a/Mkfiles/dj/config.h
+++ b/Mkfiles/dj/config.h
@@ -120,22 +120,22 @@
 #define PACKAGE_BUGREPORT "bug-yasm@tortall.net"

 

 /* Define to build version of this package. */

-#define PACKAGE_BUILD "HEAD"

+#define PACKAGE_BUILD "BRANCH"

 

 /* Define to internal version of this package. */

-#define PACKAGE_INTVER "0.5.99"

+#define PACKAGE_INTVER "0.5.1"

 

 /* Define to the full name of this package. */

 #define PACKAGE_NAME "yasm"

 

 /* Define to the full name and version of this package. */

-#define PACKAGE_STRING "yasm HEAD"

+#define PACKAGE_STRING "yasm 0.5.x"

 

 /* Define to the one symbol short name of this package. */

 #define PACKAGE_TARNAME "yasm"

 

 /* Define to the version of this package. */

-#define PACKAGE_VERSION "HEAD"

+#define PACKAGE_VERSION "0.5.x"

 

 /* Define if the C compiler supports function prototypes. */

 #define PROTOTYPES 1

@@ -159,7 +159,7 @@
 #define STDC_HEADERS 1

 

 /* Version number of package */

-#define VERSION "HEAD"

+#define VERSION "0.5.x"

 

 /* Define if using the dmalloc debugging malloc package */

 /* #undef WITH_DMALLOC */

diff --git a/Mkfiles/vc/config.h b/Mkfiles/vc/config.h
index 35e2a12..8ca63df 100644
--- a/Mkfiles/vc/config.h
+++ b/Mkfiles/vc/config.h
@@ -121,22 +121,22 @@
 #define PACKAGE_BUGREPORT "bug-yasm@tortall.net"

 

 /* Define to build version of this package. */

-#define PACKAGE_BUILD "HEAD"

+#define PACKAGE_BUILD "BRANCH"

 

 /* Define to internal version of this package. */

-#define PACKAGE_INTVER "0.5.99"

+#define PACKAGE_INTVER "0.5.1"

 

 /* Define to the full name of this package. */

 #define PACKAGE_NAME "yasm"

 

 /* Define to the full name and version of this package. */

-#define PACKAGE_STRING "yasm HEAD"

+#define PACKAGE_STRING "yasm 0.5.x"

 

 /* Define to the one symbol short name of this package. */

 #define PACKAGE_TARNAME "yasm"

 

 /* Define to the version of this package. */

-#define PACKAGE_VERSION "HEAD"

+#define PACKAGE_VERSION "0.5.x"

 

 /* Define if the C compiler supports function prototypes. */

 #define PROTOTYPES 1

@@ -160,7 +160,7 @@
 #define STDC_HEADERS 1

 

 /* Version number of package */

-#define VERSION "HEAD"

+#define VERSION "0.5.x"

 

 /* Define if using the dmalloc debugging malloc package */

 /* #undef WITH_DMALLOC */

diff --git a/Mkfiles/vc/libyasm/libyasm.vcproj b/Mkfiles/vc/libyasm/libyasm.vcproj
index bf8aba8..c586293 100644
--- a/Mkfiles/vc/libyasm/libyasm.vcproj
+++ b/Mkfiles/vc/libyasm/libyasm.vcproj
@@ -130,24 +130,6 @@
 				RelativePath="..\..\..\libyasm\bitvect.c">

 			</File>

 			<File

-				RelativePath="..\..\..\libyasm\bc-align.c">

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-data.c">

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-incbin.c">

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-insn.c">

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-org.c">

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-reserve.c">

-			</File>

-			<File

 				RelativePath="..\..\..\libyasm\bytecode.c">

 			</File>

 			<File

diff --git a/Mkfiles/vc8/config.h b/Mkfiles/vc8/config.h
index 9beb477..198f885 100644
--- a/Mkfiles/vc8/config.h
+++ b/Mkfiles/vc8/config.h
@@ -123,22 +123,22 @@
 #define PACKAGE_BUGREPORT "bug-yasm@tortall.net"

 

 /* Define to build version of this package. */

-#define PACKAGE_BUILD "HEAD"

+#define PACKAGE_BUILD "BRANCH"

 

 /* Define to internal version of this package. */

-#define PACKAGE_INTVER "0.5.99"

+#define PACKAGE_INTVER "0.5.1"

 

 /* Define to the full name of this package. */

 #define PACKAGE_NAME "yasm"

 

 /* Define to the full name and version of this package. */

-#define PACKAGE_STRING "yasm HEAD"

+#define PACKAGE_STRING "yasm 0.5.x"

 

 /* Define to the one symbol short name of this package. */

 #define PACKAGE_TARNAME "yasm"

 

 /* Define to the version of this package. */

-#define PACKAGE_VERSION "HEAD"

+#define PACKAGE_VERSION "0.5.x"

 

 /* Define if the C compiler supports function prototypes. */

 #define PROTOTYPES 1

@@ -162,7 +162,7 @@
 #define STDC_HEADERS 1

 

 /* Version number of package */

-#define VERSION "HEAD"

+#define VERSION "0.5.x"

 

 /* Define if using the dmalloc debugging malloc package */

 /* #undef WITH_DMALLOC */

diff --git a/Mkfiles/vc8/libyasm/libyasm.vcproj b/Mkfiles/vc8/libyasm/libyasm.vcproj
index adf19d0..3a72ec0 100644
--- a/Mkfiles/vc8/libyasm/libyasm.vcproj
+++ b/Mkfiles/vc8/libyasm/libyasm.vcproj
@@ -334,30 +334,6 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\..\libyasm\bc-align.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-data.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-incbin.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-insn.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-org.c"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\libyasm\bc-reserve.c"

-				>

-			</File>

-			<File

 				RelativePath="..\..\..\libyasm\bytecode.c"

 				>

 			</File>

diff --git a/configure.ac b/configure.ac
index 1e1e045..12dab43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,12 +10,12 @@
 AC_CONFIG_AUX_DIR(config)
 AM_CONFIG_HEADER([config.h])
 
-AM_INIT_AUTOMAKE(yasm, [HEAD])
+AM_INIT_AUTOMAKE(yasm, [0.5.x])
 AM_MAINTAINER_MODE
 
-AC_DEFINE(PACKAGE_INTVER, ["0.5.99"],
+AC_DEFINE(PACKAGE_INTVER, ["0.5.1"],
 	  [Define to internal version of this package.])
-AC_DEFINE(PACKAGE_BUILD, ["HEAD"], [Define to build version of this package.])
+AC_DEFINE(PACKAGE_BUILD, ["BRANCH"], [Define to build version of this package.])
 
 #
 # autoconf command-line options
@@ -53,14 +53,6 @@
   *) AC_MSG_ERROR([bad value ${enableval} for --enable-gcov]) ;;
 esac])
 
-AC_ARG_ENABLE(python,
-AC_HELP_STRING([--enable-python],[Build Python bindings]),
-[case "${enableval}" in
-  yes) enable_python="yes" ;;
-  no)  enable_python="no" ;;
-  *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
-esac], enable_python="auto")
-
 #
 # Checks for programs.
 #
@@ -160,7 +152,6 @@
 # Force x86 architecture only for now.
 ARCH=x86
 AC_SUBST([ARCH])
-AC_SUBST([GCC])
 
 # Require things for --enable-maintainer-mode option.
 if test "$USE_MAINTAINER_MODE" = "yes"; then
@@ -257,41 +248,6 @@
 HOST_CC="$CC_FOR_BUILD"
 AC_SUBST(HOST_CC)
 
-# Detect if we can build Python bindings
-# (needs Python, Python headers, and Pyrex)
-if test x$enable_python = xno; then
-    have_python=no
-else
-    AC_MSG_NOTICE([Checking to see if we can build Python bindings])
-    have_python=no
-    AM_PATH_PYTHON(2.4,[],[AC_MSG_WARN([Python not found])])
-
-    if test -z "$PYTHON" || test "$PYTHON" = : ; then
-        have_python=no
-    else
-        AC_MSG_CHECKING([for Pyrex >= 0.9.3])
-        PYREX_CHECK_VERSION(0.9.3, [AC_MSG_RESULT(yes)
-                                    have_pyrex=yes],
-                                   [AC_MSG_RESULT(no)
-                                    have_pyrex=no])
-
-        AM_CHECK_PYTHON_HEADERS(have_python_headers=yes,have_python_headers=no)
-
-	if test x$have_pyrex = xyes -a x$have_python_headers = xyes ; then
-	    have_python=yes
-        fi
-    fi
-
-    if test x$have_python = xno ; then
-        if test x$enable_python = xyes ; then
-            AC_MSG_ERROR([Building Python explicitly requested, but can't build Python bindings because either Pyrex, Python headers or a suitable Python version was not found])
-        else
-            AC_MSG_WARN([Couldn't find either Pyrex, the Python headers or a suitable version of Python, not building Python bindings])
-        fi
-    fi               
-fi
-
-AM_CONDITIONAL(HAVE_PYTHON, test x$have_python = xyes)
 
 AC_CONFIG_FILES([Makefile
 	po/Makefile.in
diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c
index 8a638a3..b7bc7e4 100644
--- a/frontends/yasm/yasm.c
+++ b/frontends/yasm/yasm.c
@@ -79,9 +79,7 @@
 
 /*@null@*/ /*@dependent@*/ static FILE *open_file(const char *filename,
 						  const char *mode);
-static void check_errors(/*@only@*/ yasm_errwarns *errwarns,
-			 /*@only@*/ yasm_object *object);
-static void cleanup(/*@null@*/ /*@only@*/ yasm_object *object);
+static void cleanup(/*@null@*/ yasm_object *object);
 
 /* Forward declarations: cmd line parser handlers */
 static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
@@ -110,9 +108,7 @@
 static /*@exits@*/ void handle_yasm_fatal(const char *message, va_list va);
 static const char *handle_yasm_gettext(const char *msgid);
 static void print_yasm_error(const char *filename, unsigned long line,
-			     const char *msg, /*@null@*/ const char *xref_fn,
-			     unsigned long xref_line,
-			     /*@null@*/ const char *xref_msg);
+			     const char *msg);
 static void print_yasm_warning(const char *filename, unsigned long line,
 			       const char *msg);
 
@@ -184,10 +180,10 @@
 };
 
 /* help messages */
-/*@observer@*/ static const char *help_head = N_(
+/*@observer@*/ static const char help_head[] = N_(
     "usage: yasm [option]* file\n"
     "Options:\n");
-/*@observer@*/ static const char *help_tail = N_(
+/*@observer@*/ static const char help_tail[] = N_(
     "\n"
     "Files are asm sources to be assembled.\n"
     "\n"
@@ -218,7 +214,6 @@
     size_t i;
     yasm_arch_create_error arch_error;
     const char *base_filename;
-    yasm_errwarns *errwarns;
 
 #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
     setlocale(LC_MESSAGES, "");
@@ -233,7 +228,6 @@
     yasm_fatal = handle_yasm_fatal;
     yasm_gettext_hook = handle_yasm_gettext;
     yasm_errwarn_initialize();
-    errwarns = yasm_errwarns_create();
 
     /* Initialize parameter storage */
     STAILQ_INIT(&preproc_options);
@@ -350,7 +344,7 @@
 	
 	/* Pre-process until done */
 	cur_preproc = yasm_preproc_create(cur_preproc_module, in, in_filename,
-					  linemap, errwarns);
+					  linemap);
 
 	apply_preproc_builtins();
 	apply_preproc_saved_options();
@@ -384,20 +378,18 @@
 	if (obj != stdout)
 	    fclose(obj);
 
-	if (yasm_errwarns_num_errors(errwarns, warning_error) > 0) {
-	    yasm_errwarns_output_all(errwarns, linemap, warning_error,
-				     print_yasm_error, print_yasm_warning);
+	if (yasm_get_num_errors(warning_error) > 0) {
+	    yasm_errwarn_output_all(linemap, warning_error, print_yasm_error,
+				    print_yasm_warning);
 	    if (obj != stdout)
 		remove(obj_filename);
 	    yasm_xfree(preproc_buf);
 	    yasm_linemap_destroy(linemap);
-	    yasm_errwarns_destroy(errwarns);
 	    cleanup(NULL);
 	    return EXIT_FAILURE;
 	}
 	yasm_xfree(preproc_buf);
 	yasm_linemap_destroy(linemap);
-	yasm_errwarns_destroy(errwarns);
 	cleanup(NULL);
 	return EXIT_SUCCESS;
     }
@@ -602,8 +594,7 @@
     }
 
     cur_preproc = cur_preproc_module->create(in, in_filename,
-					     yasm_object_get_linemap(object),
-					     errwarns);
+					     yasm_object_get_linemap(object));
 
     apply_preproc_builtins();
     apply_preproc_saved_options();
@@ -617,31 +608,46 @@
     /* Parse! */
     cur_parser_module->do_parse(object, cur_preproc, cur_arch, cur_objfmt,
 				cur_dbgfmt, in, in_filename,
-				list_filename != NULL, def_sect, errwarns);
+				list_filename != NULL, def_sect);
 
     /* Close input file */
     if (in != stdin)
 	fclose(in);
 
-    check_errors(errwarns, object);
-
     /* Check for undefined symbols */
     yasm_symtab_parser_finalize(yasm_object_get_symtab(object),
 				strcmp(cur_parser_module->keyword, "gas")==0,
-				cur_objfmt, errwarns);
-    check_errors(errwarns, object);
+				cur_objfmt);
+
+    if (yasm_get_num_errors(warning_error) > 0) {
+	yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
+				print_yasm_error, print_yasm_warning);
+	cleanup(object);
+	return EXIT_FAILURE;
+    }
 
     /* Finalize parse */
-    yasm_object_finalize(object, errwarns);
-    check_errors(errwarns, object);
+    yasm_object_finalize(object);
+
+    if (yasm_get_num_errors(warning_error) > 0) {
+	yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
+				print_yasm_error, print_yasm_warning);
+	cleanup(object);
+	return EXIT_FAILURE;
+    }
 
     /* Optimize */
-    cur_optimizer_module->optimize(object, errwarns);
-    check_errors(errwarns, object);
+    cur_optimizer_module->optimize(object);
+
+    if (yasm_get_num_errors(warning_error) > 0) {
+	yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
+				print_yasm_error, print_yasm_warning);
+	cleanup(object);
+	return EXIT_FAILURE;
+    }
 
     /* generate any debugging information */
-    yasm_dbgfmt_generate(cur_dbgfmt, errwarns);
-    check_errors(errwarns, object);
+    yasm_dbgfmt_generate(cur_dbgfmt);
 
     /* open the object file for output (if not already opened by dbg objfmt) */
     if (!obj && strcmp(cur_objfmt_module->keyword, "dbg") != 0) {
@@ -654,8 +660,7 @@
 
     /* Write the object file */
     yasm_objfmt_output(cur_objfmt, obj?obj:stderr,
-		       strcmp(cur_dbgfmt_module->keyword, "null"), cur_dbgfmt,
-		       errwarns);
+		       strcmp(cur_dbgfmt_module->keyword, "null"), cur_dbgfmt);
 
     /* Close object file */
     if (obj)
@@ -664,9 +669,13 @@
     /* 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_errwarns_num_errors(errwarns, warning_error) > 0)
+    if (yasm_get_num_errors(warning_error) > 0) {
+	yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
+				print_yasm_error, print_yasm_warning);
 	remove(obj_filename);
-    check_errors(errwarns, object);
+	cleanup(object);
+	return EXIT_FAILURE;
+    }
 
     /* Open and write the list file */
     if (list_filename) {
@@ -683,9 +692,8 @@
 	fclose(list);
     }
 
-    yasm_errwarns_output_all(errwarns, yasm_object_get_linemap(object),
-			     warning_error, print_yasm_error,
-			     print_yasm_warning);
+    yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
+			    print_yasm_error, print_yasm_warning);
 
     cleanup(object);
     return EXIT_SUCCESS;
@@ -704,19 +712,6 @@
     return f;
 }
 
-static void
-check_errors(yasm_errwarns *errwarns, yasm_object *object)
-{
-    if (yasm_errwarns_num_errors(errwarns, warning_error) > 0) {
-	yasm_errwarns_output_all(errwarns, yasm_object_get_linemap(object),
-				 warning_error, print_yasm_error,
-				 print_yasm_warning);
-	yasm_errwarns_destroy(errwarns);
-	cleanup(object);
-	exit(EXIT_FAILURE);
-    }
-}
-
 /* 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).
@@ -1177,39 +1172,19 @@
     return gettext(msgid);
 }
 
-static const char *fmt[2] = {
+const char *fmt[2] = {
 	"%s:%lu: %s%s\n",	/* GNU */
 	"%s(%lu) : %s%s\n"	/* VC */
 };
 
-static const char *fmt_noline[2] = {
-	"%s: %s%s\n",	/* GNU */
-	"%s : %s%s\n"	/* VC */
-};
-
 static void
-print_yasm_error(const char *filename, unsigned long line, const char *msg,
-		 const char *xref_fn, unsigned long xref_line,
-		 const char *xref_msg)
+print_yasm_error(const char *filename, unsigned long line, const char *msg)
 {
-    if (line)
-	fprintf(stderr, fmt[ewmsg_style], filename, line, "", msg);
-    else
-	fprintf(stderr, fmt_noline[ewmsg_style], filename, "", msg);
-
-    if (xref_fn && xref_msg) {
-	if (xref_line)
-	    fprintf(stderr, fmt[ewmsg_style], xref_fn, xref_line, "", xref_msg);
-	else
-	    fprintf(stderr, fmt_noline[ewmsg_style], xref_fn, "", xref_msg);
-    }
+    fprintf(stderr, fmt[ewmsg_style], filename, line, "", msg);
 }
 
 static void
 print_yasm_warning(const char *filename, unsigned long line, const char *msg)
 {
-    if (line)
-	fprintf(stderr, fmt[ewmsg_style], filename, line, _("warning: "), msg);
-    else
-	fprintf(stderr, fmt_noline[ewmsg_style], filename, _("warning: "), msg);
+    fprintf(stderr, fmt[ewmsg_style], filename, line, _("warning: "), msg);
 }
diff --git a/libyasm/Makefile.inc b/libyasm/Makefile.inc
index d411e71..105173c 100644
--- a/libyasm/Makefile.inc
+++ b/libyasm/Makefile.inc
@@ -3,12 +3,6 @@
 libyasm_a_SOURCES += libyasm/arch.c
 libyasm_a_SOURCES += libyasm/assocdat.c
 libyasm_a_SOURCES += libyasm/bitvect.c
-libyasm_a_SOURCES += libyasm/bc-align.c
-libyasm_a_SOURCES += libyasm/bc-data.c
-libyasm_a_SOURCES += libyasm/bc-incbin.c
-libyasm_a_SOURCES += libyasm/bc-insn.c
-libyasm_a_SOURCES += libyasm/bc-org.c
-libyasm_a_SOURCES += libyasm/bc-reserve.c
 libyasm_a_SOURCES += libyasm/bytecode.c
 libyasm_a_SOURCES += libyasm/errwarn.c
 libyasm_a_SOURCES += libyasm/expr.c
diff --git a/libyasm/arch.h b/libyasm/arch.h
index 0d94c7b..e7846f5 100644
--- a/libyasm/arch.h
+++ b/libyasm/arch.h
@@ -136,21 +136,22 @@
     /** Module-level implementation of yasm_arch_parse_cpu().
      * Call yasm_arch_parse_cpu() instead of calling this function.
      */
-    void (*parse_cpu) (yasm_arch *arch, const char *cpuid, size_t cpuid_len);
+    void (*parse_cpu) (yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+		       unsigned long line);
 
     /** Module-level implementation of yasm_arch_parse_check_insnprefix().
      * Call yasm_arch_parse_check_insnprefix() instead of calling this function.
      */
     yasm_arch_insnprefix (*parse_check_insnprefix)
 	(yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
-	 size_t id_len);
+	 size_t id_len, unsigned long line);
 
     /** Module-level implementation of yasm_arch_parse_check_regtmod().
      * Call yasm_arch_parse_check_regtmod() instead of calling this function.
      */
     yasm_arch_regtmod (*parse_check_regtmod)
 	(yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
-	 size_t id_len);
+	 size_t id_len, unsigned long line);
 
     /** Module-level implementation of yasm_arch_parse_directive().
      * Call yasm_arch_parse_directive() instead of calling this function.
@@ -180,7 +181,8 @@
      */
     int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
 			     unsigned char *buf, size_t destsize,
-			     size_t valsize, size_t shift, int warn);
+			     size_t valsize, size_t shift, int warn,
+			     unsigned long line);
 
     /** Module-level implementation of yasm_arch_intnum_tobytes().
      * Call yasm_arch_intnum_tobytes() instead of calling this function.
@@ -188,7 +190,7 @@
     int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
 			   unsigned char *buf, size_t destsize, size_t valsize,
 			   int shift, const yasm_bytecode *bc,
-			   int warn);
+			   int warn, unsigned long line);
 
     /** Module-level implementation of yasm_arch_get_reg_size().
      * Call yasm_arch_get_reg_size() instead of calling this function.
@@ -228,7 +230,7 @@
      */
     const char *default_machine_keyword;
 
-    /** Canonical "word" size in bits.
+    /** Canonical "word" size in bytes.
      * Call yasm_arch_wordsize() to get the word size of a particular
      * #yasm_arch.
      */
@@ -348,8 +350,10 @@
  * \param arch		architecture
  * \param cpuid		cpu identifier as in the input file
  * \param cpuid_len	length of cpu identifier string
+ * \param line		virtual line (from yasm_linemap)
  */
-void yasm_arch_parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
+void yasm_arch_parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+			 unsigned long line);
 
 /** Check an generic identifier to see if it matches architecture specific
  * names for instructions or instruction prefixes.  Unrecognized identifiers
@@ -361,11 +365,12 @@
  *			[output]
  * \param id		identifier as in the input file
  * \param id_len	length of id string
+ * \param line		virtual line (from yasm_linemap)
  * \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized)
  */
 yasm_arch_insnprefix yasm_arch_parse_check_insnprefix
     (yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
-     size_t id_len);
+     size_t id_len, unsigned long line);
 
 /** Check an generic identifier to see if it matches architecture specific
  * names for registers or target modifiers.  Unrecognized identifiers should
@@ -377,11 +382,12 @@
  *			[output]
  * \param id		identifier as in the input file
  * \param id_len	length of id string
+ * \param line		virtual line (from yasm_linemap)
  * \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized)
  */
 yasm_arch_regtmod yasm_arch_parse_check_regtmod
     (yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
-     size_t id_len);
+     size_t id_len, unsigned long line);
 
 /** Handle architecture-specific directives.
  * Should modify behavior ONLY of parse functions, much like parse_cpu().
@@ -442,11 +448,13 @@
  * \param valsize	size (in bits)
  * \param shift		left shift (in bits)
  * \param warn		enables standard overflow/underflow warnings
+ * \param line		virtual line; may be 0 if warn is 0.
  * \return Nonzero on error.
  */
 int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
 			       unsigned char *buf, size_t destsize,
-			       size_t valsize, size_t shift, int warn);
+			       size_t valsize, size_t shift, int warn,
+			       unsigned long line);
 
 /** Output #yasm_intnum to buffer.  Puts the value into the least
  * significant bits of the destination, or may be shifted into more
@@ -462,14 +470,16 @@
  * \param bc		bytecode being output ("parent" of value)
  * \param warn		enables standard warnings (value doesn't fit into
  *			valsize bits)
+ * \param line		virtual line; may be 0 if warn is 0
  * \return Nonzero on error.
  */
 int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
 			     unsigned char *buf, size_t destsize,
 			     size_t valsize, int shift,
-			     const yasm_bytecode *bc, int warn);
+			     const yasm_bytecode *bc, int warn,
+			     unsigned long line);
 
-/** Get the equivalent size of a register in bits.
+/** Get the equivalent byte size of a register.
  * \param arch	architecture
  * \param reg	register
  * \return 0 if there is no suitable equivalent size, otherwise the size.
@@ -534,14 +544,14 @@
     ((yasm_arch_base *)arch)->module->get_address_size(arch)
 #define yasm_arch_set_var(arch, var, val) \
     ((yasm_arch_base *)arch)->module->set_var(arch, var, val)
-#define yasm_arch_parse_cpu(arch, cpuid, cpuid_len) \
-    ((yasm_arch_base *)arch)->module->parse_cpu(arch, cpuid, cpuid_len)
-#define yasm_arch_parse_check_insnprefix(arch, data, id, id_len) \
+#define yasm_arch_parse_cpu(arch, cpuid, cpuid_len, line) \
+    ((yasm_arch_base *)arch)->module->parse_cpu(arch, cpuid, cpuid_len, line)
+#define yasm_arch_parse_check_insnprefix(arch, data, id, id_len, line) \
     ((yasm_arch_base *)arch)->module->parse_check_insnprefix(arch, data, id, \
-							     id_len)
-#define yasm_arch_parse_check_regtmod(arch, data, id, id_len) \
+							     id_len, line)
+#define yasm_arch_parse_check_regtmod(arch, data, id, id_len, line) \
     ((yasm_arch_base *)arch)->module->parse_check_regtmod(arch, data, id, \
-							  id_len)
+							  id_len, line)
 #define yasm_arch_parse_directive(arch, name, valparams, objext_valparams, \
 				  object, line) \
     ((yasm_arch_base *)arch)->module->parse_directive \
@@ -555,13 +565,13 @@
 	(arch, bc, prev_bc, data, num_operands, operands, num_prefixes, \
 	 prefixes, num_segregs, segregs)
 #define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \
-				   warn) \
+				   warn, line) \
     ((yasm_arch_base *)arch)->module->floatnum_tobytes \
-	(arch, flt, buf, destsize, valsize, shift, warn)
+	(arch, flt, buf, destsize, valsize, shift, warn, line)
 #define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \
-				 bc, warn) \
+				 bc, warn, line) \
     ((yasm_arch_base *)arch)->module->intnum_tobytes \
-	(arch, intn, buf, destsize, valsize, shift, bc, warn)
+	(arch, intn, buf, destsize, valsize, shift, bc, warn, line)
 #define yasm_arch_get_reg_size(arch, reg) \
     ((yasm_arch_base *)arch)->module->get_reg_size(arch, reg)
 #define yasm_arch_reggroup_get_reg(arch, regg, regi) \
diff --git a/libyasm/bc-align.c b/libyasm/bc-align.c
deleted file mode 100644
index ed2fab8..0000000
--- a/libyasm/bc-align.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Align bytecode
- *
- *  Copyright (C) 2005-2006  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 YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-
-#include "bytecode.h"
-
-#include "bc-int.h"
-
-
-typedef struct bytecode_align {
-    /*@only@*/ yasm_expr *boundary;	/* alignment boundary */
-
-    /* What to fill intervening locations with, NULL if using code_fill */
-    /*@only@*/ /*@null@*/ yasm_expr *fill;
-
-    /* Maximum number of bytes to skip, NULL if no maximum. */
-    /*@only@*/ /*@null@*/ yasm_expr *maxskip;
-
-    /* Code fill, NULL if using 0 fill */
-    /*@null@*/ const unsigned char **code_fill;
-} bytecode_align;
-
-static void bc_align_destroy(void *contents);
-static void bc_align_print(const void *contents, FILE *f, int indent_level);
-static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_align_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			    yasm_output_value_func output_value,
-			    /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_align_callback = {
-    bc_align_destroy,
-    bc_align_print,
-    bc_align_finalize,
-    bc_align_resolve,
-    bc_align_tobytes,
-    0
-};
-
-
-static void
-bc_align_destroy(void *contents)
-{
-    bytecode_align *align = (bytecode_align *)contents;
-    if (align->boundary)
-	yasm_expr_destroy(align->boundary);
-    if (align->fill)
-	yasm_expr_destroy(align->fill);
-    if (align->maxskip)
-	yasm_expr_destroy(align->maxskip);
-    yasm_xfree(contents);
-}
-
-static void
-bc_align_print(const void *contents, FILE *f, int indent_level)
-{
-    const bytecode_align *align = (const bytecode_align *)contents;
-    fprintf(f, "%*s_Align_\n", indent_level, "");
-    fprintf(f, "%*sBoundary=", indent_level, "");
-    yasm_expr_print(align->boundary, f);
-    fprintf(f, "\n%*sFill=", indent_level, "");
-    yasm_expr_print(align->fill, f);
-    fprintf(f, "\n%*sMax Skip=", indent_level, "");
-    yasm_expr_print(align->maxskip, f);
-    fprintf(f, "\n");
-}
-
-static void
-bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-    bytecode_align *align = (bytecode_align *)bc->contents;
-    if (!yasm_expr_get_intnum(&align->boundary, NULL))
-	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-		       N_("align boundary must be a constant"));
-    if (align->fill && !yasm_expr_get_intnum(&align->fill, NULL))
-	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-		       N_("align fill must be a constant"));
-    if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, NULL))
-	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-		       N_("align maximum skip must be a constant"));
-}
-
-static yasm_bc_resolve_flags
-bc_align_resolve(yasm_bytecode *bc, int save,
-		 yasm_calc_bc_dist_func calc_bc_dist)
-{
-    bytecode_align *align = (bytecode_align *)bc->contents;
-    unsigned long end;
-    unsigned long boundary =
-	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
-
-    if (boundary == 0) {
-	bc->len = 0;
-	return YASM_BC_RESOLVE_MIN_LEN;
-    }
-
-    end = bc->offset;
-    if (bc->offset & (boundary-1))
-	end = (bc->offset & ~(boundary-1)) + boundary;
-
-    bc->len = end - bc->offset;
-
-    if (align->maxskip) {
-	unsigned long maxskip =
-	    yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, NULL));
-	if ((end - bc->offset) > maxskip)
-	    bc->len = 0;
-    }
-    return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-static int
-bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-		 yasm_output_value_func output_value,
-		 /*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    bytecode_align *align = (bytecode_align *)bc->contents;
-    unsigned long len;
-    unsigned long boundary =
-	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
-
-    if (boundary == 0)
-	return 0;
-    else {
-	unsigned long end = bc->offset;
-	if (bc->offset & (boundary-1))
-	    end = (bc->offset & ~(boundary-1)) + boundary;
-	len = end - bc->offset;
-	if (len == 0)
-	    return 0;
-	if (align->maxskip) {
-	    unsigned long maxskip =
-		yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip,
-							  NULL));
-	    if (len > maxskip)
-		return 0;
-	}
-    }
-
-    if (align->fill) {
-	unsigned long v;
-	v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, NULL));
-	memset(*bufp, (int)v, len);
-	*bufp += len;
-    } else if (align->code_fill) {
-	unsigned long maxlen = 15;
-	while (!align->code_fill[maxlen] && maxlen>0)
-	    maxlen--;
-	if (maxlen == 0) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("could not find any code alignment size"));
-	    return 1;
-	}
-
-	/* Fill with maximum code fill as much as possible */
-	while (len > maxlen) {
-	    memcpy(*bufp, align->code_fill[maxlen], maxlen);
-	    *bufp += maxlen;
-	    len -= maxlen;
-	}
-
-	if (!align->code_fill[len]) {
-	    yasm_error_set(YASM_ERROR_VALUE,
-			   N_("invalid alignment size %d"), len);
-	    return 1;
-	}
-	/* Handle rest of code fill */
-	memcpy(*bufp, align->code_fill[len], len);
-	*bufp += len;
-    } else {
-	/* Just fill with 0 */
-	memset(*bufp, 0, len);
-	*bufp += len;
-    }
-    return 0;
-}
-
-yasm_bytecode *
-yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill,
-		     yasm_expr *maxskip, const unsigned char **code_fill,
-		     unsigned long line)
-{
-    bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align));
-
-    align->boundary = boundary;
-    align->fill = fill;
-    align->maxskip = maxskip;
-    align->code_fill = code_fill;
-
-    return yasm_bc_create_common(&bc_align_callback, align, line);
-}
diff --git a/libyasm/bc-data.c b/libyasm/bc-data.c
deleted file mode 100644
index 9c9dd82..0000000
--- a/libyasm/bc-data.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Data (and LEB128) bytecode
- *
- *  Copyright (C) 2001-2006  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 YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-#include "value.h"
-
-#include "bytecode.h"
-#include "arch.h"
-
-#include "bc-int.h"
-
-
-struct yasm_dataval {
-    /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;
-
-    enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128 } type;
-
-    union {
-	yasm_value val;
-	struct {
-	    /*@only@*/ unsigned char *contents;
-	    unsigned long len;
-	} raw;
-    } data;
-};
-
-typedef struct bytecode_data {
-    /* converted data (linked list) */
-    yasm_datavalhead datahead;
-} bytecode_data;
-
-static void bc_data_destroy(void *contents);
-static void bc_data_print(const void *contents, FILE *f, int indent_level);
-static void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_data_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			   yasm_output_value_func output_value,
-			   /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_data_callback = {
-    bc_data_destroy,
-    bc_data_print,
-    bc_data_finalize,
-    bc_data_resolve,
-    bc_data_tobytes,
-    0
-};
-
-
-static void
-bc_data_destroy(void *contents)
-{
-    bytecode_data *bc_data = (bytecode_data *)contents;
-    yasm_dvs_destroy(&bc_data->datahead);
-    yasm_xfree(contents);
-}
-
-static void
-bc_data_print(const void *contents, FILE *f, int indent_level)
-{
-    const bytecode_data *bc_data = (const bytecode_data *)contents;
-    fprintf(f, "%*s_Data_\n", indent_level, "");
-    fprintf(f, "%*sElements:\n", indent_level+1, "");
-    yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
-}
-
-static void
-bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-    bytecode_data *bc_data = (bytecode_data *)bc->contents;
-    yasm_dataval *dv;
-    yasm_intnum *intn;
-
-    /* Convert values from simple expr to value. */
-    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
-	switch (dv->type) {
-	    case DV_VALUE:
-		if (yasm_value_finalize(&dv->data.val)) {
-		    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				   N_("data expression too complex"));
-		    return;
-		}
-		break;
-	    case DV_ULEB128:
-	    case DV_SLEB128:
-		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
-		if (!intn) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-				   N_("LEB128 requires constant values"));
-		    return;
-		}
-		/* Warn for negative values in unsigned environment.
-		 * This could be an error instead: the likelihood this is
-		 * desired is very low!
-		 */
-		if (yasm_intnum_sign(intn) == -1 && dv->type == DV_ULEB128)
-		    yasm_warn_set(YASM_WARN_GENERAL,
-				  N_("negative value in unsigned LEB128"));
-		break;
-	    default:
-		break;
-	}
-    }
-}
-
-static yasm_bc_resolve_flags
-bc_data_resolve(yasm_bytecode *bc, int save,
-		yasm_calc_bc_dist_func calc_bc_dist)
-{
-    bytecode_data *bc_data = (bytecode_data *)bc->contents;
-    yasm_dataval *dv;
-    yasm_intnum *intn;
-
-    /* Count up element sizes, rounding up string length. */
-    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
-	switch (dv->type) {
-	    case DV_EMPTY:
-		break;
-	    case DV_VALUE:
-		bc->len += dv->data.val.size/8;
-		break;
-	    case DV_RAW:
-		bc->len += dv->data.raw.len;
-		break;
-	    case DV_ULEB128:
-	    case DV_SLEB128:
-		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
-		if (!intn)
-		    yasm_internal_error(N_("non-constant in data_tobytes"));
-		bc->len +=
-		    yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128);
-		break;
-	}
-    }
-
-    return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-static int
-bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-		yasm_output_value_func output_value,
-		/*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    bytecode_data *bc_data = (bytecode_data *)bc->contents;
-    yasm_dataval *dv;
-    unsigned char *bufp_orig = *bufp;
-    yasm_intnum *intn;
-    unsigned int val_len;
-
-    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
-	switch (dv->type) {
-	    case DV_EMPTY:
-		break;
-	    case DV_VALUE:
-		val_len = dv->data.val.size/8;
-		if (output_value(&dv->data.val, *bufp, val_len,
-				 (unsigned long)(*bufp-bufp_orig), bc, 1, d))
-		    return 1;
-		*bufp += val_len;
-		break;
-	    case DV_RAW:
-		memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len);
-		*bufp += dv->data.raw.len;
-		break;
-	    case DV_ULEB128:
-	    case DV_SLEB128:
-		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
-		if (!intn)
-		    yasm_internal_error(N_("non-constant in data_tobytes"));
-		*bufp +=
-		    yasm_intnum_get_leb128(intn, *bufp, dv->type == DV_SLEB128);
-	}
-    }
-
-    return 0;
-}
-
-yasm_bytecode *
-yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
-		    int append_zero, yasm_arch *arch, unsigned long line)
-{
-    bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data));
-    yasm_bytecode *bc = yasm_bc_create_common(&bc_data_callback, data, line);
-    yasm_dataval *dv, *dv2, *dvo;
-    yasm_intnum *intn;
-    unsigned long len = 0, rlen, i;
-
-
-    yasm_dvs_initialize(&data->datahead);
-
-    /* Prescan input data for length, etc.  Careful: this needs to be
-     * precisely paired with the second loop.
-     */
-    STAILQ_FOREACH(dv, datahead, link) {
-	switch (dv->type) {
-	    case DV_EMPTY:
-		break;
-	    case DV_VALUE:
-	    case DV_ULEB128:
-	    case DV_SLEB128:
-		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
-		if (intn && dv->type == DV_VALUE && (arch || size == 1))
-		    len += size;
-		else if (intn && dv->type == DV_ULEB128)
-		    len += yasm_intnum_size_leb128(intn, 0);
-		else if (intn && dv->type == DV_SLEB128)
-		    len += yasm_intnum_size_leb128(intn, 1);
-		else {
-		    if (len > 0) {
-			/* Create bytecode for all previous len */
-			dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
-			STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
-			len = 0;
-		    }
-
-		    /* Create bytecode for this value */
-		    dvo = yasm_xmalloc(sizeof(yasm_dataval));
-		    STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
-		}
-		break;
-	    case DV_RAW:
-		rlen = dv->data.raw.len;
-		/* find count, rounding up to nearest multiple of size */
-		rlen = (rlen + size - 1) / size;
-		len += rlen*size;
-		break;
-	}
-	if (append_zero)
-	    len++;
-    }
-
-    /* Create final dataval for any trailing length */
-    if (len > 0) {
-	dvo = yasm_dv_create_raw(yasm_xmalloc(len), len);
-	STAILQ_INSERT_TAIL(&data->datahead, dvo, link);
-    }
-
-    /* Second iteration: copy data and delete input datavals. */
-    dv = STAILQ_FIRST(datahead);
-    dvo = STAILQ_FIRST(&data->datahead);
-    len = 0;
-    while (dv && dvo) {
-	switch (dv->type) {
-	    case DV_EMPTY:
-		break;
-	    case DV_VALUE:
-	    case DV_ULEB128:
-	    case DV_SLEB128:
-		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
-		if (intn && dv->type == DV_VALUE && (arch || size == 1)) {
-		    if (size == 1)
-			yasm_intnum_get_sized(intn,
-					      &dvo->data.raw.contents[len],
-					      1, 8, 0, 0, 1);
-		    else
-			yasm_arch_intnum_tobytes(arch, intn,
-						 &dvo->data.raw.contents[len],
-						 size, size*8, 0, bc, 1);
-		    yasm_value_delete(&dv->data.val);
-		    len += size;
-		} else if (intn && dv->type == DV_ULEB128) {
-		    len += yasm_intnum_get_leb128(intn,
-						  &dvo->data.raw.contents[len],
-						  0);
-		} else if (intn && dv->type == DV_SLEB128) {
-		    len += yasm_intnum_get_leb128(intn,
-						  &dvo->data.raw.contents[len],
-						  1);
-		} else {
-		    dvo->type = dv->type;
-		    dvo->data.val = dv->data.val;   /* structure copy */
-		    dvo->data.val.size = size*8;    /* remember size */
-		    dvo = STAILQ_NEXT(dvo, link);
-		    len = 0;
-		}
-		break;
-	    case DV_RAW:
-		rlen = dv->data.raw.len;
-		memcpy(&dvo->data.raw.contents[len], dv->data.raw.contents,
-		       rlen);
-		yasm_xfree(dv->data.raw.contents);
-		len += rlen;
-		/* pad with 0's to nearest multiple of size */
-		rlen %= size;
-		if (rlen > 0) {
-		    rlen = size-rlen;
-		    for (i=0; i<rlen; i++)
-			dvo->data.raw.contents[len++] = 0;
-		}
-		break;
-	}
-	if (append_zero)
-	    dvo->data.raw.contents[len++] = 0;
-	dv2 = STAILQ_NEXT(dv, link);
-	yasm_xfree(dv);
-	dv = dv2;
-    }
-
-    return bc;
-}
-
-yasm_bytecode *
-yasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line)
-{
-    yasm_dataval *dv;
-
-    /* Convert all values into LEB type, error on strings/raws */
-    STAILQ_FOREACH(dv, datahead, link) {
-	switch (dv->type) {
-	    case DV_VALUE:
-		dv->type = sign ? DV_SLEB128 : DV_ULEB128;
-		break;
-	    case DV_RAW:
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("LEB128 does not allow string constants"));
-		break;
-	    default:
-		break;
-	}
-    }
-
-    return yasm_bc_create_data(datahead, 0, 0, 0, line);
-}
-
-yasm_dataval *
-yasm_dv_create_expr(yasm_expr *e)
-{
-    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
-
-    retval->type = DV_VALUE;
-    yasm_value_initialize(&retval->data.val, e, 0);
-
-    return retval;
-}
-
-yasm_dataval *
-yasm_dv_create_raw(unsigned char *contents, unsigned long len)
-{
-    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
-
-    retval->type = DV_RAW;
-    retval->data.raw.contents = contents;
-    retval->data.raw.len = len;
-
-    return retval;
-}
-
-void
-yasm_dvs_destroy(yasm_datavalhead *headp)
-{
-    yasm_dataval *cur, *next;
-
-    cur = STAILQ_FIRST(headp);
-    while (cur) {
-	next = STAILQ_NEXT(cur, link);
-	switch (cur->type) {
-	    case DV_VALUE:
-		yasm_value_delete(&cur->data.val);
-		break;
-	    case DV_RAW:
-		yasm_xfree(cur->data.raw.contents);
-		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(const yasm_datavalhead *head, FILE *f, int indent_level)
-{
-    yasm_dataval *cur;
-    unsigned long i;
-
-    STAILQ_FOREACH(cur, head, link) {
-	switch (cur->type) {
-	    case DV_EMPTY:
-		fprintf(f, "%*sEmpty\n", indent_level, "");
-		break;
-	    case DV_VALUE:
-		fprintf(f, "%*sValue:\n", indent_level, "");
-		yasm_value_print(&cur->data.val, f, indent_level+1);
-		break;
-	    case DV_RAW:
-		fprintf(f, "%*sLength=%lu\n", indent_level, "",
-			cur->data.raw.len);
-		fprintf(f, "%*sBytes=[", indent_level, "");
-		for (i=0; i<cur->data.raw.len; i++)
-		    fprintf(f, "0x%02x, ", cur->data.raw.contents[i]);
-		fprintf(f, "]\n");
-		break;
-	    case DV_ULEB128:
-		fprintf(f, "%*sULEB128 value:\n", indent_level, "");
-		yasm_value_print(&cur->data.val, f, indent_level+1);
-		break;
-	    case DV_SLEB128:
-		fprintf(f, "%*sSLEB128 value:\n", indent_level, "");
-		yasm_value_print(&cur->data.val, f, indent_level+1);
-		break;
-	}
-    }
-}
-
-/* Non-macro yasm_dvs_initialize() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_dvs_initialize
-void
-yasm_dvs_initialize(yasm_datavalhead *headp)
-{
-    STAILQ_INIT(headp);
-}
diff --git a/libyasm/bc-incbin.c b/libyasm/bc-incbin.c
deleted file mode 100644
index fd7f79e..0000000
--- a/libyasm/bc-incbin.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Incbin bytecode
- *
- *  Copyright (C) 2001-2006  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 YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-#include "value.h"
-
-#include "bytecode.h"
-
-#include "bc-int.h"
-
-
-typedef struct bytecode_incbin {
-    /*@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;
-
-static void bc_incbin_destroy(void *contents);
-static void bc_incbin_print(const void *contents, FILE *f, int indent_level);
-static void bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_incbin_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			     yasm_output_value_func output_value,
-			     /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_incbin_callback = {
-    bc_incbin_destroy,
-    bc_incbin_print,
-    bc_incbin_finalize,
-    bc_incbin_resolve,
-    bc_incbin_tobytes,
-    0
-};
-
-
-static void
-bc_incbin_destroy(void *contents)
-{
-    bytecode_incbin *incbin = (bytecode_incbin *)contents;
-    yasm_xfree(incbin->filename);
-    yasm_expr_destroy(incbin->start);
-    yasm_expr_destroy(incbin->maxlen);
-    yasm_xfree(contents);
-}
-
-static void
-bc_incbin_print(const void *contents, FILE *f, int indent_level)
-{
-    const bytecode_incbin *incbin = (const bytecode_incbin *)contents;
-    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(incbin->start, f);
-    fprintf(f, "%*sMax Len=", indent_level, "");
-    if (!incbin->maxlen)
-	fprintf(f, "nil (unlimited)");
-    else
-	yasm_expr_print(incbin->maxlen, f);
-    fprintf(f, "\n");
-}
-
-static void
-bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
-    yasm_value val;
-
-    if (yasm_value_finalize_expr(&val, incbin->start, 0))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("start expression too complex"));
-    else if (val.rel)
-	yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-		       N_("start expression not absolute"));
-    incbin->start = val.abs;
-
-    if (yasm_value_finalize_expr(&val, incbin->maxlen, 0))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("maximum length expression too complex"));
-    else if (val.rel)
-	yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-		       N_("maximum length expression not absolute"));
-    incbin->maxlen = val.abs;
-}
-
-static yasm_bc_resolve_flags
-bc_incbin_resolve(yasm_bytecode *bc, int save,
-		  yasm_calc_bc_dist_func calc_bc_dist)
-{
-    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
-    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_destroy(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_destroy(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_set(YASM_ERROR_IO,
-		       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_set(YASM_ERROR_IO,
-		       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_warn_set(YASM_WARN_GENERAL,
-		      N_("`incbin': start past end of file `%s'"),
-		      incbin->filename);
-	start = flen;
-    }
-    flen -= start;
-    if (incbin->maxlen)
-	if (maxlen < flen)
-	    flen = maxlen;
-    bc->len += flen;
-    return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-static int
-bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-		  yasm_output_value_func output_value,
-		  /*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
-    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_set(YASM_ERROR_IO, 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_set(YASM_ERROR_IO,
-		       N_("`incbin': unable to seek on file `%s'"),
-		       incbin->filename);
-	fclose(f);
-	return 1;
-    }
-
-    /* Read len bytes */
-    if (fread(*bufp, 1, (size_t)bc->len, f) < (size_t)bc->len) {
-	yasm_error_set(YASM_ERROR_IO,
-		       N_("`incbin': unable to read %lu bytes from file `%s'"),
-		       bc->len, incbin->filename);
-	fclose(f);
-	return 1;
-    }
-
-    *bufp += bc->len;
-    fclose(f);
-    return 0;
-}
-
-yasm_bytecode *
-yasm_bc_create_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
-		      unsigned long line)
-{
-    bytecode_incbin *incbin = yasm_xmalloc(sizeof(bytecode_incbin));
-
-    /*@-mustfree@*/
-    incbin->filename = filename;
-    incbin->start = start;
-    incbin->maxlen = maxlen;
-    /*@=mustfree@*/
-
-    return yasm_bc_create_common(&bc_incbin_callback, incbin, line);
-}
diff --git a/libyasm/bc-insn.c b/libyasm/bc-insn.c
deleted file mode 100644
index 48fb211..0000000
--- a/libyasm/bc-insn.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Insn bytecode
- *
- *  Copyright (C) 2005-2006  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 YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-
-#include "errwarn.h"
-#include "expr.h"
-#include "value.h"
-
-#include "bytecode.h"
-#include "arch.h"
-
-#include "bc-int.h"
-
-
-typedef struct bytecode_insn {
-    /*@dependent@*/ yasm_arch *arch;
-    unsigned long insn_data[4];
-
-    int num_operands;
-    /*@null@*/ yasm_insn_operands operands;
-
-    /* array of 4-element prefix_data arrays */
-    int num_prefixes;
-    /*@null@*/ unsigned long **prefixes;
-
-    /* array of segment prefixes */
-    int num_segregs;
-    /*@null@*/ unsigned long *segregs;
-} bytecode_insn;
-
-static void bc_insn_destroy(void *contents);
-static void bc_insn_print(const void *contents, FILE *f, int indent_level);
-static void bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_insn_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			   yasm_output_value_func output_value,
-			   /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_insn_callback = {
-    bc_insn_destroy,
-    bc_insn_print,
-    bc_insn_finalize,
-    bc_insn_resolve,
-    bc_insn_tobytes,
-    0
-};
-
-
-yasm_immval *
-yasm_imm_create_expr(yasm_expr *e)
-{
-    yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
-
-    if (yasm_value_finalize_expr(&im->val, e, 0))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("immediate expression too complex"));
-    im->sign = 0;
-
-    return im;
-}
-
-const yasm_expr *
-yasm_ea_get_disp(const yasm_effaddr *ea)
-{
-    return ea->disp.abs;
-}
-
-void
-yasm_ea_set_len(yasm_effaddr *ptr, unsigned int 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->disp.size = (unsigned char)len;
-}
-
-void
-yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned int nosplit)
-{
-    if (!ptr)
-	return;
-
-    ptr->nosplit = (unsigned char)nosplit;
-}
-
-void
-yasm_ea_set_strong(yasm_effaddr *ptr, unsigned int strong)
-{
-    if (!ptr)
-	return;
-
-    ptr->strong = (unsigned char)strong;
-}
-
-void
-yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg)
-{
-    if (!ea)
-	return;
-
-    if (segreg != 0 && ea->segreg != 0)
-	yasm_warn_set(YASM_WARN_GENERAL,
-		      N_("multiple segment overrides, using leftmost"));
-
-    ea->segreg = segreg;
-}
-
-/*@-nullstate@*/
-void
-yasm_ea_destroy(yasm_effaddr *ea)
-{
-    ea->callback->destroy(ea);
-    yasm_value_delete(&ea->disp);
-    yasm_xfree(ea);
-}
-/*@=nullstate@*/
-
-/*@-nullstate@*/
-void
-yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
-{
-    fprintf(f, "%*sDisp:\n", indent_level, "");
-    yasm_value_print(&ea->disp, f, indent_level+1);
-    fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
-    ea->callback->print(ea, f, indent_level);
-}
-/*@=nullstate@*/
-
-static void
-bc_insn_destroy(void *contents)
-{
-    bytecode_insn *insn = (bytecode_insn *)contents;
-    if (insn->num_operands > 0)
-	yasm_ops_delete(&insn->operands, 0);
-    if (insn->num_prefixes > 0) {
-	int i;
-	for (i=0; i<insn->num_prefixes; i++)
-	    yasm_xfree(insn->prefixes[i]);
-	yasm_xfree(insn->prefixes);
-    }
-    if (insn->num_segregs > 0)
-	yasm_xfree(insn->segregs);
-    yasm_xfree(contents);
-}
-
-static void
-bc_insn_print(const void *contents, FILE *f, int indent_level)
-{
-}
-
-static void
-bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-    bytecode_insn *insn = (bytecode_insn *)bc->contents;
-    int i;
-    yasm_insn_operand *op;
-    yasm_error_class eclass;
-    char *str, *xrefstr;
-    unsigned long xrefline;
-
-    /* Simplify the operands' expressions first. */
-    for (i = 0, op = yasm_ops_first(&insn->operands);
-	 op && i<insn->num_operands; op = yasm_operand_next(op), i++) {
-	/* Check operand type */
-	switch (op->type) {
-	    case YASM_INSN__OPERAND_MEMORY:
-		/* Don't get over-ambitious here; some archs' memory expr
-		 * parser are sensitive to the presence of *1, etc, so don't
-		 * simplify reg*1 identities.
-		 */
-		if (op->data.ea)
-		    op->data.ea->disp.abs =
-			yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
-					      NULL, NULL, NULL, NULL);
-		if (yasm_error_occurred()) {
-		    /* Add a pointer to where it was used to the error */
-		    yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
-		    if (xrefstr) {
-			yasm_error_set_xref(xrefline, "%s", xrefstr);
-			yasm_xfree(xrefstr);
-		    }
-		    if (str) {
-			yasm_error_set(eclass, "%s in memory expression", str);
-			yasm_xfree(str);
-		    }
-		    return;
-		}
-		break;
-	    case YASM_INSN__OPERAND_IMM:
-		op->data.val =
-		    yasm_expr__level_tree(op->data.val, 1, 1, 1, NULL, NULL,
-					  NULL, NULL);
-		if (yasm_error_occurred()) {
-		    /* Add a pointer to where it was used to the error */
-		    yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
-		    if (xrefstr) {
-			yasm_error_set_xref(xrefline, "%s", xrefstr);
-			yasm_xfree(xrefstr);
-		    }
-		    if (str) {
-			yasm_error_set(eclass, "%s in immediate expression",
-				       str);
-			yasm_xfree(str);
-		    }
-		    return;
-		}
-		break;
-	    default:
-		break;
-	}
-    }
-
-    yasm_arch_finalize_insn(insn->arch, bc, prev_bc, insn->insn_data,
-			    insn->num_operands, &insn->operands,
-			    insn->num_prefixes, insn->prefixes,
-			    insn->num_segregs, insn->segregs);
-}
-
-static yasm_bc_resolve_flags
-bc_insn_resolve(yasm_bytecode *bc, int save,
-		yasm_calc_bc_dist_func calc_bc_dist)
-{
-    yasm_internal_error(N_("bc_insn_resolve() is not implemented"));
-    /*@notreached@*/
-    return YASM_BC_RESOLVE_ERROR;
-}
-
-static int
-bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-		yasm_output_value_func output_value,
-		/*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    yasm_internal_error(N_("bc_insn_tobytes() is not implemented"));
-    /*@notreached@*/
-    return 1;
-}
-
-yasm_bytecode *
-yasm_bc_create_insn(yasm_arch *arch, const unsigned long insn_data[4],
-		    int num_operands, /*@null@*/ yasm_insn_operands *operands,
-		    unsigned long line)
-{
-    bytecode_insn *insn = yasm_xmalloc(sizeof(bytecode_insn));
-
-    insn->arch = arch;
-    insn->insn_data[0] = insn_data[0];
-    insn->insn_data[1] = insn_data[1];
-    insn->insn_data[2] = insn_data[2];
-    insn->insn_data[3] = insn_data[3];
-    insn->num_operands = num_operands;
-    if (operands)
-	insn->operands = *operands;	/* structure copy */
-    else
-	yasm_ops_initialize(&insn->operands);
-    insn->num_prefixes = 0;
-    insn->prefixes = NULL;
-    insn->num_segregs = 0;
-    insn->segregs = NULL;
-
-    return yasm_bc_create_common(&bc_insn_callback, insn, line);
-}
-
-yasm_bytecode *
-yasm_bc_create_empty_insn(yasm_arch *arch, unsigned long line)
-{
-    bytecode_insn *insn = yasm_xmalloc(sizeof(bytecode_insn));
-
-    insn->arch = arch;
-    insn->insn_data[0] = 0;
-    insn->insn_data[1] = 0;
-    insn->insn_data[2] = 0;
-    insn->insn_data[3] = 0;
-    insn->num_operands = 0;
-    yasm_ops_initialize(&insn->operands);
-    insn->num_prefixes = 0;
-    insn->prefixes = NULL;
-    insn->num_segregs = 0;
-    insn->segregs = NULL;
-
-    return yasm_bc_create_common(&bc_insn_callback, insn, line);
-}
-
-void
-yasm_bc_insn_add_prefix(yasm_bytecode *bc, const unsigned long prefix_data[4])
-{
-    bytecode_insn *insn = (bytecode_insn *)bc->contents;
-
-    assert(bc->callback == bc_insn_callback);
-
-    insn->prefixes =
-	yasm_xrealloc(insn->prefixes,
-		      (insn->num_prefixes+1)*sizeof(unsigned long *));
-    insn->prefixes[insn->num_prefixes] =
-	yasm_xmalloc(4*sizeof(unsigned long));
-    insn->prefixes[insn->num_prefixes][0] = prefix_data[0];
-    insn->prefixes[insn->num_prefixes][1] = prefix_data[1];
-    insn->prefixes[insn->num_prefixes][2] = prefix_data[2];
-    insn->prefixes[insn->num_prefixes][3] = prefix_data[3];
-    insn->num_prefixes++;
-}
-
-void
-yasm_bc_insn_add_seg_prefix(yasm_bytecode *bc, unsigned long segreg)
-{
-    bytecode_insn *insn = (bytecode_insn *)bc->contents;
-
-    assert(bc->callback == bc_insn_callback);
-
-    insn->segregs =
-	yasm_xrealloc(insn->segregs,
-		      (insn->num_segregs+1)*sizeof(unsigned long));
-    insn->segregs[insn->num_segregs] = segreg;
-    insn->num_segregs++;
-}
diff --git a/libyasm/bc-int.h b/libyasm/bc-int.h
index 5bb8635..ff0636b 100644
--- a/libyasm/bc-int.h
+++ b/libyasm/bc-int.h
@@ -36,7 +36,6 @@
     int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
 		    yasm_output_value_func output_value,
 		    /*@null@*/ yasm_output_reloc_func output_reloc);
-    int reserve;    /* Reserve space instead of outputting data */
 } yasm_bytecode_callback;
 
 struct yasm_bytecode {
diff --git a/libyasm/bc-org.c b/libyasm/bc-org.c
deleted file mode 100644
index 0d4da09..0000000
--- a/libyasm/bc-org.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * ORG bytecode
- *
- *  Copyright (C) 2005-2006  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 YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-#include "file.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-#include "value.h"
-
-#include "bytecode.h"
-
-#include "bc-int.h"
-
-
-typedef struct bytecode_org {
-    unsigned long start;	/* target starting offset within section */
-} bytecode_org;
-
-static void bc_org_destroy(void *contents);
-static void bc_org_print(const void *contents, FILE *f, int indent_level);
-static void bc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_org_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			  yasm_output_value_func output_value,
-			  /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_org_callback = {
-    bc_org_destroy,
-    bc_org_print,
-    bc_org_finalize,
-    bc_org_resolve,
-    bc_org_tobytes,
-    0
-};
-
-
-static void
-bc_org_destroy(void *contents)
-{
-    yasm_xfree(contents);
-}
-
-static void
-bc_org_print(const void *contents, FILE *f, int indent_level)
-{
-    const bytecode_org *org = (const bytecode_org *)contents;
-    fprintf(f, "%*s_Org_\n", indent_level, "");
-    fprintf(f, "%*sStart=%lu\n", indent_level, "", org->start);
-}
-
-static void
-bc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-}
-
-static yasm_bc_resolve_flags
-bc_org_resolve(yasm_bytecode *bc, int save,
-	       yasm_calc_bc_dist_func calc_bc_dist)
-{
-    bytecode_org *org = (bytecode_org *)bc->contents;
-
-    /* Check for overrun */
-    if (bc->offset > org->start) {
-	yasm_error_set(YASM_ERROR_GENERAL,
-		       N_("ORG overlap with already existing data"));
-	return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
-    }
-
-    /* Generate space to start offset */
-    bc->len = org->start - bc->offset;
-    return YASM_BC_RESOLVE_MIN_LEN;
-}
-
-static int
-bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-	       yasm_output_value_func output_value,
-	       /*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    bytecode_org *org = (bytecode_org *)bc->contents;
-    unsigned long len, i;
-
-    /* Sanity check for overrun */
-    if (bc->offset > org->start) {
-	yasm_error_set(YASM_ERROR_GENERAL,
-		       N_("ORG overlap with already existing data"));
-	return 1;
-    }
-    len = org->start - bc->offset;
-    for (i=0; i<len; i++)
-	YASM_WRITE_8(*bufp, 0);
-    return 0;
-}
-
-yasm_bytecode *
-yasm_bc_create_org(unsigned long start, unsigned long line)
-{
-    bytecode_org *org = yasm_xmalloc(sizeof(bytecode_org));
-
-    org->start = start;
-
-    return yasm_bc_create_common(&bc_org_callback, org, line);
-}
diff --git a/libyasm/bc-reserve.c b/libyasm/bc-reserve.c
deleted file mode 100644
index 9e1fa1a..0000000
--- a/libyasm/bc-reserve.c
+++ /dev/null
@@ -1,162 +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.
- */
-#define YASM_LIB_INTERNAL
-#include "util.h"
-/*@unused@*/ RCSID("$Id$");
-
-#include "coretype.h"
-
-#include "errwarn.h"
-#include "intnum.h"
-#include "expr.h"
-#include "value.h"
-
-#include "bytecode.h"
-
-#include "bc-int.h"
-#include "expr-int.h"
-
-
-typedef struct bytecode_reserve {
-    /*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
-    unsigned char itemsize;	    /* size of each item (in bytes) */
-} bytecode_reserve;
-
-static void bc_reserve_destroy(void *contents);
-static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
-static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
-static yasm_bc_resolve_flags bc_reserve_resolve
-    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
-static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-			      yasm_output_value_func output_value,
-			      /*@null@*/ yasm_output_reloc_func output_reloc);
-
-static const yasm_bytecode_callback bc_reserve_callback = {
-    bc_reserve_destroy,
-    bc_reserve_print,
-    bc_reserve_finalize,
-    bc_reserve_resolve,
-    bc_reserve_tobytes,
-    1
-};
-
-
-static void
-bc_reserve_destroy(void *contents)
-{
-    bytecode_reserve *reserve = (bytecode_reserve *)contents;
-    yasm_expr_destroy(reserve->numitems);
-    yasm_xfree(contents);
-}
-
-static void
-bc_reserve_print(const void *contents, FILE *f, int indent_level)
-{
-    const bytecode_reserve *reserve = (const bytecode_reserve *)contents;
-    fprintf(f, "%*s_Reserve_\n", indent_level, "");
-    fprintf(f, "%*sNum Items=", indent_level, "");
-    yasm_expr_print(reserve->numitems, f);
-    fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
-	    (unsigned int)reserve->itemsize);
-}
-
-static void
-bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-{
-    bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
-    yasm_value val;
-
-    if (yasm_value_finalize_expr(&val, reserve->numitems, 0))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("reserve expression too complex"));
-    else if (val.rel)
-	yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-		       N_("reserve expression not absolute"));
-    else if (val.abs && yasm_expr__contains(val.abs, YASM_EXPR_FLOAT))
-	yasm_error_set(YASM_ERROR_VALUE,
-		       N_("expression must not contain floating point value"));
-    reserve->numitems = val.abs;
-}
-
-static yasm_bc_resolve_flags
-bc_reserve_resolve(yasm_bytecode *bc, int save,
-		   yasm_calc_bc_dist_func calc_bc_dist)
-{
-    bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
-    yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
-    /*@null@*/ yasm_expr *temp;
-    yasm_expr **tempp;
-    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
-
-    if (!reserve->numitems)
-	return YASM_BC_RESOLVE_MIN_LEN;
-
-    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.
-	 */
-	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-		       N_("attempt to reserve non-constant quantity of space"));
-	retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
-    } else
-	bc->len += yasm_intnum_get_uint(num)*reserve->itemsize;
-    yasm_expr_destroy(temp);
-    return retval;
-}
-
-static int
-bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
-		   yasm_output_value_func output_value,
-		   /*@unused@*/ yasm_output_reloc_func output_reloc)
-{
-    yasm_internal_error(N_("bc_reserve_tobytes called"));
-    /*@notreached@*/
-    return 1;
-}
-
-yasm_bytecode *
-yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
-		       unsigned long line)
-{
-    bytecode_reserve *reserve = yasm_xmalloc(sizeof(bytecode_reserve));
-
-    /*@-mustfree@*/
-    reserve->numitems = numitems;
-    /*@=mustfree@*/
-    reserve->itemsize = (unsigned char)itemsize;
-
-    return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
-}
diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c
index 7138b3c..79f6a7c 100644
--- a/libyasm/bytecode.c
+++ b/libyasm/bytecode.c
@@ -29,6 +29,7 @@
 /*@unused@*/ RCSID("$Id$");
 
 #include "coretype.h"
+#include "file.h"
 
 #include "errwarn.h"
 #include "intnum.h"
@@ -37,11 +38,313 @@
 #include "symrec.h"
 
 #include "bytecode.h"
+#include "arch.h"
+#include "objfmt.h"
+#include "dbgfmt.h"
 
 #include "bc-int.h"
 #include "expr-int.h"
 
 
+struct yasm_dataval {
+    /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;
+
+    enum { DV_EMPTY, DV_VALUE, DV_STRING } type;
+
+    union {
+	yasm_value val;
+	struct {
+	    /*@only@*/ char *contents;
+	    size_t len;
+	} str;
+    } data;
+};
+
+/* Standard bytecode types */
+
+typedef struct bytecode_data {
+    /* non-converted data (linked list) */
+    yasm_datavalhead datahead;
+
+    /* final (converted) size of each element (in bytes) */
+    unsigned int size;
+
+    /* append a zero byte after each element? */
+    int append_zero;
+} bytecode_data;
+
+typedef struct bytecode_leb128 {
+    /* source data (linked list) */
+    yasm_datavalhead datahead;
+
+    /* signedness (0=unsigned, 1=signed) */
+    int sign;
+
+    /* total length (calculated at finalize time) */
+    unsigned long len;
+} bytecode_leb128;
+
+typedef struct bytecode_reserve {
+    /*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
+    unsigned char itemsize;	    /* size of each item (in bytes) */
+} bytecode_reserve;
+
+typedef struct bytecode_incbin {
+    /*@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 {
+    /*@only@*/ yasm_expr *boundary;	/* alignment boundary */
+
+    /* What to fill intervening locations with, NULL if using code_fill */
+    /*@only@*/ /*@null@*/ yasm_expr *fill;
+
+    /* Maximum number of bytes to skip, NULL if no maximum. */
+    /*@only@*/ /*@null@*/ yasm_expr *maxskip;
+
+    /* Code fill, NULL if using 0 fill */
+    /*@null@*/ const unsigned char **code_fill;
+} bytecode_align;
+
+typedef struct bytecode_org {
+    unsigned long start;	/* target starting offset within section */
+} bytecode_org;
+
+typedef struct bytecode_insn {
+    /*@dependent@*/ yasm_arch *arch;
+    unsigned long insn_data[4];
+
+    int num_operands;
+    /*@null@*/ yasm_insn_operands operands;
+
+    /* array of 4-element prefix_data arrays */
+    int num_prefixes;
+    /*@null@*/ unsigned long **prefixes;
+
+    /* array of segment prefixes */
+    int num_segregs;
+    /*@null@*/ unsigned long *segregs;
+} bytecode_insn;
+
+/* Standard bytecode callback function prototypes */
+
+static void bc_data_destroy(void *contents);
+static void bc_data_print(const void *contents, FILE *f, int indent_level);
+static void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_data_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			   yasm_output_value_func output_value,
+			   /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_leb128_destroy(void *contents);
+static void bc_leb128_print(const void *contents, FILE *f, int indent_level);
+static void bc_leb128_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_leb128_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_leb128_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			     yasm_output_value_func output_value,
+			     /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_reserve_destroy(void *contents);
+static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
+static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_reserve_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			      yasm_output_value_func output_value,
+			      /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_incbin_destroy(void *contents);
+static void bc_incbin_print(const void *contents, FILE *f, int indent_level);
+static void bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_incbin_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			     yasm_output_value_func output_value,
+			     /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_align_destroy(void *contents);
+static void bc_align_print(const void *contents, FILE *f, int indent_level);
+static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_align_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			    yasm_output_value_func output_value,
+			    /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_org_destroy(void *contents);
+static void bc_org_print(const void *contents, FILE *f, int indent_level);
+static void bc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_org_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			  yasm_output_value_func output_value,
+			  /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_insn_destroy(void *contents);
+static void bc_insn_print(const void *contents, FILE *f, int indent_level);
+static void bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
+static yasm_bc_resolve_flags bc_insn_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+			   yasm_output_value_func output_value,
+			   /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Standard bytecode callback structures */
+
+static const yasm_bytecode_callback bc_data_callback = {
+    bc_data_destroy,
+    bc_data_print,
+    bc_data_finalize,
+    bc_data_resolve,
+    bc_data_tobytes
+};
+
+static const yasm_bytecode_callback bc_leb128_callback = {
+    bc_leb128_destroy,
+    bc_leb128_print,
+    bc_leb128_finalize,
+    bc_leb128_resolve,
+    bc_leb128_tobytes
+};
+
+static const yasm_bytecode_callback bc_reserve_callback = {
+    bc_reserve_destroy,
+    bc_reserve_print,
+    bc_reserve_finalize,
+    bc_reserve_resolve,
+    bc_reserve_tobytes
+};
+
+static const yasm_bytecode_callback bc_incbin_callback = {
+    bc_incbin_destroy,
+    bc_incbin_print,
+    bc_incbin_finalize,
+    bc_incbin_resolve,
+    bc_incbin_tobytes
+};
+
+static const yasm_bytecode_callback bc_align_callback = {
+    bc_align_destroy,
+    bc_align_print,
+    bc_align_finalize,
+    bc_align_resolve,
+    bc_align_tobytes
+};
+
+static const yasm_bytecode_callback bc_org_callback = {
+    bc_org_destroy,
+    bc_org_print,
+    bc_org_finalize,
+    bc_org_resolve,
+    bc_org_tobytes
+};
+
+static const yasm_bytecode_callback bc_insn_callback = {
+    bc_insn_destroy,
+    bc_insn_print,
+    bc_insn_finalize,
+    bc_insn_resolve,
+    bc_insn_tobytes
+};
+
+/* Static structures for when NULL is passed to conversion functions. */
+/*  for Convert*ToBytes() */
+unsigned char bytes_static[16];
+
+
+yasm_immval *
+yasm_imm_create_expr(yasm_expr *e)
+{
+    yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
+
+    if (yasm_value_finalize_expr(&im->val, e))
+	yasm__error(e->line, N_("immediate expression too complex"));
+    im->len = 0;
+    im->sign = 0;
+
+    return im;
+}
+
+const yasm_expr *
+yasm_ea_get_disp(const yasm_effaddr *ea)
+{
+    return ea->disp.abs;
+}
+
+void
+yasm_ea_set_len(yasm_effaddr *ptr, unsigned int 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->disp_len = (unsigned char)len;
+}
+
+void
+yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned int nosplit)
+{
+    if (!ptr)
+	return;
+
+    ptr->nosplit = (unsigned char)nosplit;
+}
+
+void
+yasm_ea_set_strong(yasm_effaddr *ptr, unsigned int strong)
+{
+    if (!ptr)
+	return;
+
+    ptr->strong = (unsigned char)strong;
+}
+
+void
+yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg, unsigned long line)
+{
+    if (!ea)
+	return;
+
+    if (segreg != 0 && ea->segreg != 0)
+	yasm__warning(YASM_WARN_GENERAL, line,
+		      N_("multiple segment overrides, using leftmost"));
+
+    ea->segreg = segreg;
+}
+
+/*@-nullstate@*/
+void
+yasm_ea_destroy(yasm_effaddr *ea)
+{
+    ea->callback->destroy(ea);
+    yasm_value_delete(&ea->disp);
+    yasm_xfree(ea);
+}
+/*@=nullstate@*/
+
+/*@-nullstate@*/
+void
+yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
+{
+    fprintf(f, "%*sDisp:\n", indent_level, "");
+    yasm_value_print(&ea->disp, f, indent_level+1);
+    fprintf(f, "%*sLen=%u\n", indent_level, "", (unsigned int)ea->disp_len);
+    fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
+    ea->callback->print(ea, f, indent_level);
+}
+/*@=nullstate@*/
+
 void
 yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
 {
@@ -93,6 +396,900 @@
     return bc;
 }
 
+static void
+bc_data_destroy(void *contents)
+{
+    bytecode_data *bc_data = (bytecode_data *)contents;
+    yasm_dvs_destroy(&bc_data->datahead);
+    yasm_xfree(contents);
+}
+
+static void
+bc_data_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_data *bc_data = (const bytecode_data *)contents;
+    fprintf(f, "%*s_Data_\n", indent_level, "");
+    fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "", bc_data->size);
+    fprintf(f, "%*sAppend Zero=%i\n", indent_level+1, "", bc_data->append_zero);
+    fprintf(f, "%*sElements:\n", indent_level+1, "");
+    yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
+}
+
+static void
+bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_data *bc_data = (bytecode_data *)bc->contents;
+    yasm_dataval *dv;
+
+    /* Convert values from simple expr to value. */
+    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
+	if (dv->type == DV_VALUE) {
+	    if (yasm_value_finalize(&dv->data.val))
+		yasm__error(bc->line, N_("expression too complex"));
+	}
+    }
+}
+
+static yasm_bc_resolve_flags
+bc_data_resolve(yasm_bytecode *bc, int save,
+		yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_data *bc_data = (bytecode_data *)bc->contents;
+    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_VALUE:
+		bc->len += bc_data->size;
+		break;
+	    case DV_STRING:
+		slen = dv->data.str.len;
+		/* find count, rounding up to nearest multiple of size */
+		slen = (slen + bc_data->size - 1) / bc_data->size;
+		bc->len += slen*bc_data->size;
+		break;
+	}
+	if (bc_data->append_zero)
+	    bc->len++;
+    }
+
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		yasm_output_value_func output_value,
+		/*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_data *bc_data = (bytecode_data *)bc->contents;
+    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_VALUE:
+		if (output_value(&dv->data.val, *bufp, bc_data->size,
+				 (size_t)(bc_data->size*8), 0,
+				 (unsigned long)(*bufp-bufp_orig), bc, 1, d))
+		    return 1;
+		*bufp += bc_data->size;
+		break;
+	    case DV_STRING:
+		slen = dv->data.str.len;
+		memcpy(*bufp, dv->data.str.contents, 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;
+	}
+	if (bc_data->append_zero)
+	    YASM_WRITE_8(*bufp, 0);
+    }
+
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
+		    int append_zero, unsigned long line)
+{
+    bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data));
+
+    data->datahead = *datahead;
+    data->size = size;
+    data->append_zero = append_zero;
+
+    return yasm_bc_create_common(&bc_data_callback, data, line);
+}
+
+static void
+bc_leb128_destroy(void *contents)
+{
+    bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)contents;
+    yasm_dvs_destroy(&bc_leb128->datahead);
+    yasm_xfree(contents);
+}
+
+static void
+bc_leb128_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_leb128 *bc_leb128 = (const bytecode_leb128 *)contents;
+    fprintf(f, "%*s_Data_\n", indent_level, "");
+    fprintf(f, "%*sSign=%u\n", indent_level+1, "",
+	    (unsigned int)bc_leb128->sign);
+    fprintf(f, "%*sElements:\n", indent_level+1, "");
+    yasm_dvs_print(&bc_leb128->datahead, f, indent_level+2);
+}
+
+static void
+bc_leb128_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+    yasm_dataval *dv;
+    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+
+    /* Only constant expressions are allowed.
+     * Because of this, go ahead and calculate length.
+     */
+    bc_leb128->len = 0;
+    STAILQ_FOREACH(dv, &bc_leb128->datahead, link) {
+	switch (dv->type) {
+	    case DV_EMPTY:
+		break;
+	    case DV_VALUE:
+		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
+		if (!intn) {
+		    yasm__error(bc->line,
+				N_("LEB128 requires constant values"));
+		    return;
+		}
+		/* Warn for negative values in unsigned environment.
+		 * This could be an error instead: the likelihood this is
+		 * desired is very low!
+		 */
+		if (yasm_intnum_sign(intn) == -1 && !bc_leb128->sign)
+		    yasm__warning(YASM_WARN_GENERAL, bc->line,
+				  N_("negative value in unsigned LEB128"));
+		bc_leb128->len +=
+		    yasm_intnum_size_leb128(intn, bc_leb128->sign);
+		break;
+	    case DV_STRING:
+		yasm__error(bc->line,
+			    N_("LEB128 does not allow string constants"));
+		return;
+	}
+    }
+}
+
+static yasm_bc_resolve_flags
+bc_leb128_resolve(yasm_bytecode *bc, int save,
+		  yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+    bc->len += bc_leb128->len;
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_leb128_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		  yasm_output_value_func output_value,
+		  /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+    yasm_dataval *dv;
+    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+
+    STAILQ_FOREACH(dv, &bc_leb128->datahead, link) {
+	switch (dv->type) {
+	    case DV_EMPTY:
+		break;
+	    case DV_VALUE:
+		intn = yasm_expr_get_intnum(&dv->data.val.abs, NULL);
+		if (!intn)
+		    yasm_internal_error(N_("non-constant in leb128_tobytes"));
+		*bufp += yasm_intnum_get_leb128(intn, *bufp, bc_leb128->sign);
+		break;
+	    case DV_STRING:
+		yasm_internal_error(N_("string in leb128_tobytes"));
+	}
+    }
+
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line)
+{
+    bytecode_leb128 *leb128 = yasm_xmalloc(sizeof(bytecode_leb128));
+
+    leb128->datahead = *datahead;
+    leb128->sign = sign;
+
+    return yasm_bc_create_common(&bc_leb128_callback, leb128, line);
+}
+
+static void
+bc_reserve_destroy(void *contents)
+{
+    bytecode_reserve *reserve = (bytecode_reserve *)contents;
+    yasm_expr_destroy(reserve->numitems);
+    yasm_xfree(contents);
+}
+
+static void
+bc_reserve_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_reserve *reserve = (const bytecode_reserve *)contents;
+    fprintf(f, "%*s_Reserve_\n", indent_level, "");
+    fprintf(f, "%*sNum Items=", indent_level, "");
+    yasm_expr_print(reserve->numitems, f);
+    fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+	    (unsigned int)reserve->itemsize);
+}
+
+static void
+bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
+    yasm_value val;
+
+    if (yasm_value_finalize_expr(&val, reserve->numitems))
+	yasm__error(bc->line, N_("expression too complex"));
+    else if (val.rel)
+	yasm__error(bc->line, N_("reserve expression not absolute"));
+    else if (val.abs && yasm_expr__contains(val.abs, YASM_EXPR_FLOAT))
+	yasm__error(bc->line,
+		    N_("expression must not contain floating point value"));
+    reserve->numitems = val.abs;
+}
+
+static yasm_bc_resolve_flags
+bc_reserve_resolve(yasm_bytecode *bc, int save,
+		   yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
+    yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
+    /*@null@*/ yasm_expr *temp;
+    yasm_expr **tempp;
+    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
+
+    if (!reserve->numitems)
+	return YASM_BC_RESOLVE_MIN_LEN;
+
+    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.
+	 */
+	yasm__error(bc->line,
+		    N_("attempt to reserve non-constant quantity of space"));
+	retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
+    } else
+	bc->len += yasm_intnum_get_uint(num)*reserve->itemsize;
+    yasm_expr_destroy(temp);
+    return retval;
+}
+
+static int
+bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		   yasm_output_value_func output_value,
+		   /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    yasm_internal_error(N_("bc_reserve_tobytes called"));
+    /*@notreached@*/
+    return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
+		       unsigned long line)
+{
+    bytecode_reserve *reserve = yasm_xmalloc(sizeof(bytecode_reserve));
+
+    /*@-mustfree@*/
+    reserve->numitems = numitems;
+    /*@=mustfree@*/
+    reserve->itemsize = (unsigned char)itemsize;
+
+    return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
+}
+
+static void
+bc_incbin_destroy(void *contents)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)contents;
+    yasm_xfree(incbin->filename);
+    yasm_expr_destroy(incbin->start);
+    yasm_expr_destroy(incbin->maxlen);
+    yasm_xfree(contents);
+}
+
+static void
+bc_incbin_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_incbin *incbin = (const bytecode_incbin *)contents;
+    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(incbin->start, f);
+    fprintf(f, "%*sMax Len=", indent_level, "");
+    if (!incbin->maxlen)
+	fprintf(f, "nil (unlimited)");
+    else
+	yasm_expr_print(incbin->maxlen, f);
+    fprintf(f, "\n");
+}
+
+static void
+bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
+    yasm_value val;
+
+    if (yasm_value_finalize_expr(&val, incbin->start))
+	yasm__error(bc->line, N_("start expression too complex"));
+    else if (val.rel)
+	yasm__error(bc->line, N_("start expression not absolute"));
+    incbin->start = val.abs;
+
+    if (yasm_value_finalize_expr(&val, incbin->maxlen))
+	yasm__error(bc->line, N_("maximum length expression too complex"));
+    else if (val.rel)
+	yasm__error(bc->line, N_("maximum length expression not absolute"));
+    incbin->maxlen = val.abs;
+}
+
+static yasm_bc_resolve_flags
+bc_incbin_resolve(yasm_bytecode *bc, int save,
+		  yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
+    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_destroy(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_destroy(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(bc->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(bc->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, bc->line,
+		      N_("`incbin': start past end of file `%s'"),
+		      incbin->filename);
+	start = flen;
+    }
+    flen -= start;
+    if (incbin->maxlen)
+	if (maxlen < flen)
+	    flen = maxlen;
+    bc->len += flen;
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		  yasm_output_value_func output_value,
+		  /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
+    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(bc->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(bc->line, N_("`incbin': unable to seek on file `%s'"),
+		    incbin->filename);
+	fclose(f);
+	return 1;
+    }
+
+    /* Read len bytes */
+    if (fread(*bufp, 1, (size_t)bc->len, f) < (size_t)bc->len) {
+	yasm__error(bc->line,
+		    N_("`incbin': unable to read %lu bytes from file `%s'"),
+		    bc->len, incbin->filename);
+	fclose(f);
+	return 1;
+    }
+
+    *bufp += bc->len;
+    fclose(f);
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
+		      unsigned long line)
+{
+    bytecode_incbin *incbin = yasm_xmalloc(sizeof(bytecode_incbin));
+
+    /*@-mustfree@*/
+    incbin->filename = filename;
+    incbin->start = start;
+    incbin->maxlen = maxlen;
+    /*@=mustfree@*/
+
+    return yasm_bc_create_common(&bc_incbin_callback, incbin, line);
+}
+
+static void
+bc_align_destroy(void *contents)
+{
+    bytecode_align *align = (bytecode_align *)contents;
+    if (align->boundary)
+	yasm_expr_destroy(align->boundary);
+    if (align->fill)
+	yasm_expr_destroy(align->fill);
+    if (align->maxskip)
+	yasm_expr_destroy(align->maxskip);
+    yasm_xfree(contents);
+}
+
+static void
+bc_align_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_align *align = (const bytecode_align *)contents;
+    fprintf(f, "%*s_Align_\n", indent_level, "");
+    fprintf(f, "%*sBoundary=", indent_level, "");
+    yasm_expr_print(align->boundary, f);
+    fprintf(f, "\n%*sFill=", indent_level, "");
+    yasm_expr_print(align->fill, f);
+    fprintf(f, "\n%*sMax Skip=", indent_level, "");
+    yasm_expr_print(align->maxskip, f);
+    fprintf(f, "\n");
+}
+
+static void
+bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    if (!yasm_expr_get_intnum(&align->boundary, NULL))
+	yasm__error(bc->line, N_("align boundary must be a constant"));
+    if (align->fill && !yasm_expr_get_intnum(&align->fill, NULL))
+	yasm__error(bc->line, N_("align fill must be a constant"));
+    if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, NULL))
+	yasm__error(bc->line, N_("align maximum skip must be a constant"));
+}
+
+static yasm_bc_resolve_flags
+bc_align_resolve(yasm_bytecode *bc, int save,
+		 yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    unsigned long end;
+    unsigned long boundary =
+	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
+
+    if (boundary == 0) {
+	bc->len = 0;
+	return YASM_BC_RESOLVE_MIN_LEN;
+    }
+
+    end = bc->offset;
+    if (bc->offset & (boundary-1))
+	end = (bc->offset & ~(boundary-1)) + boundary;
+
+    bc->len = end - bc->offset;
+
+    if (align->maxskip) {
+	unsigned long maxskip =
+	    yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, NULL));
+	if ((end - bc->offset) > maxskip)
+	    bc->len = 0;
+    }
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		 yasm_output_value_func output_value,
+		 /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    unsigned long len;
+    unsigned long boundary =
+	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
+
+    if (boundary == 0)
+	return 0;
+    else {
+	unsigned long end = bc->offset;
+	if (bc->offset & (boundary-1))
+	    end = (bc->offset & ~(boundary-1)) + boundary;
+	len = end - bc->offset;
+	if (len == 0)
+	    return 0;
+	if (align->maxskip) {
+	    unsigned long maxskip =
+		yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip,
+							  NULL));
+	    if (len > maxskip)
+		return 0;
+	}
+    }
+
+    if (align->fill) {
+	unsigned long v;
+	v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, NULL));
+	memset(*bufp, (int)v, len);
+	*bufp += len;
+    } else if (align->code_fill) {
+	unsigned long maxlen = 15;
+	while (!align->code_fill[maxlen] && maxlen>0)
+	    maxlen--;
+	if (maxlen == 0) {
+	    yasm__error(bc->line, N_("could not find any code alignment size"));
+	    return 1;
+	}
+
+	/* Fill with maximum code fill as much as possible */
+	while (len > maxlen) {
+	    memcpy(*bufp, align->code_fill[maxlen], maxlen);
+	    *bufp += maxlen;
+	    len -= maxlen;
+	}
+
+	if (!align->code_fill[len]) {
+	    yasm__error(bc->line, N_("invalid alignment size %d"), len);
+	    return 1;
+	}
+	/* Handle rest of code fill */
+	memcpy(*bufp, align->code_fill[len], len);
+	*bufp += len;
+    } else {
+	/* Just fill with 0 */
+	memset(*bufp, 0, len);
+	*bufp += len;
+    }
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill,
+		     yasm_expr *maxskip, const unsigned char **code_fill,
+		     unsigned long line)
+{
+    bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align));
+
+    align->boundary = boundary;
+    align->fill = fill;
+    align->maxskip = maxskip;
+    align->code_fill = code_fill;
+
+    return yasm_bc_create_common(&bc_align_callback, align, line);
+}
+
+static void
+bc_org_destroy(void *contents)
+{
+    yasm_xfree(contents);
+}
+
+static void
+bc_org_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_org *org = (const bytecode_org *)contents;
+    fprintf(f, "%*s_Org_\n", indent_level, "");
+    fprintf(f, "%*sStart=%lu\n", indent_level, "", org->start);
+}
+
+static void
+bc_org_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+}
+
+static yasm_bc_resolve_flags
+bc_org_resolve(yasm_bytecode *bc, int save,
+	       yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_org *org = (bytecode_org *)bc->contents;
+
+    /* Check for overrun */
+    if (bc->offset > org->start) {
+	yasm__error(bc->line, N_("ORG overlap with already existing data"));
+	return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
+    }
+
+    /* Generate space to start offset */
+    bc->len = org->start - bc->offset;
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+	       yasm_output_value_func output_value,
+	       /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_org *org = (bytecode_org *)bc->contents;
+    unsigned long len, i;
+
+    /* Sanity check for overrun */
+    if (bc->offset > org->start) {
+	yasm__error(bc->line, N_("ORG overlap with already existing data"));
+	return 1;
+    }
+    len = org->start - bc->offset;
+    for (i=0; i<len; i++)
+	YASM_WRITE_8(*bufp, 0);
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_org(unsigned long start, unsigned long line)
+{
+    bytecode_org *org = yasm_xmalloc(sizeof(bytecode_org));
+
+    org->start = start;
+
+    return yasm_bc_create_common(&bc_org_callback, org, line);
+}
+
+static void
+bc_insn_destroy(void *contents)
+{
+    bytecode_insn *insn = (bytecode_insn *)contents;
+    if (insn->num_operands > 0)
+	yasm_ops_delete(&insn->operands, 0);
+    if (insn->num_prefixes > 0) {
+	int i;
+	for (i=0; i<insn->num_prefixes; i++)
+	    yasm_xfree(insn->prefixes[i]);
+	yasm_xfree(insn->prefixes);
+    }
+    if (insn->num_segregs > 0)
+	yasm_xfree(insn->segregs);
+    yasm_xfree(contents);
+}
+
+static void
+bc_insn_print(const void *contents, FILE *f, int indent_level)
+{
+}
+
+static void
+bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_insn *insn = (bytecode_insn *)bc->contents;
+    int i;
+    int error = 0;
+    yasm_insn_operand *op;
+
+    /* Simplify the operands' expressions first. */
+    for (i = 0, op = yasm_ops_first(&insn->operands);
+	 op && i<insn->num_operands; op = yasm_operand_next(op), i++) {
+	/* Check operand type */
+	switch (op->type) {
+	    case YASM_INSN__OPERAND_MEMORY:
+		/* Don't get over-ambitious here; some archs' memory expr
+		 * parser are sensitive to the presence of *1, etc, so don't
+		 * simplify reg*1 identities.
+		 */
+		if (op->data.ea)
+		    op->data.ea->disp.abs =
+			yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
+					      NULL, NULL, NULL, NULL, &error);
+		if (error) {
+		    /* Follow up error with a pointer to where it was used */
+		    yasm__error(bc->line, N_("(used in memory expression)"));
+		    return;
+		}
+		break;
+	    case YASM_INSN__OPERAND_IMM:
+		op->data.val =
+		    yasm_expr__level_tree(op->data.val, 1, 1, 1, NULL, NULL,
+					  NULL, NULL, &error);
+		if (error) {
+		    /* Follow up error with a pointer to where it was used */
+		    yasm__error(bc->line,
+				N_("(used in immediate expression)"));
+		    return;
+		}
+		break;
+	    default:
+		break;
+	}
+    }
+
+    yasm_arch_finalize_insn(insn->arch, bc, prev_bc, insn->insn_data,
+			    insn->num_operands, &insn->operands,
+			    insn->num_prefixes, insn->prefixes,
+			    insn->num_segregs, insn->segregs);
+}
+
+static yasm_bc_resolve_flags
+bc_insn_resolve(yasm_bytecode *bc, int save,
+		yasm_calc_bc_dist_func calc_bc_dist)
+{
+    yasm_internal_error(N_("bc_insn_resolve() is not implemented"));
+    /*@notreached@*/
+    return YASM_BC_RESOLVE_ERROR;
+}
+
+static int
+bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+		yasm_output_value_func output_value,
+		/*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    yasm_internal_error(N_("bc_insn_tobytes() is not implemented"));
+    /*@notreached@*/
+    return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_insn(yasm_arch *arch, const unsigned long insn_data[4],
+		    int num_operands, /*@null@*/ yasm_insn_operands *operands,
+		    unsigned long line)
+{
+    bytecode_insn *insn = yasm_xmalloc(sizeof(bytecode_insn));
+
+    insn->arch = arch;
+    insn->insn_data[0] = insn_data[0];
+    insn->insn_data[1] = insn_data[1];
+    insn->insn_data[2] = insn_data[2];
+    insn->insn_data[3] = insn_data[3];
+    insn->num_operands = num_operands;
+    if (operands)
+	insn->operands = *operands;	/* structure copy */
+    else
+	yasm_ops_initialize(&insn->operands);
+    insn->num_prefixes = 0;
+    insn->prefixes = NULL;
+    insn->num_segregs = 0;
+    insn->segregs = NULL;
+
+    return yasm_bc_create_common(&bc_insn_callback, insn, line);
+}
+
+yasm_bytecode *
+yasm_bc_create_empty_insn(yasm_arch *arch, unsigned long line)
+{
+    bytecode_insn *insn = yasm_xmalloc(sizeof(bytecode_insn));
+
+    insn->arch = arch;
+    insn->insn_data[0] = 0;
+    insn->insn_data[1] = 0;
+    insn->insn_data[2] = 0;
+    insn->insn_data[3] = 0;
+    insn->num_operands = 0;
+    yasm_ops_initialize(&insn->operands);
+    insn->num_prefixes = 0;
+    insn->prefixes = NULL;
+    insn->num_segregs = 0;
+    insn->segregs = NULL;
+
+    return yasm_bc_create_common(&bc_insn_callback, insn, line);
+}
+
+void
+yasm_bc_insn_add_prefix(yasm_bytecode *bc, const unsigned long prefix_data[4])
+{
+    bytecode_insn *insn = (bytecode_insn *)bc->contents;
+
+    assert(bc->callback == bc_insn_callback);
+
+    insn->prefixes =
+	yasm_xrealloc(insn->prefixes,
+		      (insn->num_prefixes+1)*sizeof(unsigned long *));
+    insn->prefixes[insn->num_prefixes] =
+	yasm_xmalloc(4*sizeof(unsigned long));
+    insn->prefixes[insn->num_prefixes][0] = prefix_data[0];
+    insn->prefixes[insn->num_prefixes][1] = prefix_data[1];
+    insn->prefixes[insn->num_prefixes][2] = prefix_data[2];
+    insn->prefixes[insn->num_prefixes][3] = prefix_data[3];
+    insn->num_prefixes++;
+}
+
+void
+yasm_bc_insn_add_seg_prefix(yasm_bytecode *bc, unsigned long segreg)
+{
+    bytecode_insn *insn = (bytecode_insn *)bc->contents;
+
+    assert(bc->callback == bc_insn_callback);
+
+    insn->segregs =
+	yasm_xrealloc(insn->segregs,
+		      (insn->num_segregs+1)*sizeof(unsigned long));
+    insn->segregs[insn->num_segregs] = segreg;
+    insn->num_segregs++;
+}
+
 yasm_section *
 yasm_bc_get_section(yasm_bytecode *bc)
 {
@@ -159,12 +1356,10 @@
     if (bc->multiple) {
 	yasm_value val;
 
-	if (yasm_value_finalize_expr(&val, bc->multiple, 0))
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("multiple expression too complex"));
+	if (yasm_value_finalize_expr(&val, bc->multiple))
+	    yasm__error(bc->line, N_("multiple expression too complex"));
 	else if (val.rel)
-	    yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-			   N_("multiple expression not absolute"));
+	    yasm__error(bc->line, N_("multiple expression not absolute"));
 	bc->multiple = val.abs;
     }
 }
@@ -181,7 +1376,7 @@
     dist = precbc2->offset + precbc2->len;
     if (dist < precbc1->offset + precbc1->len) {
 	intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len - dist);
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
 	return intn;
     }
     dist -= precbc1->offset + precbc1->len;
@@ -218,7 +1413,7 @@
 	if (!num) {
 	    retval = YASM_BC_RESOLVE_UNKNOWN_LEN;
 	    if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT)) {
-		yasm_error_set(YASM_ERROR_VALUE,
+		yasm__error(bc->line,
 		    N_("expression must not contain floating point value"));
 		retval |= YASM_BC_RESOLVE_ERROR;
 	    }
@@ -256,7 +1451,7 @@
     }
 
     /* special case for reserve bytecodes */
-    if (bc->callback->reserve) {
+    if (bc->callback == &bc_reserve_callback) {
 	*bufsize = bc->len;
 	*gap = 1;
 	return NULL;	/* we didn't allocate a buffer */
@@ -297,15 +1492,103 @@
     if (bc->multiple) {
 	num = yasm_expr_get_intnum(&bc->multiple, calc_bc_dist);
 	if (!num) {
-	    yasm_error_set(YASM_ERROR_VALUE,
-			   N_("could not determine multiple"));
+	    yasm__error(bc->line, N_("could not determine multiple"));
 	    return 1;
 	}
 	if (yasm_intnum_sign(num) < 0) {
-	    yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
+	    yasm__error(bc->line, N_("multiple is negative"));
 	    return 1;
 	}
 	*multiple = yasm_intnum_get_uint(num);
     }
     return 0;
 }
+
+yasm_dataval *
+yasm_dv_create_expr(yasm_expr *e)
+{
+    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
+
+    retval->type = DV_VALUE;
+    yasm_value_initialize(&retval->data.val, e);
+
+    return retval;
+}
+
+yasm_dataval *
+yasm_dv_create_string(char *contents, size_t len)
+{
+    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
+
+    retval->type = DV_STRING;
+    retval->data.str.contents = contents;
+    retval->data.str.len = len;
+
+    return retval;
+}
+
+void
+yasm_dvs_destroy(yasm_datavalhead *headp)
+{
+    yasm_dataval *cur, *next;
+
+    cur = STAILQ_FIRST(headp);
+    while (cur) {
+	next = STAILQ_NEXT(cur, link);
+	switch (cur->type) {
+	    case DV_VALUE:
+		yasm_value_delete(&cur->data.val);
+		break;
+	    case DV_STRING:
+		yasm_xfree(cur->data.str.contents);
+		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(const yasm_datavalhead *head, FILE *f, int indent_level)
+{
+    yasm_dataval *cur;
+
+    STAILQ_FOREACH(cur, head, link) {
+	switch (cur->type) {
+	    case DV_EMPTY:
+		fprintf(f, "%*sEmpty\n", indent_level, "");
+		break;
+	    case DV_VALUE:
+		fprintf(f, "%*sValue:\n", indent_level, "");
+		yasm_value_print(&cur->data.val, f, indent_level+1);
+		break;
+	    case DV_STRING:
+		fprintf(f, "%*sLength=%lu\n", indent_level, "",
+			(unsigned long)cur->data.str.len);
+		fprintf(f, "%*sString=\"%s\"\n", indent_level, "",
+			cur->data.str.contents);
+		break;
+	}
+    }
+}
+
+/* Non-macro yasm_dvs_initialize() for non-YASM_LIB_INTERNAL users. */
+#undef yasm_dvs_initialize
+void
+yasm_dvs_initialize(yasm_datavalhead *headp)
+{
+    STAILQ_INIT(headp);
+}
diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h
index 621bd05..c69daa0 100644
--- a/libyasm/bytecode.h
+++ b/libyasm/bytecode.h
@@ -60,7 +60,9 @@
 
     unsigned long segreg;	/**< segment register override (0 if none) */
 
-    unsigned char need_nonzero_len; /**< 1 if length of disp must be >0. */
+    unsigned char disp_len;	/**< length of disp (in bytes), 0 if unknown,
+				 *   0xff if unknown and required to be >0.
+				 */
     unsigned char need_disp;	/**< 1 if a displacement should be present
 				 *   in the output.
 				 */
@@ -77,6 +79,7 @@
 typedef struct yasm_immval {
     yasm_value val;		/**< the immediate value itself */
 
+    unsigned char len;		/**< final length (in bytes), 0 if unknown */
     unsigned char sign;		/**< 1 if final imm is treated as signed */
 } yasm_immval;
 
@@ -110,9 +113,9 @@
 /*@observer@*/ const yasm_expr *yasm_ea_get_disp(const yasm_effaddr *ea);
 
 /** Set the length of the displacement portion of an effective address.
- * The length is specified in bits.
+ * The length is specified in bytes.
  * \param ea	effective address
- * \param len	length in bits
+ * \param len	length in bytes
  */
 void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len);
 
@@ -141,8 +144,10 @@
  * addresses.  A override of an override will result in a warning.
  * \param ea		effective address
  * \param segreg	segment register (0 if none)
+ * \param line		virtual line number
  */
-void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg);
+void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg,
+			unsigned long line);
 
 /** Delete (free allocated memory for) an effective address.
  * \param ea	effective address (only pointer to it).
@@ -169,14 +174,12 @@
  * \param size		storage size (in bytes) for each data value
  * \param append_zero	append a single zero byte after each data value
  *			(if non-zero)
- * \param arch		architecture (optional); if provided, data items
- *			are directly simplified to bytes if possible
  * \param line		virtual line (from yasm_linemap)
  * \return Newly allocated bytecode.
  */
 /*@only@*/ yasm_bytecode *yasm_bc_create_data
     (yasm_datavalhead *datahead, unsigned int size, int append_zero,
-     /*@null@*/ yasm_arch *arch, unsigned long line);
+     unsigned long line);
 
 /** Create a bytecode containing LEB128-encoded data value(s).
  * \param datahead	list of data values (kept, do not free)
@@ -364,7 +367,7 @@
  * \param bc		bytecode
  * \param multiple	multiple value (output)
  * \param calc_bc_dist	bytecode distance calculation function (optional)
- * \return 1 on error (set with yasm_error_set), 0 on success.
+ * \return 1 on error (set with yasm__error), 0 on success.
  */
 int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ unsigned long *multiple,
 			 /*@null@*/ yasm_calc_bc_dist_func calc_bc_dist);
@@ -376,25 +379,12 @@
 yasm_dataval *yasm_dv_create_expr(/*@keep@*/ yasm_expr *expn);
 
 /** Create a new data value from a string.
- * \param contents	string (may contain NULs)
+ * \param contents	string (raw, may contain NULs)
  * \param len		length of string
  * \return Newly allocated data value.
  */
 yasm_dataval *yasm_dv_create_string(/*@keep@*/ char *contents, size_t len);
 
-/** Create a new data value from raw bytes data.
- * \param contents	raw data (may contain NULs)
- * \param len		length
- * \return Newly allocated data value.
- */
-yasm_dataval *yasm_dv_create_raw(/*@keep@*/ unsigned char *contents,
-				 unsigned long len);
-
-#ifndef YASM_DOXYGEN
-#define yasm_dv_create_string(s, l) yasm_dv_create_raw((unsigned char *)(s), \
-						       (unsigned long)(l))
-#endif
-
 /** Initialize a list of data values.
  * \param headp	list of data values
  */
diff --git a/libyasm/coretype.h b/libyasm/coretype.h
index 89e5ed3..14ebc43 100644
--- a/libyasm/coretype.h
+++ b/libyasm/coretype.h
@@ -66,11 +66,6 @@
     void (*print) (void *data, FILE *f, int indent_level);
 } yasm_assoc_data_callback;
 
-/** Set of collected error/warnings (opaque type).
- * \see errwarn.h for details.
- */
-typedef struct yasm_errwarns yasm_errwarns;
-
 /** Bytecode (opaque type).
  * \see bytecode.h for related functions.
  * Define YASM_BC_INTERNAL to get visible internals.
@@ -152,9 +147,6 @@
      * section start.  Boolean.
      */
     unsigned int section_rel : 1;
-
-    /** Size of the value, in bits. */
-    unsigned int size : 8;
 } yasm_value;
 
 /** Maximum value of #yasm_value.rshift */
@@ -195,16 +187,12 @@
     YASM_EXPR_OR,	/**< Bitwise OR. */
     YASM_EXPR_AND,	/**< Bitwise AND. */
     YASM_EXPR_XOR,	/**< Bitwise XOR. */
-    YASM_EXPR_XNOR,	/**< Bitwise XNOR. */
     YASM_EXPR_NOR,	/**< Bitwise NOR. */
     YASM_EXPR_SHL,	/**< Shift left (logical). */
     YASM_EXPR_SHR,	/**< Shift right (logical). */
     YASM_EXPR_LOR,	/**< Logical OR. */
     YASM_EXPR_LAND,	/**< Logical AND. */
     YASM_EXPR_LNOT,	/**< Logical negation. */
-    YASM_EXPR_LXOR,	/**< Logical XOR. */
-    YASM_EXPR_LXNOR,	/**< Logical XNOR. */
-    YASM_EXPR_LNOR,	/**< Logical NOR. */
     YASM_EXPR_LT,	/**< Less than comparison. */
     YASM_EXPR_GT,	/**< Greater than comparison. */
     YASM_EXPR_EQ,	/**< Equality comparison. */
@@ -247,6 +235,9 @@
  * \param value		value
  * \param buf		buffer for byte representation
  * \param destsize	destination size (in bytes)
+ * \param valsize	size (in bits)
+ * \param shift		left shift (in bits); may be negative to specify right
+ *			shift (standard warnings include truncation to boundary)
  * \param offset	offset (in bytes) of the expr contents from the start
  *			of the bytecode (needed for relative)
  * \param bc		current bytecode (usually passed into higher-level
@@ -261,7 +252,8 @@
  */
 typedef int (*yasm_output_value_func)
     (yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
-     unsigned long offset, yasm_bytecode *bc, int warn, /*@null@*/ void *d);
+     size_t valsize, int shift, unsigned long offset, yasm_bytecode *bc,
+     int warn, /*@null@*/ void *d) /*@uses *ep@*/;
 
 /** Convert a symbol reference to its byte representation.  Usually implemented
  * by object formats and debug formats to keep track of relocations generated
diff --git a/libyasm/dbgfmt.h b/libyasm/dbgfmt.h
index 8f767f7..323b538 100644
--- a/libyasm/dbgfmt.h
+++ b/libyasm/dbgfmt.h
@@ -78,7 +78,7 @@
     /** Module-level implementation of yasm_dbgfmt_generate().
      * Call yasm_dbgfmt_generate() instead of calling this function.
      */
-    void (*generate) (yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns);
+    void (*generate) (yasm_dbgfmt *dbgfmt);
 } yasm_dbgfmt_module;
 
 /** Get the keyword used to select a debug format.
@@ -120,10 +120,8 @@
 
 /** Generate debugging information bytecodes.
  * \param dbgfmt	debug format
- * \param errwarns	error/warning set
- * \note Errors and warnings are stored into errwarns.
  */
-void yasm_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns);
+void yasm_dbgfmt_generate(yasm_dbgfmt *dbgfmt);
 
 #ifndef YASM_DOXYGEN
 
@@ -140,8 +138,8 @@
 #define yasm_dbgfmt_directive(dbgfmt, name, sect, valparams, line) \
     ((yasm_dbgfmt_base *)dbgfmt)->module->directive(dbgfmt, name, sect, \
 						    valparams, line)
-#define yasm_dbgfmt_generate(dbgfmt, ews) \
-    ((yasm_dbgfmt_base *)dbgfmt)->module->generate(dbgfmt, ews)
+#define yasm_dbgfmt_generate(dbgfmt) \
+    ((yasm_dbgfmt_base *)dbgfmt)->module->generate(dbgfmt)
 
 #endif
 
diff --git a/libyasm/errwarn.c b/libyasm/errwarn.c
index b1f94a0..e8c3790 100644
--- a/libyasm/errwarn.c
+++ b/libyasm/errwarn.c
@@ -55,48 +55,34 @@
 /*@exits@*/ void (*yasm_fatal) (const char *message, va_list va) = def_fatal;
 const char * (*yasm_gettext_hook) (const char *msgid) = def_gettext_hook;
 
-/* Error indicator */
-/* yasm_eclass is not static so that yasm_error_occurred macro can access it */
-yasm_error_class yasm_eclass;
-static /*@only@*/ /*@null@*/ char *yasm_estr;
-static unsigned long yasm_exrefline;
-static /*@only@*/ /*@null@*/ char *yasm_exrefstr;
-
-/* Warning indicator */
-typedef struct warn {
-    /*@reldef@*/ STAILQ_ENTRY(warn) link;
-
-    yasm_warn_class wclass;
-    /*@owned@*/ /*@null@*/ char *wstr;
-} warn;
-static STAILQ_HEAD(, warn) yasm_warns;
-
 /* 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;
-    unsigned long xrefline;
-    /*@owned@*/ char *msg;
-    /*@owned@*/ char *xrefmsg;
+    unsigned long displine;
+
+    /* FIXME: This should not be a fixed size.  But we don't have vasprintf()
+     * right now. */
+    char msg[MSG_MAXSIZE];
 } errwarn_data;
 
-struct yasm_errwarns {
-    /*@reldef@*/ SLIST_HEAD(, errwarn_data) errwarns;
-
-    /* Total error count */
-    unsigned int ecount;
-
-    /* Total warning count */
-    unsigned int wcount;
-
-    /* Last inserted error/warning.  Used to speed up insertions. */
-    /*@null@*/ errwarn_data *previous_we;
-};
+/* 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];
@@ -117,19 +103,24 @@
 	(1UL<<YASM_WARN_PREPROC) | (0UL<<YASM_WARN_ORPHAN_LABEL) |
 	(1UL<<YASM_WARN_UNINIT_CONTENTS);
 
-    yasm_eclass = YASM_ERROR_NONE;
-    yasm_estr = NULL;
-    yasm_exrefline = 0;
-    yasm_exrefstr = NULL;
-
-    STAILQ_INIT(&yasm_warns);
+    error_count = 0;
+    warning_count = 0;
+    SLIST_INIT(&errwarns);
+    previous_we = NULL;
 }
 
 void
 yasm_errwarn_cleanup(void)
 {
-    yasm_error_clear();
-    yasm_warn_clear();
+    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
@@ -188,7 +179,7 @@
  * type is WE_PARSERERROR.
  */
 static errwarn_data *
-errwarn_data_new(yasm_errwarns *errwarns, unsigned long line,
+errwarn_data_new(unsigned long line, unsigned long displine,
 		 int replace_parser_error)
 {
     errwarn_data *first, *next, *ins_we, *we;
@@ -197,8 +188,8 @@
     /* Find the entry with either line=line or the last one with line<line.
      * Start with the last entry added to speed the search.
      */
-    ins_we = errwarns->previous_we;
-    first = SLIST_FIRST(&errwarns->errwarns);
+    ins_we = previous_we;
+    first = SLIST_FIRST(&errwarns);
     if (!ins_we || !first)
 	action = INS_HEAD;
     while (action == INS_NONE) {
@@ -225,12 +216,10 @@
 
 	we->type = WE_UNKNOWN;
 	we->line = line;
-	we->xrefline = 0;
-	we->msg = NULL;
-	we->xrefmsg = NULL;
+	we->displine = displine;
 
 	if (action == INS_HEAD)
-	    SLIST_INSERT_HEAD(&errwarns->errwarns, we, link);
+	    SLIST_INSERT_HEAD(&errwarns, we, link);
 	else if (action == INS_AFTER) {
 	    assert(ins_we != NULL);
 	    SLIST_INSERT_AFTER(ins_we, we, link);
@@ -239,149 +228,114 @@
     }
 
     /* Remember previous err/warn */
-    errwarns->previous_we = we;
+    previous_we = we;
 
     return we;
 }
 
+/* Register an error at line line, displaying line displine.  Does not print
+ * the error, only stores it for output_all() to print.
+ */
 void
-yasm_error_clear(void)
+yasm__error_va_at(unsigned long line, unsigned long displine, const char *fmt,
+		  va_list va)
 {
-    if (yasm_estr)
-	yasm_xfree(yasm_estr);
-    if (yasm_exrefstr)
-	yasm_xfree(yasm_exrefstr);
-    yasm_eclass = YASM_ERROR_NONE;
-    yasm_estr = NULL;
-    yasm_exrefline = 0;
-    yasm_exrefstr = NULL;
-}
+    errwarn_data *we = errwarn_data_new(line, displine, 1);
 
-int
-yasm_error_matches(yasm_error_class eclass)
-{
-    if (yasm_eclass == YASM_ERROR_NONE)
-	return eclass == YASM_ERROR_NONE;
-    if (yasm_eclass == YASM_ERROR_GENERAL)
-	return eclass == YASM_ERROR_GENERAL;
-    return (yasm_eclass & eclass) == eclass;
-}
+    we->type = WE_ERROR;
 
-void
-yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va)
-{
-    if (yasm_eclass != YASM_ERROR_NONE)
-	return;
-
-    yasm_eclass = eclass;
-    yasm_estr = yasm_xmalloc(MSG_MAXSIZE+1);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(yasm_estr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
+    vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
 #else
-    vsprintf(yasm_estr, yasm_gettext_hook(format), va);
+    vsprintf(we->msg, yasm_gettext_hook(fmt), va);
 #endif
+
+    error_count++;
 }
 
+/* Register an warning at line line, displaying line displine.  Does not print
+ * the warning, only stores it for output_all() to print.
+ */
 void
-yasm_error_set(yasm_error_class eclass, const char *format, ...)
+yasm__warning_va_at(yasm_warn_class num, unsigned long line,
+		    unsigned long displine, const char *fmt, va_list va)
 {
-    va_list va;
-    va_start(va, format);
-    yasm_error_set_va(eclass, format, va);
-    va_end(va);
-}
+    errwarn_data *we;
 
-void
-yasm_error_set_xref_va(unsigned long xrefline, const char *format, va_list va)
-{
-    if (yasm_eclass != YASM_ERROR_NONE)
-	return;
-
-    yasm_exrefline = xrefline;
-
-    yasm_exrefstr = yasm_xmalloc(MSG_MAXSIZE+1);
-#ifdef HAVE_VSNPRINTF
-    vsnprintf(yasm_exrefstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
-#else
-    vsprintf(yasm_exrefstr, yasm_gettext_hook(format), va);
-#endif
-}
-
-void
-yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
-{
-    va_list va;
-    va_start(va, format);
-    yasm_error_set_xref_va(xrefline, format, va);
-    va_end(va);
-}
-
-void
-yasm_error_fetch(yasm_error_class *eclass, char **str, unsigned long *xrefline,
-		 char **xrefstr)
-{
-    *eclass = yasm_eclass;
-    *str = yasm_estr;
-    *xrefline = yasm_exrefline;
-    *xrefstr = yasm_exrefstr;
-    yasm_eclass = YASM_ERROR_NONE;
-    yasm_estr = NULL;
-    yasm_exrefline = 0;
-    yasm_exrefstr = NULL;
-}
-
-void yasm_warn_clear(void)
-{
-    /* Delete all error/warnings */
-    while (!STAILQ_EMPTY(&yasm_warns)) {
-	warn *w = STAILQ_FIRST(&yasm_warns);
-
-	if (w->wstr)
-	    yasm_xfree(w->wstr);
-
-	STAILQ_REMOVE_HEAD(&yasm_warns, link);
-	yasm_xfree(w);
-    }
-}
-
-void
-yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va)
-{
-    warn *w;
-
-    if (!(warn_class_enabled & (1UL<<wclass)))
+    if (!(warn_class_enabled & (1UL<<num)))
 	return;	    /* warning is part of disabled class */
 
-    w = yasm_xmalloc(sizeof(warn));
-    w->wclass = wclass;
-    w->wstr = yasm_xmalloc(MSG_MAXSIZE+1);
+    we = errwarn_data_new(line, displine, 0);
+
+    we->type = WE_WARNING;
+
 #ifdef HAVE_VSNPRINTF
-    vsnprintf(w->wstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
+    vsnprintf(we->msg, MSG_MAXSIZE, yasm_gettext_hook(fmt), va);
 #else
-    vsprintf(w->wstr, yasm_gettext_hook(format), va);
+    vsprintf(we->msg, yasm_gettext_hook(fmt), va);
 #endif
-    STAILQ_INSERT_TAIL(&yasm_warns, w, link);
+
+    warning_count++;
 }
 
+/* Register an error at line line.  Does not print the error, only stores it
+ * for output_all() to print.
+ */
 void
-yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
+yasm__error(unsigned long line, const char *fmt, ...)
 {
     va_list va;
-    va_start(va, format);
-    yasm_warn_set_va(wclass, format, va);
+    va_start(va, fmt);
+    yasm__error_va_at(line, line, fmt, va);
     va_end(va);
 }
 
+/* Register an error at line line, displaying line displine.  Does not print
+ * the error, only stores it for output_all() to print.
+ */
 void
-yasm_warn_fetch(yasm_warn_class *wclass, char **str)
+yasm__error_at(unsigned long line, unsigned long displine, const char *fmt,
+	       ...)
 {
-    warn *w = STAILQ_FIRST(&yasm_warns);
+    va_list va;
+    va_start(va, fmt);
+    yasm__error_va_at(line, displine, fmt, va);
+    va_end(va);
+}
 
-    *wclass = w->wclass;
-    *str = w->wstr;
+/* Register an warning at line line.  Does not print the warning, only stores
+ * it for output_all() to print.
+ */
+void
+yasm__warning(yasm_warn_class num, unsigned long line, const char *fmt, ...)
+{
+    va_list va;
+    va_start(va, fmt);
+    yasm__warning_va_at(num, line, line, fmt, va);
+    va_end(va);
+}
 
-    STAILQ_REMOVE_HEAD(&yasm_warns, link);
-    yasm_xfree(w);
+/* Register an warning at line line, displaying line displine.  Does not print
+ * the warning, only stores it for output_all() to print.
+ */
+void
+yasm__warning_at(yasm_warn_class num, unsigned long line,
+		 unsigned long displine, const char *fmt, ...)
+{
+    va_list va;
+    va_start(va, fmt);
+    yasm__warning_va_at(num, line, line, fmt, va);
+    va_end(va);
+}
+
+/* Parser error handler.  Moves YACC-style error into our error handling
+ * system.
+ */
+void
+yasm__parser_error(unsigned long line, const char *s)
+{
+    yasm__error(line, N_("parser error: %s"), s);
+    previous_we->type = WE_PARSERERROR;
 }
 
 void
@@ -402,103 +356,36 @@
     warn_class_enabled = 0;
 }
 
-yasm_errwarns *
-yasm_errwarns_create(void)
-{
-    yasm_errwarns *errwarns = yasm_xmalloc(sizeof(yasm_errwarns));
-    SLIST_INIT(&errwarns->errwarns);
-    errwarns->ecount = 0;
-    errwarns->wcount = 0;
-    errwarns->previous_we = NULL;
-    return errwarns;
-}
-
-void
-yasm_errwarns_destroy(yasm_errwarns *errwarns)
-{
-    errwarn_data *we;
-
-    /* Delete all error/warnings */
-    while (!SLIST_EMPTY(&errwarns->errwarns)) {
-	we = SLIST_FIRST(&errwarns->errwarns);
-	if (we->msg)
-	    yasm_xfree(we->msg);
-	if (we->xrefmsg)
-	    yasm_xfree(we->xrefmsg);
-
-	SLIST_REMOVE_HEAD(&errwarns->errwarns, link);
-	yasm_xfree(we);
-    }
-
-    yasm_xfree(errwarns);
-}
-
-void
-yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line)
-{
-    if (yasm_eclass != YASM_ERROR_NONE) {
-	errwarn_data *we = errwarn_data_new(errwarns, line, 1);
-	yasm_error_class eclass;
-
-	yasm_error_fetch(&eclass, &we->msg, &we->xrefline, &we->xrefmsg);
-	if (eclass != YASM_ERROR_GENERAL
-	    && (eclass & YASM_ERROR_PARSE) == YASM_ERROR_PARSE)
-	    we->type = WE_PARSERERROR;
-	else
-	    we->type = WE_ERROR;
-	errwarns->ecount++;
-    }
-
-    while (!STAILQ_EMPTY(&yasm_warns)) {
-	errwarn_data *we = errwarn_data_new(errwarns, line, 0);
-	yasm_warn_class wclass;
-
-	yasm_warn_fetch(&wclass, &we->msg);
-	we->type = WE_WARNING;
-	errwarns->wcount++;
-    }
-}
-
 unsigned int
-yasm_errwarns_num_errors(yasm_errwarns *errwarns, int warning_as_error)
+yasm_get_num_errors(int warning_as_error)
 {
     if (warning_as_error)
-	return errwarns->ecount+errwarns->wcount;
+	return error_count+warning_count;
     else
-	return errwarns->ecount;
+	return error_count;
 }
 
 void
-yasm_errwarns_output_all(yasm_errwarns *errwarns, yasm_linemap *lm,
-			 int warning_as_error,
-			 yasm_print_error_func print_error,
-			 yasm_print_warning_func print_warning)
+yasm_errwarn_output_all(yasm_linemap *lm, int warning_as_error,
+     yasm_print_error_func print_error, yasm_print_warning_func print_warning)
 {
     errwarn_data *we;
-    const char *filename, *xref_filename;
-    unsigned long line, xref_line;
+    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")),
-		    NULL, 0, NULL);
+		    yasm_gettext_hook(N_("warnings being treated as errors")));
 	warning_as_error = 2;
     }
 
     /* Output error/warnings. */
-    SLIST_FOREACH(we, &errwarns->errwarns, link) {
+    SLIST_FOREACH(we, &errwarns, link) {
 	/* Output error/warning */
-	yasm_linemap_lookup(lm, we->line, &filename, &line);
-	if (we->xrefline)
-	    yasm_linemap_lookup(lm, we->xrefline, &xref_filename, &xref_line);
-	else {
-	    xref_filename = NULL;
-	    xref_line = 0;
-	}
-	if (we->type == WE_ERROR || we->type == WE_PARSERERROR)
-	    print_error(filename, line, we->msg, xref_filename, xref_line,
-			we->xrefmsg);
+	yasm_linemap_lookup(lm, we->displine, &filename, &line);
+	if (we->type == WE_ERROR)
+	    print_error(filename, line, we->msg);
 	else
 	    print_warning(filename, line, we->msg);
     }
diff --git a/libyasm/errwarn.h b/libyasm/errwarn.h
index f76d6d2..dc05f70 100644
--- a/libyasm/errwarn.h
+++ b/libyasm/errwarn.h
@@ -36,35 +36,13 @@
 
 /** Warning classes (that may be enabled/disabled). */
 typedef enum {
-    YASM_WARN_NONE = 0,	    /**< No warning */
-    YASM_WARN_GENERAL,	    /**< Non-specific warnings */
+    YASM_WARN_GENERAL = 0,  /**< Non-specific warnings */
     YASM_WARN_UNREC_CHAR,   /**< Unrecognized characters (while tokenizing) */
     YASM_WARN_PREPROC,	    /**< Preprocessor warnings */
     YASM_WARN_ORPHAN_LABEL, /**< Label alone on a line without a colon */
-    YASM_WARN_UNINIT_CONTENTS /**< Uninitialized space in code/data section */
+    YASM_WARN_UNINIT_CONTENTS	/**< Uninitialized space in code/data section */
 } yasm_warn_class;
 
-/** Error classes.  Bitmask-based to support limited subclassing. */
-typedef enum {
-    YASM_ERROR_NONE		= 0x0000, /**< No error */
-    YASM_ERROR_GENERAL		= 0xFFFF, /**< Non-specific */
-    YASM_ERROR_ARITHMETIC	= 0x0001, /**< Arithmetic error (general) */
-    YASM_ERROR_OVERFLOW		= 0x8001, /**< Arithmetic overflow */
-    YASM_ERROR_FLOATING_POINT	= 0x4001, /**< Floating point error */
-    YASM_ERROR_ZERO_DIVISION	= 0x2001, /**< Divide-by-zero */
-    YASM_ERROR_ASSERTION	= 0x0002, /**< Assertion error */
-    YASM_ERROR_VALUE		= 0x0004, /**< Value inappropriate
-					   *   (e.g. not in range) */
-    YASM_ERROR_NOT_ABSOLUTE	= 0x8004, /**< Absolute expression required */
-    YASM_ERROR_TOO_COMPLEX	= 0x4004, /**< Expression too complex */
-    YASM_ERROR_NOT_CONSTANT	= 0x2004, /**< Constant expression required */
-    YASM_ERROR_IO		= 0x0008, /**< I/O error */
-    YASM_ERROR_NOT_IMPLEMENTED	= 0x0010, /**< Not implemented error */
-    YASM_ERROR_TYPE		= 0x0020, /**< Type error */
-    YASM_ERROR_SYNTAX		= 0x0040, /**< Syntax error */
-    YASM_ERROR_PARSE		= 0x8040  /**< Parser error */
-} yasm_error_class;
-
 /** Initialize any internal data structures. */
 void yasm_errwarn_initialize(void);
 
@@ -107,118 +85,101 @@
  */
 /*@exits@*/ void yasm__fatal(const char *message, ...);
 
-/** Unconditionally clear the error indicator, freeing any associated data.
- * Has no effect if the error indicator is not set.
+/** Log an error at a given line, displaying a different line.  va_list version
+ * of yasm__error_at().
+ * \internal
+ * \param line      virtual line
+ * \param displine  displayed virtual line
+ * \param message   printf-like-format message
+ * \param va	    argument list for message
  */
-void yasm_error_clear(void);
+void yasm__error_va_at(unsigned long line, unsigned long displine,
+		       const char *message, va_list va);
 
-/** Get the error indicator.  YASM_ERROR_NONE is returned if no error has
- * been set.  Note that as YASM_ERROR_NONE is 0, the return value can also
- * be treated as a boolean value.
- * \return Current error indicator.
+/** Log an error.  va_list version of yasm__error().
+ * \internal
+ * \param line      virtual line
+ * \param message   printf-like-format message
+ * \param va	    argument list for message
  */
-yasm_error_class yasm_error_occurred(void);
+#define yasm__error_va(line, message, va) \
+    yasm__error_va_at(line, line, message, va)
 
-/** Check the error indicator against an error class.  To check if any error
- * has been set, check against the YASM_ERROR_GENERAL class.  This function
- * properly checks error subclasses.
- * \param eclass    base error class to check against
- * \return Nonzero if error indicator is set and a subclass of eclass, 0
- *         otherwise.
- */
-int yasm_error_matches(yasm_error_class eclass);
-
-#ifndef YASM_DOXYGEN
-extern yasm_error_class yasm_eclass;
-#define yasm_error_occurred()	    yasm_eclass
-#endif
-
-/** Set the error indicator (va_list version).  Has no effect if the error
- * indicator is already set.
- * \param eclass    error class
- * \param format    printf format string
- * \param va	    argument list for format
- */
-void yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va);
-
-/** Set the error indicator.  Has no effect if the error indicator is already
- * set.
- * \param eclass    error class
- * \param format    printf format string
- * \param ...	    argument list for format
- */
-void yasm_error_set(yasm_error_class eclass, const char *format, ...)
-    /*@printflike@*/;
-
-/** Set a cross-reference for a new error (va_list version).  Has no effect
- * if the error indicator is already set (e.g. with yasm_error_set()).  This
- * function must be called prior to its corresponding yasm_error_set() call.
- * \param xrefline  virtual line to cross-reference to (should not be 0)
- * \param format    printf format string
- * \param va	    argument list for format
- */
-void yasm_error_set_xref_va(unsigned long xrefline, const char *format,
-			    va_list va);
-
-/** Set a cross-reference for a new error.  Has no effect if the error
- * indicator is already set (e.g. with yasm_error_set()).  This function
- * must be called prior to its corresponding yasm_error_set() call.
- * \param xrefline  virtual line to cross-reference to (should not be 0)
- * \param format    printf format string
- * \param ...	    argument list for format
- */
-void yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
-    /*@printflike@*/;
-
-/** Fetch the error indicator and all associated data.  If the error
- * indicator is set, the output pointers are set to the current error
- * indicator values, and the error indicator is cleared.
- * The code using this function is then responsible for yasm_xfree()'ing
- * str and xrefstr (if non-NULL).  If the error indicator is not set,
- * all output values are set to 0 (including eclass, which is set to
- * YASM_ERROR_NONE).
- * \param eclass    error class (output)
- * \param str	    error message
- * \param xrefline  virtual line used for cross-referencing (0 if no xref)
- * \param xrefstr   cross-reference error message (NULL if no xref)
- */
-void yasm_error_fetch(/*@out@*/ yasm_error_class *eclass,
-		      /*@out@*/ /*@only@*/ /*@null@*/ char **str,
-		      /*@out@*/ unsigned long *xrefline,
-		      /*@out@*/ /*@only@*/ /*@null@*/ char **xrefstr);
-
-/** Unconditionally clear all warning indicators, freeing any associated data.
- * Has no effect if no warning indicators have been set.
- */
-void yasm_warn_clear(void);
-
-/** Add a warning indicator (va_list version).
+/** Log a warning at a given line, displaying a different line.  va_list
+ * version of yasm__warning_at().
+ * \internal
  * \param wclass    warning class
- * \param format    printf format string
- * \param va	    argument list for format
+ * \param line      virtual line
+ * \param displine  displayed virtual line
+ * \param message   printf-like-format message
+ * \param va	    argument list for message
  */
-void yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va);
+void yasm__warning_va_at(yasm_warn_class wclass, unsigned long line,
+			 unsigned long displine, const char *message,
+			 va_list va);
 
-/** Add a warning indicator.
+/** Log a warning.  va_list version of yasm__warning().
+ * \internal
  * \param wclass    warning class
- * \param format    printf format string
- * \param ...	    argument list for format
+ * \param line      virtual line
+ * \param message   printf-like-format message
+ * \param va	    argument list for message
  */
-void yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
+#define yasm__warning_va(wclass, line, message, va) \
+    yasm__warning_va_at(wclass, line, line, message, va)
+
+/** Log an error.  Does not print it out immediately; yasm_errwarn_output_all()
+ * outputs errors and warnings.
+ * \internal
+ * \param line      virtual line
+ * \param message   printf-like-format message
+ * \param ...	    argument list for message
+ */
+void yasm__error(unsigned long line, const char *message, ...)
     /*@printflike@*/;
 
-/** Fetch the first warning indicator and all associated data.  If there
- * is at least one warning indicator, the output pointers are set to the
- * first warning indicator values, and first warning indicator is removed.
- * The code using this function is then responsible for yasm_xfree()'ing
- * str and xrefstr (if non-NULL).  If there is no warning indicator set,
- * all output values are set to 0 (including wclass, which is set to
- * YASM_WARN_NONE).
- * \param wclass    warning class (output)
- * \param str	    warning message
+/** Log an error at a given line, displaying a different line.  Does not print
+ * it out immediately; yasm_errwarn_output_all() outputs errors and warnings.
+ * \internal
+ * \param line      virtual line
+ * \param displine  displayed virtual line
+ * \param message   printf-like-format message
+ * \param ...	    argument list for message
  */
-void yasm_warn_fetch(/*@out@*/ yasm_warn_class *wclass,
-		     /*@out@*/ /*@only@*/ char **str);
+void yasm__error_at(unsigned long line, unsigned long displine,
+		    const char *message, ...) /*@printflike@*/;
+
+/** Log a warning.  Does not print it out immediately;
+ * yasm_errwarn_output_all() outputs errors and warnings.
+ * \internal
+ * \param wclass    warning class
+ * \param line      virtual line
+ * \param message   printf-like-format message
+ * \param ...	    argument list for message
+ */
+void yasm__warning(yasm_warn_class wclass, unsigned long line,
+		   const char *message, ...) /*@printflike@*/;
+
+/** Log a warning at a given line, displaying a different line.  Does not print
+ * it out immediately; yasm_errwarn_output_all() outputs errors and warnings.
+ * \internal
+ * \param wclass    warning class
+ * \param line      virtual line
+ * \param displine  displayed virtual line
+ * \param message   printf-like-format message
+ * \param ...	    argument list for message
+ */
+void yasm__warning_at(yasm_warn_class wclass, unsigned long line,
+		      unsigned long displine, const char *message, ...)
+    /*@printflike@*/;
+
+/** Log a parser error.  Parser errors can be overwritten by non-parser errors
+ * on the same line.
+ * \internal
+ * \param line      virtual line
+ * \param message   parser error message
+ */
+void yasm__parser_error(unsigned long line, const char *message);
 
 /** Enable a class of warnings.
  * \param wclass    warning class
@@ -233,48 +194,19 @@
 /** Disable all classes of warnings. */
 void yasm_warn_disable_all(void);
 
-/** Create an error/warning set for collection of multiple error/warnings.
- * \return Newly allocated set.
- */
-/*@only@*/ yasm_errwarns *yasm_errwarns_create(void);
-
-/** Destroy an error/warning set.
- * \param errwarns  error/warning set
- */
-void yasm_errwarns_destroy(/*@only@*/ yasm_errwarns *errwarns);
-
-/** Propagate error indicator and warning indicator(s) to an error/warning set.
- * Has no effect if the error indicator and warning indicator are not set.
- * Does not print immediately; yasm_errwarn_output_all() outputs
- * accumulated errors and warnings.
- * Generally multiple errors on the same line will be reported, but errors
- * of class YASM_ERROR_PARSE will get overwritten by any other class on the
- * same line.
- * \param errwarns  error/warning set
- * \param line      virtual line
- */
-void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line);
-
 /** Get total number of errors logged.
- * \param errwarns	    error/warning set
  * \param warning_as_error  if nonzero, warnings are treated as errors.
  * \return Number of errors.
  */
-unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns,
-				      int warning_as_error);
+unsigned int yasm_get_num_errors(int warning_as_error);
 
 /** Print out an error.
- * \param fn		filename of source file
- * \param line		line number
- * \param msg		error message
- * \param xref_fn	cross-referenced source filename
- * \param xref_line	cross-referenced line number
- * \param xref_msg	cross-referenced error message
+ * \param fn	filename of source file
+ * \param line	line number
+ * \param msg	error message
  */
 typedef void (*yasm_print_error_func)
-    (const char *fn, unsigned long line, const char *msg,
-     /*@null@*/ const char *xref_fn, unsigned long xref_line,
-     /*@null@*/ const char *xref_msg);
+    (const char *fn, unsigned long line, const char *msg);
 
 /** Print out a warning.
  * \param fn	filename of source file
@@ -284,16 +216,15 @@
 typedef void (*yasm_print_warning_func)
     (const char *fn, unsigned long line, const char *msg);
 
-/** Outputs error/warning set in sorted order (sorted by virtual line number).
- * \param errwarns	    error/warning set
+/** Outputs all errors and warnings.
  * \param lm	line map (to convert virtual lines into filename/line pairs)
- * \param warning_as_error  if nonzero, treat warnings as errors.
+ * \param warning_as_error  if nonzero, treat warnings as errors
  * \param print_error	    function called to print out errors
  * \param print_warning	    function called to print out warnings
  */
-void yasm_errwarns_output_all
-    (yasm_errwarns *errwarns, yasm_linemap *lm, int warning_as_error,
-     yasm_print_error_func print_error, yasm_print_warning_func print_warning);
+void yasm_errwarn_output_all
+    (yasm_linemap *lm, int warning_as_error, yasm_print_error_func print_error,
+     yasm_print_warning_func print_warning);
 
 /** Convert a possibly unprintable character into a printable string.
  * \internal
diff --git a/libyasm/expr.c b/libyasm/expr.c
index a0f5569..3f37d24 100644
--- a/libyasm/expr.c
+++ b/libyasm/expr.c
@@ -50,12 +50,6 @@
 				    int (*func) (/*@null@*/ yasm_expr *e,
 						 /*@null@*/ void *d));
 
-/* Bitmap of used items.  We should really never need more than 2 at a time,
- * so 31 is pretty much overkill.
- */
-static unsigned long itempool_used = 0;
-static yasm_expr__item itempool[31];
-
 /* 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@*/
@@ -64,7 +58,6 @@
 		 yasm_expr__item *right, unsigned long line)
 {
     yasm_expr *ptr, *sube;
-    unsigned long z;
     ptr = yasm_xmalloc(sizeof(yasm_expr));
 
     ptr->op = op;
@@ -73,10 +66,7 @@
     ptr->terms[1].type = YASM_EXPR_NONE;
     if (left) {
 	ptr->terms[0] = *left;	/* structure copy */
-	z = left-itempool;
-	if (z>=31)
-	    yasm_internal_error(N_("could not find expritem in pool"));
-	itempool_used &= ~(1<<z);
+	yasm_xfree(left);
 	ptr->numterms++;
 
 	/* Search downward until we find something *other* than an
@@ -96,10 +86,7 @@
 
     if (right) {
 	ptr->terms[1] = *right;	/* structure copy */
-	z = right-itempool;
-	if (z>=31)
-	    yasm_internal_error(N_("could not find expritem in pool"));
-	itempool_used &= ~(1<<z);
+	yasm_xfree(right);
 	ptr->numterms++;
 
 	/* Search downward until we find something *other* than an
@@ -122,26 +109,10 @@
 /*@=compmempass@*/
 
 /* helpers */
-static yasm_expr__item *
-expr_get_item(void)
-{
-    int z = 0;
-    unsigned long v = itempool_used & 0x7fffffff;
-
-    while (v & 1) {
-	v >>= 1;
-	z++;
-    }
-    if (z>=31)
-	yasm_internal_error(N_("too many expritems"));
-    itempool_used |= 1<<z;
-    return &itempool[z];
-}
-
 yasm_expr__item *
 yasm_expr_sym(yasm_symrec *s)
 {
-    yasm_expr__item *e = expr_get_item();
+    yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
     e->type = YASM_EXPR_SYM;
     e->data.sym = s;
     return e;
@@ -150,7 +121,7 @@
 yasm_expr__item *
 yasm_expr_expr(yasm_expr *x)
 {
-    yasm_expr__item *e = expr_get_item();
+    yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
     e->type = YASM_EXPR_EXPR;
     e->data.expn = x;
     return e;
@@ -159,7 +130,7 @@
 yasm_expr__item *
 yasm_expr_int(yasm_intnum *i)
 {
-    yasm_expr__item *e = expr_get_item();
+    yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
     e->type = YASM_EXPR_INT;
     e->data.intn = i;
     return e;
@@ -168,7 +139,7 @@
 yasm_expr__item *
 yasm_expr_float(yasm_floatnum *f)
 {
-    yasm_expr__item *e = expr_get_item();
+    yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
     e->type = YASM_EXPR_FLOAT;
     e->data.flt = f;
     return e;
@@ -177,7 +148,7 @@
 yasm_expr__item *
 yasm_expr_reg(unsigned long reg)
 {
-    yasm_expr__item *e = expr_get_item();
+    yasm_expr__item *e = yasm_xmalloc(sizeof(yasm_expr__item));
     e->type = YASM_EXPR_REG;
     e->data.reg = reg;
     return e;
@@ -333,7 +304,8 @@
 	     * 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);
+		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);
@@ -401,10 +373,8 @@
 static int
 expr_is_constant(yasm_expr_op op, yasm_intnum *intn)
 {
-    int iszero = yasm_intnum_is_zero(intn);
-    return ((iszero && op == YASM_EXPR_MUL) ||
-	    (iszero && op == YASM_EXPR_AND) ||
-	    (iszero && op == YASM_EXPR_LAND) ||
+    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));
 }
 
@@ -412,31 +382,24 @@
 static int
 expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn)
 {
-    int iszero = yasm_intnum_is_zero(intn);
     return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
-	    (iszero && op == YASM_EXPR_ADD) ||
+	    (yasm_intnum_is_zero(intn) && op == YASM_EXPR_ADD) ||
 	    (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
-	    (!iszero && op == YASM_EXPR_LAND) ||
-	    (iszero && op == YASM_EXPR_OR) ||
-	    (iszero && op == YASM_EXPR_LOR));
+	    (yasm_intnum_is_zero(intn) && op == YASM_EXPR_OR));
 }
 
 /* Look for simple "right" identities like x+|-0, x*&/1 */
 static int
 expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn)
 {
-    int iszero = yasm_intnum_is_zero(intn);
-    int ispos1 = yasm_intnum_is_pos1(intn);
-    return ((ispos1 && op == YASM_EXPR_MUL) ||
-	    (ispos1 && op == YASM_EXPR_DIV) ||
-	    (iszero && op == YASM_EXPR_ADD) ||
-	    (iszero && op == YASM_EXPR_SUB) ||
+    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) ||
-	    (!iszero && op == YASM_EXPR_LAND) ||
-	    (iszero && op == YASM_EXPR_OR) ||
-	    (iszero && op == YASM_EXPR_LOR) ||
-	    (iszero && op == YASM_EXPR_SHL) ||
-	    (iszero && op == YASM_EXPR_SHR));
+	    (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.
@@ -513,11 +476,10 @@
 	numterms = 1;
     }
 
-    /* Compute NOT, NEG, and LNOT on single intnum. */
+    /* Compute NOT and NEG on single intnum. */
     if (numterms == 1 && int_term == 0 &&
-	(e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG ||
-	 e->op == YASM_EXPR_LNOT))
-	yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL);
+	(e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG))
+	yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL, e->line);
 
     /* Change expression to IDENT if possible. */
     if (numterms == 1)
@@ -606,7 +568,7 @@
 	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);
+				 e->terms[i].data.intn, e->line);
 		fold_numterms--;
 		level_numterms--;
 		/* make sure to delete folded intnum */
@@ -636,8 +598,7 @@
      */
     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_LOR && e->op != YASM_EXPR_LAND &&
-	 e->op != YASM_EXPR_LXOR && e->op != YASM_EXPR_XOR) ||
+	 e->op != YASM_EXPR_XOR) ||
 	level_numterms <= fold_numterms) {
 	/* Downsize e if necessary */
 	if (fold_numterms < e->numterms && e->numterms > 2)
@@ -682,7 +643,8 @@
 			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);
+					 e->op, sube->terms[j].data.intn,
+					 e->line);
 			/* make sure to delete folded intnum */
 			yasm_intnum_destroy(sube->terms[j].data.intn);
 		    }
@@ -733,7 +695,8 @@
 yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
 		      int simplify_reg_mul, yasm_calc_bc_dist_func calc_bc_dist,
 		      yasm_expr_xform_func expr_xform_extra,
-		      void *expr_xform_extra_data, yasm__exprhead *eh)
+		      void *expr_xform_extra_data, yasm__exprhead *eh,
+		      int *error)
 {
     int i;
     yasm__exprhead eh_local;
@@ -768,8 +731,10 @@
 		/* Check for circular reference */
 		SLIST_FOREACH(np, eh, next) {
 		    if (np->e == equ_expr) {
-			yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				       N_("circular reference detected"));
+			yasm__error(e->line,
+				    N_("circular reference detected"));
+			if (error)
+			    *error = 1;
 			return e;
 		    }
 		}
@@ -788,8 +753,10 @@
 		/* Check for circular reference */
 		SLIST_FOREACH(np, eh, next) {
 		    if (np->e == start) {
-			yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				       N_("circular reference detected"));
+			yasm__error(e->line,
+				    N_("circular reference detected"));
+			if (error)
+			    *error = 1;
 			return e;
 		    }
 		}
@@ -826,7 +793,7 @@
 		yasm_expr__level_tree(e->terms[i].data.expn, fold_const,
 				      simplify_ident, simplify_reg_mul,
 				      calc_bc_dist, expr_xform_extra,
-				      expr_xform_extra_data, eh);
+				      expr_xform_extra_data, eh, error);
 
 	if (ee.e) {
 	    SLIST_REMOVE_HEAD(eh, next);
@@ -842,7 +809,8 @@
 	if (expr_xform_extra)
 	    e = expr_xform_extra(e, expr_xform_extra_data);
 	e = yasm_expr__level_tree(e, fold_const, simplify_ident,
-				  simplify_reg_mul, NULL, NULL, NULL, NULL);
+				  simplify_reg_mul, NULL, NULL, NULL, NULL,
+				  error);
     }
     return e;
 }
@@ -878,9 +846,6 @@
 	case YASM_EXPR_OR:
 	case YASM_EXPR_AND:
 	case YASM_EXPR_XOR:
-	case YASM_EXPR_LOR:
-	case YASM_EXPR_LAND:
-	case YASM_EXPR_LXOR:
 	    /* 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).
@@ -1223,9 +1188,6 @@
 	case YASM_EXPR_XOR:
 	    strcpy(opstr, "^");
 	    break;
-	case YASM_EXPR_XNOR:
-	    strcpy(opstr, "XNOR");
-	    break;
 	case YASM_EXPR_NOR:
 	    strcpy(opstr, "NOR");
 	    break;
@@ -1244,15 +1206,6 @@
 	case YASM_EXPR_LNOT:
 	    strcpy(opstr, "!");
 	    break;
-	case YASM_EXPR_LXOR:
-	    strcpy(opstr, "^^");
-	    break;
-	case YASM_EXPR_LXNOR:
-	    strcpy(opstr, "LXNOR");
-	    break;
-	case YASM_EXPR_LNOR:
-	    strcpy(opstr, "LNOR");
-	    break;
 	case YASM_EXPR_LT:
 	    strcpy(opstr, "<");
 	    break;
diff --git a/libyasm/expr.h b/libyasm/expr.h
index 59b3b5a..f21907a 100644
--- a/libyasm/expr.h
+++ b/libyasm/expr.h
@@ -152,6 +152,8 @@
  * \param expr_xform_extra  extra transformation function
  * \param expr_xform_extra_data	data to pass to expr_xform_extra
  * \param eh		    call with NULL (for internal use in recursion)
+ * \param error		    if non-NULL, set to 1 if an error is encountered
+ *			    (e.g. circular reference errors)
  * \return Leveled expression.
  */
 /*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree
@@ -159,7 +161,8 @@
      int simplify_ident, int simplify_reg_mul,
      /*@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);
+     /*@null@*/ void *expr_xform_extra_data, /*@null@*/ yasm__exprhead *eh,
+     /*@null@*/ int *error);
 
 /** Simplify an expression as much as possible.  Eliminates extraneous
  * branches and simplifies integer-only subexpressions.  Simplified version
@@ -169,7 +172,7 @@
  * \return Simplified expression.
  */
 #define yasm_expr_simplify(e, cbd) \
-    yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL)
+    yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL, NULL)
 
 /** Extract the segment portion of a SEG:OFF expression, leaving the offset.
  * \param ep		expression (pointer to)
diff --git a/libyasm/floatnum.c b/libyasm/floatnum.c
index 3ddd93e..7c65f81 100644
--- a/libyasm/floatnum.c
+++ b/libyasm/floatnum.c
@@ -509,17 +509,15 @@
     yasm_xfree(flt);
 }
 
-int
+void
 yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
-		   /*@unused@*/ yasm_floatnum *operand)
+		   /*@unused@*/ yasm_floatnum *operand, unsigned long line)
 {
-    if (op != YASM_EXPR_NEG) {
-	yasm_error_set(YASM_ERROR_FLOATING_POINT,
-		       N_("Unsupported floating-point arithmetic operation"));
-	return 1;
-    }
-    acc->sign ^= 1;
-    return 0;
+    if (op != YASM_EXPR_NEG)
+	yasm__error(line,
+		    N_("Unsupported floating-point arithmetic operation"));
+    else
+	acc->sign ^= 1;
 }
 
 int
@@ -527,7 +525,7 @@
 {
     unsigned char t[4];
 
-    if (yasm_floatnum_get_sized(flt, t, 4, 32, 0, 0, 0)) {
+    if (yasm_floatnum_get_sized(flt, t, 4, 32, 0, 0, 0, 0)) {
 	*ret_val = 0xDEADBEEFUL;    /* Obviously incorrect return value */
 	return 1;
     }
@@ -662,7 +660,7 @@
 int
 yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
 			size_t destsize, size_t valsize, size_t shift,
-			int bigendian, int warn)
+			int bigendian, int warn, unsigned long line)
 {
     int retval;
     if (destsize*8 != valsize || shift>0 || bigendian) {
@@ -686,10 +684,10 @@
     }
     if (warn) {
 	if (retval < 0)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("underflow in floating point expression"));
 	else if (retval > 0)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("overflow in floating point expression"));
     }
     return retval;
@@ -724,21 +722,21 @@
 
     /* 32-bit (single precision) format */
     fprintf(f, "32-bit: %d: ",
-	    yasm_floatnum_get_sized(flt, out, 4, 32, 0, 0, 0));
+	    yasm_floatnum_get_sized(flt, out, 4, 32, 0, 0, 0, 0));
     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, 64, 0, 0, 0));
+	    yasm_floatnum_get_sized(flt, out, 8, 64, 0, 0, 0, 0));
     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, 80, 0, 0, 0));
+	    yasm_floatnum_get_sized(flt, out, 10, 80, 0, 0, 0, 0));
     for (i=0; i<10; i++)
 	fprintf(f, "%02x ", out[i]);
     fprintf(f, "\n");
diff --git a/libyasm/floatnum.h b/libyasm/floatnum.h
index 3e488f1..a7523dd 100644
--- a/libyasm/floatnum.h
+++ b/libyasm/floatnum.h
@@ -66,10 +66,10 @@
  * \param acc	    floatnum accumulator
  * \param op	    operation
  * \param operand   floatnum operand
- * \return Nonzero on error.
+ * \param line      virtual line (of expression)
  */
-int yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
-		       yasm_floatnum *operand);
+void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
+			yasm_floatnum *operand, unsigned long line);
 
 /** Convert a floatnum to single-precision and return as 32-bit value.
  * The 32-bit value is a "standard" C value (eg, of unknown endian).
@@ -95,12 +95,13 @@
  * \param shift	    left shift (in bits)
  * \param bigendian endianness (nonzero=big, zero=little)
  * \param warn	    enables standard overflow/underflow warnings
+ * \param line      virtual line; may be 0 if warn is 0.
  * \return Nonzero if flt can't fit into the specified precision: -1 if
  *         underflow occurred, 1 if overflow occurred.
  */
 int yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
 			    size_t destsize, size_t valsize, size_t shift,
-			    int bigendian, int warn);
+			    int bigendian, int warn, unsigned long line);
 
 /** Basic check to see if size is valid for flt conversion (using
  * yasm_floatnum_get_sized()).  Doesn't actually check for underflow/overflow
diff --git a/libyasm/hamt.c b/libyasm/hamt.c
index 129bae1..6d2b2ad 100644
--- a/libyasm/hamt.c
+++ b/libyasm/hamt.c
@@ -37,11 +37,11 @@
 #include "hamt.h"
 #include "_stdint.h"			/* for uintptr_t */
 
-struct HAMTEntry {
+typedef struct HAMTEntry {
     STAILQ_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 */
@@ -160,24 +160,6 @@
     return 0;
 }
 
-const HAMTEntry *
-HAMT_first(const HAMT *hamt)
-{
-    return STAILQ_FIRST(&hamt->entries);
-}
-
-const HAMTEntry *
-HAMT_next(const HAMTEntry *prev)
-{
-    return STAILQ_NEXT(prev, next);
-}
-
-void *
-HAMTEntry_get_data(const HAMTEntry *entry)
-{
-    return entry->data;
-}
-
 /*@-temptrans -kepttrans -mustfree@*/
 void *
 HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
diff --git a/libyasm/hamt.h b/libyasm/hamt.h
index 865844c..78d380e 100644
--- a/libyasm/hamt.h
+++ b/libyasm/hamt.h
@@ -36,8 +36,6 @@
 
 /** Hash array mapped trie data structure (opaque type). */
 typedef struct HAMT HAMT;
-/** Hash array mapped trie entry (opaque type). */
-typedef struct HAMTEntry HAMTEntry;
 
 /** Create new, empty, HAMT.  error_func() is called when an internal error is
  * encountered--it should NOT return to the calling function.
@@ -93,22 +91,4 @@
 		  int (*func) (/*@dependent@*/ /*@null@*/ void *node,
 			       /*@null@*/ void *d));
 
-/** Get the first entry in a HAMT.
- * \param hamt		Hash array mapped trie
- * \return First entry in HAMT, or NULL if HAMT is empty.
- */
-const HAMTEntry *HAMT_first(const HAMT *hamt);
-
-/** Get the next entry in a HAMT.
- * \param prev		Previous entry in HAMT
- * \return Next entry in HAMT, or NULL if no more entries.
- */
-/*@null@*/ const HAMTEntry *HAMT_next(const HAMTEntry *prev);
-
-/** Get the corresponding data for a HAMT entry.
- * \param entry		HAMT entry (as returned by HAMT_first() and HAMT_next())
- * \return Corresponding data item.
- */
-void *HAMTEntry_get_data(const HAMTEntry *entry);
-
 #endif
diff --git a/libyasm/intnum.c b/libyasm/intnum.c
index 160d5dd..b4d8282 100644
--- a/libyasm/intnum.c
+++ b/libyasm/intnum.c
@@ -83,7 +83,7 @@
 }
 
 yasm_intnum *
-yasm_intnum_create_dec(char *str)
+yasm_intnum_create_dec(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
@@ -91,7 +91,7 @@
 
     if (BitVector_from_Dec_static(from_dec_data, conv_bv,
 				  (unsigned char *)str) == ErrCode_Ovfl)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
 	intn->type = INTNUM_UL;
@@ -105,14 +105,14 @@
 }
 
 yasm_intnum *
-yasm_intnum_create_bin(char *str)
+yasm_intnum_create_bin(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = (unsigned char)strlen(str);
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
@@ -128,14 +128,14 @@
 }
 
 yasm_intnum *
-yasm_intnum_create_oct(char *str)
+yasm_intnum_create_oct(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = strlen(str)*3;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
@@ -151,14 +151,14 @@
 }
 
 yasm_intnum *
-yasm_intnum_create_hex(char *str)
+yasm_intnum_create_hex(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = strlen(str)*4;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
@@ -175,7 +175,7 @@
 
 /*@-usedef -compdef -uniondef@*/
 yasm_intnum *
-yasm_intnum_create_charconst_nasm(const char *str)
+yasm_intnum_create_charconst_nasm(const char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
     size_t len = strlen(str);
@@ -183,7 +183,7 @@
     intn->origsize = len*8;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Character constant too large for internal format"));
 
     if (len > 4) {
@@ -260,7 +260,7 @@
 
 yasm_intnum *
 yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
-			  unsigned long *size)
+			  unsigned long *size, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
     const unsigned char *ptr_orig = ptr;
@@ -280,7 +280,7 @@
     *size = (ptr-ptr_orig)+1;
 
     if(i > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("Numeric constant too large for internal format"));
     else if (sign && (*ptr & 0x40) == 0x40)
 	BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1);
@@ -297,44 +297,6 @@
 }
 
 yasm_intnum *
-yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize,
-			 int bigendian)
-{
-    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
-    unsigned long i = 0;
-
-    intn->origsize = 0;
-
-    if (srcsize*8 > BITVECT_NATIVE_SIZE)
-	yasm_warn_set(YASM_WARN_GENERAL,
-		      N_("Numeric constant too large for internal format"));
-
-    /* Read the buffer into a bitvect */
-    BitVector_Empty(conv_bv);
-    if (bigendian) {
-	/* TODO */
-	yasm_internal_error(N_("big endian not implemented"));
-    } else {
-	for (i = 0; i < srcsize; i++)
-	    BitVector_Chunk_Store(conv_bv, 8, i*8, ptr[i]);
-    }
-
-    /* Sign extend if needed */
-    if (srcsize*8 < BITVECT_NATIVE_SIZE && sign && (ptr[i] & 0x80) == 0x80)
-	BitVector_Interval_Fill(conv_bv, i*8, BITVECT_NATIVE_SIZE-1);
-
-    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_copy(const yasm_intnum *intn)
 {
     yasm_intnum *n = yasm_xmalloc(sizeof(yasm_intnum));
@@ -362,12 +324,12 @@
 }
 
 /*@-nullderef -nullpass -branchstate@*/
-int
-yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
+void
+yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
+		 unsigned long line)
 {
     boolean carry = 0;
     wordptr op1, op2 = NULL;
-    N_int count;
 
     /* Always do computations with in full bit vector.
      * Bit vector results must be calculated through intermediate storage.
@@ -391,12 +353,8 @@
     }
 
     if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
-	op != YASM_EXPR_LNOT) {
-	yasm_error_set(YASM_ERROR_ARITHMETIC,
-		       N_("operation needs an operand"));
-	BitVector_Empty(result);
-	return 1;
-    }
+	op != YASM_EXPR_LNOT)
+	yasm_internal_error(N_("Operation needs an operand"));
 
     /* A operation does a bitvector computation if result is allocated. */
     switch (op) {
@@ -411,37 +369,17 @@
 	    break;
 	case YASM_EXPR_DIV:
 	    /* TODO: make sure op1 and op2 are unsigned */
-	    if (BitVector_is_empty(op2)) {
-		yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
-		BitVector_Empty(result);
-		return 1;
-	    } else
-		BitVector_Divide(result, op1, op2, spare);
+	    BitVector_Divide(result, op1, op2, spare);
 	    break;
 	case YASM_EXPR_SIGNDIV:
-	    if (BitVector_is_empty(op2)) {
-		yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
-		BitVector_Empty(result);
-		return 1;
-	    } else
-		BitVector_Divide(result, op1, op2, spare);
+	    BitVector_Divide(result, op1, op2, spare);
 	    break;
 	case YASM_EXPR_MOD:
 	    /* TODO: make sure op1 and op2 are unsigned */
-	    if (BitVector_is_empty(op2)) {
-		yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
-		BitVector_Empty(result);
-		return 1;
-	    } else
-		BitVector_Divide(spare, op1, op2, result);
+	    BitVector_Divide(spare, op1, op2, result);
 	    break;
 	case YASM_EXPR_SIGNMOD:
-	    if (BitVector_is_empty(op2)) {
-		yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
-		BitVector_Empty(result);
-		return 1;
-	    } else
-		BitVector_Divide(spare, op1, op2, result);
+	    BitVector_Divide(spare, op1, op2, result);
 	    break;
 	case YASM_EXPR_NEG:
 	    BitVector_Negate(result, op1);
@@ -458,10 +396,6 @@
 	case YASM_EXPR_XOR:
 	    Set_ExclusiveOr(result, op1, op2);
 	    break;
-	case YASM_EXPR_XNOR:
-	    Set_ExclusiveOr(result, op1, op2);
-	    Set_Complement(result, result);
-	    break;
 	case YASM_EXPR_NOR:
 	    Set_Union(result, op1, op2);
 	    Set_Complement(result, result);
@@ -476,10 +410,7 @@
 	case YASM_EXPR_SHR:
 	    if (operand->type == INTNUM_UL) {
 		BitVector_Copy(result, op1);
-		carry = BitVector_msb_(op1);
-		count = (N_int)operand->val.ul;
-		while (count-- > 0)
-		    BitVector_shift_right(result, carry);
+		BitVector_Move_Right(result, (N_int)operand->val.ul);
 	    } else	/* don't even bother, just zero result */
 		BitVector_Empty(result);
 	    break;
@@ -497,66 +428,45 @@
 	    BitVector_Empty(result);
 	    BitVector_LSB(result, BitVector_is_empty(op1));
 	    break;
-	case YASM_EXPR_LXOR:
-	    BitVector_Empty(result);
-	    BitVector_LSB(result, !BitVector_is_empty(op1) ^
-			  !BitVector_is_empty(op2));
-	    break;
-	case YASM_EXPR_LXNOR:
-	    BitVector_Empty(result);
-	    BitVector_LSB(result, !(!BitVector_is_empty(op1) ^
-			  !BitVector_is_empty(op2)));
-	    break;
-	case YASM_EXPR_LNOR:
-	    BitVector_Empty(result);
-	    BitVector_LSB(result, !(!BitVector_is_empty(op1) ||
-			  !BitVector_is_empty(op2)));
-	    break;
 	case YASM_EXPR_EQ:
 	    BitVector_Empty(result);
 	    BitVector_LSB(result, BitVector_equal(op1, op2));
 	    break;
 	case YASM_EXPR_LT:
 	    BitVector_Empty(result);
-	    BitVector_LSB(result, BitVector_Compare(op1, op2) < 0);
+	    BitVector_LSB(result, BitVector_Lexicompare(op1, op2) < 0);
 	    break;
 	case YASM_EXPR_GT:
 	    BitVector_Empty(result);
-	    BitVector_LSB(result, BitVector_Compare(op1, op2) > 0);
+	    BitVector_LSB(result, BitVector_Lexicompare(op1, op2) > 0);
 	    break;
 	case YASM_EXPR_LE:
 	    BitVector_Empty(result);
-	    BitVector_LSB(result, BitVector_Compare(op1, op2) <= 0);
+	    BitVector_LSB(result, BitVector_Lexicompare(op1, op2) <= 0);
 	    break;
 	case YASM_EXPR_GE:
 	    BitVector_Empty(result);
-	    BitVector_LSB(result, BitVector_Compare(op1, op2) >= 0);
+	    BitVector_LSB(result, BitVector_Lexicompare(op1, op2) >= 0);
 	    break;
 	case YASM_EXPR_NE:
 	    BitVector_Empty(result);
 	    BitVector_LSB(result, !BitVector_equal(op1, op2));
 	    break;
 	case YASM_EXPR_SEG:
-	    yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
-			   "SEG");
+	    yasm__error(line, N_("invalid use of '%s'"), "SEG");
 	    break;
 	case YASM_EXPR_WRT:
-	    yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
-			   "WRT");
+	    yasm__error(line, N_("invalid use of '%s'"), "WRT");
 	    break;
 	case YASM_EXPR_SEGOFF:
-	    yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
-			   ":");
+	    yasm__error(line, N_("invalid use of '%s'"), ":");
 	    break;
 	case YASM_EXPR_IDENT:
 	    if (result)
 		BitVector_Copy(result, op1);
 	    break;
 	default:
-	    yasm_error_set(YASM_ERROR_ARITHMETIC,
-			   N_("invalid operation in intnum calculation"));
-	    BitVector_Empty(result);
-	    return 1;
+	    yasm_internal_error(N_("invalid operation in intnum calculation"));
     }
 
     /* Try to fit the result into 32 bits if possible */
@@ -574,7 +484,6 @@
 	    acc->val.bv = BitVector_Clone(result);
 	}
     }
-    return 0;
 }
 /*@=nullderef =nullpass =branchstate@*/
 
@@ -675,7 +584,7 @@
 void
 yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
 		      size_t destsize, size_t valsize, int shift,
-		      int bigendian, int warn)
+		      int bigendian, int warn, unsigned long line)
 {
     wordptr op1 = op1static, op2;
     unsigned char *buf;
@@ -689,11 +598,11 @@
 
     /* General size warnings */
     if (warn<0 && !yasm_intnum_check_size(intn, valsize, rshift, 1))
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("value does not fit in signed %d bit field"),
 		      valsize);
     if (warn>0 && !yasm_intnum_check_size(intn, valsize, rshift, 2))
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("value does not fit in %d bit field"), valsize);
 
     /* Read the original data into a bitvect */
@@ -717,7 +626,7 @@
 	BitVector_Copy(conv_bv, op2);
 	BitVector_Move_Left(conv_bv, BITVECT_NATIVE_SIZE-rshift);
 	if (!BitVector_is_empty(conv_bv))
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("misaligned value, truncating to boundary"));
     }
 
@@ -950,38 +859,6 @@
     return size_leb128(val, 0);
 }
 
-char *
-yasm_intnum_get_str(const yasm_intnum *intn)
-{
-    char *s, *s2;
-
-    switch (intn->type) {
-	case INTNUM_UL:
-	    s = yasm_xmalloc(20);
-	    sprintf(s, "0x%lx", intn->val.ul);
-	    return s;
-	case INTNUM_BV:
-	    if (BitVector_msb_(intn->val.bv)) {
-		/* it's negative: negate the bitvector to get positive */
-		BitVector_Negate(conv_bv, intn->val.bv);
-		s2 = (char *)BitVector_to_Hex(conv_bv);
-		s = yasm_xmalloc(strlen(s2)+4);
-		strcpy(s, "-0x");
-		strcat(s, s2);
-		yasm_xfree(s2);
-	    } else {
-		s2 = (char *)BitVector_to_Hex(intn->val.bv);
-		s = yasm_xmalloc(strlen(s2)+3);
-		strcpy(s, "0x");
-		strcat(s, s2);
-		yasm_xfree(s2);
-	    }
-	    return s;
-    }
-    /*@notreached@*/
-    return NULL;
-}
-
 void
 yasm_intnum_print(const yasm_intnum *intn, FILE *f)
 {
diff --git a/libyasm/intnum.h b/libyasm/intnum.h
index 63c5217..779534a 100644
--- a/libyasm/intnum.h
+++ b/libyasm/intnum.h
@@ -42,35 +42,41 @@
 
 /** Create a new intnum from a decimal string.
  * \param str	    decimal string
+ * \param line	    virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str);
+/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str, unsigned long line);
 
 /** Create a new intnum from a binary string.
  * \param str	    binary string
+ * \param line	    virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str);
+/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str, unsigned long line);
 
 /** Create a new intnum from an octal string.
  * \param str	    octal string
+ * \param line	    virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str);
+/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str, unsigned long line);
 
 /** Create a new intnum from a hexidecimal string.
  * \param str	    hexidecimal string
+ * \param line	    virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str);
+/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str, unsigned long line);
 
 /** Convert character constant to integer value, using NASM rules.  NASM syntax
  * supports automatic conversion from strings such as 'abcd' to a 32-bit
  * integer value.  This function performs those conversions.
  * \param str	    character constant string
+ * \param line      virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
+/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str,
+							  unsigned long line);
 
 /** Create a new intnum from an unsigned integer value.
  * \param i	    unsigned integer value
@@ -86,23 +92,15 @@
 
 /** Create a new intnum from LEB128-encoded form.
  * \param ptr	pointer to start of LEB128 encoded form
- * \param sign	signed (1) or unsigned (0) LEB128 format
+ * \param sign	signed (1) or unsiged (0) LEB128 format
  * \param size	number of bytes read from ptr (output)
+ * \param line	virtual line (where the number came from)
  * \return Newly allocated intnum.  Number of bytes read returned into
  *         bytes_read parameter.
  */
 /*@only@*/ yasm_intnum *yasm_intnum_create_leb128
-    (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size);
-
-/** Create a new intnum from a little-endian or big-endian buffer.
- * In little endian, the LSB is in ptr[0].
- * \param ptr	    pointer to start of buffer
- * \param sign	    signed (1) or unsigned (0) source
- * \param srcsize   source buffer size (in bytes)
- * \param bigendian endianness (nonzero=big, zero=little)
- */
-/*@only@*/ yasm_intnum *yasm_intnum_create_sized
-    (unsigned char *ptr, int sign, size_t srcsize, int bigendian);
+    (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size,
+     unsigned long line);
 
 /** Duplicate an intnum.
  * \param intn	intnum
@@ -121,9 +119,10 @@
  * \param acc	    intnum accumulator
  * \param op	    operation
  * \param operand   intnum operand
- * \return Nonzero if error occurred.
+ * \param line      virtual line (of expression)
  */
-int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
+void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
+		      unsigned long line);
 
 /** Zero an intnum.
  * \param intn	    intnum
@@ -190,11 +189,12 @@
  *		    shift (standard warnings include truncation to boundary)
  * \param bigendian endianness (nonzero=big, zero=little)
  * \param warn	    enables standard warnings (value doesn't fit into valsize
- *		    bits): <0=signed warnings, >0=unsigned warnings, 0=no warn
+ *		    bits)
+ * \param line      virtual line; may be 0 if warn is 0
  */
 void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
 			   size_t destsize, size_t valsize, int shift,
-			   int bigendian, int warn);
+			   int bigendian, int warn, unsigned long line);
 
 /** Check to see if intnum will fit without overflow into size bits.
  * \param intn	    intnum
@@ -251,14 +251,6 @@
  */
 unsigned long yasm_size_uleb128(unsigned long v);
 
-/** Get an intnum as a signed decimal string.  The returned string will
- * contain a leading '-' if the intnum is negative.
- * \param intn	intnum
- * \return Newly allocated string containing the decimal representation of
- *         the intnum.
- */
-/*@only@*/ char *yasm_intnum_get_str(const yasm_intnum *intn);
-
 /** Print an intnum.  For debugging purposes.
  * \param f	file
  * \param intn	intnum
diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h
index 4f63c1c..8bbb793 100644
--- a/libyasm/objfmt.h
+++ b/libyasm/objfmt.h
@@ -87,8 +87,7 @@
     /** Module-level implementation of yasm_objfmt_output().
      * Call yasm_objfmt_output() instead of calling this function.
      */
-    void (*output) (yasm_objfmt *of, FILE *f, int all_syms, yasm_dbgfmt *df,
-		    yasm_errwarns *errwarns);
+    void (*output) (yasm_objfmt *of, FILE *f, int all_syms, yasm_dbgfmt *df);
 
     /** Module-level implementation of yasm_objfmt_destroy().
      * Call yasm_objfmt_destroy() instead of calling this function.
@@ -155,11 +154,9 @@
  * \param all_syms	if nonzero, all symbols should be included in
  *			the object file
  * \param df		debug format in use
- * \param errwarns	error/warning set
- * \note Errors and warnings are stored into errwarns.
  */
 void yasm_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms,
-			yasm_dbgfmt *df, yasm_errwarns *errwarns);
+			yasm_dbgfmt *df);
 
 /** Cleans up any allocated object format memory.
  * \param objfmt	object format
@@ -243,8 +240,8 @@
 
 #define yasm_objfmt_create(module, object, a)	module->create(object, a)
 
-#define yasm_objfmt_output(objfmt, f, all_syms, df, ews) \
-    ((yasm_objfmt_base *)objfmt)->module->output(objfmt, f, all_syms, df, ews)
+#define yasm_objfmt_output(objfmt, f, all_syms, df) \
+    ((yasm_objfmt_base *)objfmt)->module->output(objfmt, f, all_syms, df)
 #define yasm_objfmt_destroy(objfmt) \
     ((yasm_objfmt_base *)objfmt)->module->destroy(objfmt)
 #define yasm_objfmt_section_switch(objfmt, vpms, oe_vpms, line) \
diff --git a/libyasm/optimizer.h b/libyasm/optimizer.h
index 04b0d79..f986bd1 100644
--- a/libyasm/optimizer.h
+++ b/libyasm/optimizer.h
@@ -45,10 +45,10 @@
     /** Optimize an object.  Takes the unoptimized object and optimizes it.
      * If successful, the object is ready for output to an object file.
      * \param object	object
-     * \param errwarns	error/warning set
-     * \note Optimization failures are stored into errwarns.
+     * \note Optimization failures are indicated by this function calling
+     *       yasm__error_at(); see errwarn.h for details.
      */
-    void (*optimize) (yasm_object *object, yasm_errwarns *errwarns);
+    void (*optimize) (yasm_object *object);
 } yasm_optimizer_module;
 
 #endif
diff --git a/libyasm/parser.h b/libyasm/parser.h
index 80b6fca..31ba070 100644
--- a/libyasm/parser.h
+++ b/libyasm/parser.h
@@ -64,13 +64,13 @@
      *				lines of source into the object's linemap (via
      *				yasm_linemap_add_data()).
      * \param def_sect	default (starting) section in the object
-     * \param errwarns	error/warning set
-     * \note Parse errors and warnings are stored into errwarns.
+     * \note Parse failures are indicated by this function calling
+     *       yasm__error(); see errwarn.h for details.
      */
-    void (*do_parse)
-	(yasm_object *object, yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of,
-	 yasm_dbgfmt *df, FILE *f, const char *in_filename, int save_input,
-	 yasm_section *def_sect, yasm_errwarns *errwarns);
+    void (*do_parse) (yasm_object *object, yasm_preproc *pp, yasm_arch *a,
+		      yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
+		      const char *in_filename, int save_input,
+		      yasm_section *def_sect);
 } yasm_parser_module;
 
 #endif
diff --git a/libyasm/preproc.h b/libyasm/preproc.h
index a4d7490..24b78b6 100644
--- a/libyasm/preproc.h
+++ b/libyasm/preproc.h
@@ -56,17 +56,16 @@
      * Module-level implementation of yasm_preproc_create().
      * Call yasm_preproc_create() instead of calling this function.
      *
+     * The preprocessor needs access to the object format module to find out
+     * any output format specific macros.
+     *
      * \param f			initial starting file
      * \param in_filename	initial starting filename
      * \param lm		line mapping repository
-     * \param errwarns		error/warnning set.
      * \return New preprocessor.
-     *
-     * \note Any preprocessor errors and warnings are stored into errwarns.
      */
     /*@only@*/ yasm_preproc * (*create) (FILE *f, const char *in_filename,
-					 yasm_linemap *lm,
-					 yasm_errwarns *errwarns);
+					 yasm_linemap *lm);
 
     /** Module-level implementation of yasm_preproc_destroy().
      * Call yasm_preproc_destroy() instead of calling this function.
@@ -118,13 +117,11 @@
  * \param f		initial starting file
  * \param in_filename	initial starting file filename
  * \param lm		line mapping repository
- * \param errwarns	error/warning set
  * \return New preprocessor.
- * \note Errors/warnings are stored into errwarns.
  */
 /*@only@*/ yasm_preproc *yasm_preproc_create
     (yasm_preproc_module *module, FILE *f, const char *in_filename,
-     yasm_linemap *lm, yasm_errwarns *errwarns);
+     yasm_linemap *lm);
 
 /** Cleans up any allocated preproc memory.
  * \param preproc	preprocessor
@@ -187,8 +184,8 @@
 
 /* Inline macro implementations for preproc functions */
 
-#define yasm_preproc_create(module, f, in_filename, lm, ews) \
-    module->create(f, in_filename, lm, ews)
+#define yasm_preproc_create(module, f, in_filename, lm) \
+    module->create(f, in_filename, lm)
 
 #define yasm_preproc_destroy(preproc) \
     ((yasm_preproc_base *)preproc)->module->destroy(preproc)
diff --git a/libyasm/section.c b/libyasm/section.c
index f351d63..b50e571 100644
--- a/libyasm/section.c
+++ b/libyasm/section.c
@@ -347,7 +347,7 @@
 }
 
 void
-yasm_object_finalize(yasm_object *object, yasm_errwarns *errwarns)
+yasm_object_finalize(yasm_object *object)
 {
     yasm_section *sect;
 
@@ -364,7 +364,6 @@
 	while (cur) {
 	    /* Finalize */
 	    yasm_bc_finalize(cur, prev);
-	    yasm_errwarn_propagate(errwarns, cur->line);
 	    prev = cur;
 	    cur = STAILQ_NEXT(cur, link);
 	}
@@ -461,9 +460,7 @@
 }
 
 int
-yasm_section_bcs_traverse(yasm_section *sect,
-			  /*@null@*/ yasm_errwarns *errwarns,
-			  /*@null@*/ void *d,
+yasm_section_bcs_traverse(yasm_section *sect, void *d,
 			  int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
 {
     yasm_bytecode *cur = STAILQ_FIRST(&sect->bcs);
@@ -474,8 +471,6 @@
     /* Iterate through the remainder, if any. */
     while (cur) {
 	int retval = func(cur, d);
-	if (errwarns)
-	    yasm_errwarn_propagate(errwarns, cur->line);
 	if (retval != 0)
 	    return retval;
 	cur = STAILQ_NEXT(cur, link);
diff --git a/libyasm/section.h b/libyasm/section.h
index 895d593..6132751 100644
--- a/libyasm/section.h
+++ b/libyasm/section.h
@@ -103,10 +103,8 @@
 
 /** Finalize an object after parsing.
  * \param object	object
- * \param errwarns	error/warning set
- * \note Errors/warnings are stored into errwarns.
  */
-void yasm_object_finalize(yasm_object *object, yasm_errwarns *errwarns);
+void yasm_object_finalize(yasm_object *object);
 
 /** Traverses all sections in an object, calling a function on each section.
  * \param object	object
@@ -283,18 +281,15 @@
      /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
 
 /** Traverses all bytecodes in a section, calling a function on each bytecode.
- * \param sect	    section
- * \param errwarns  error/warning set (may be NULL)
- * \param d	    data pointer passed to func on each call (may be NULL)
- * \param func	    function
+ * \param sect	section
+ * \param d	data pointer passed to func on each call
+ * \param func	function
  * \return Stops early (and returns func's return value) if func returns a
  *	   nonzero value; otherwise 0.
- * \note If errwarns is non-NULL, yasm_errwarn_propagate() is called after
- *       each call to func (with the bytecode's line number).
  */
 int yasm_section_bcs_traverse
-    (yasm_section *sect, /*@null@*/ yasm_errwarns *errwarns,
-     /*@null@*/ void *d, int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
+    (yasm_section *sect, /*@null@*/ void *d,
+     int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
 
 /** Get name of a section.
  * \param   sect    section
diff --git a/libyasm/symrec.c b/libyasm/symrec.c
index 08e90f8..6d2f3fe 100644
--- a/libyasm/symrec.c
+++ b/libyasm/symrec.c
@@ -175,24 +175,6 @@
     return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
 }
 
-const yasm_symtab_iter *
-yasm_symtab_first(const yasm_symtab *symtab)
-{
-    return (const yasm_symtab_iter *)HAMT_first(symtab->sym_table);
-}
-
-/*@null@*/ const yasm_symtab_iter *
-yasm_symtab_next(const yasm_symtab_iter *prev)
-{
-    return (const yasm_symtab_iter *)HAMT_next((const HAMTEntry *)prev);
-}
-
-yasm_symrec *
-yasm_symtab_iter_value(const yasm_symtab_iter *cur)
-{
-    return (yasm_symrec *)HAMTEntry_get_data((const HAMTEntry *)cur);
-}
-
 yasm_symrec *
 yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
 {
@@ -217,13 +199,12 @@
 
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if (rec->status & SYM_DEFINED) {
-	yasm_error_set_xref(rec->line, N_("`%s' previously defined here"),
-			    name);
-	yasm_error_set(YASM_ERROR_GENERAL, N_("redefinition of `%s'"),
+	yasm__error(line, N_("redefinition of `%s'"), name);
+	yasm__error_at(line, rec->line, N_("`%s' previously defined here"),
 		       name);
     } else {
 	if (rec->visibility & YASM_SYM_EXTERN)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("`%s' both defined and declared extern"), name);
 	rec->line = line;	/* set line number of definition */
 	rec->type = type;
@@ -305,7 +286,7 @@
 	  ((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
 	rec->visibility |= vis;
     else
-	yasm_error_set(YASM_ERROR_GENERAL,
+	yasm__error(line,
 	    N_("duplicate definition of `%s'; first defined on line %lu"),
 	    rec->name, rec->line);
 }
@@ -314,7 +295,6 @@
     unsigned long firstundef_line;
     int undef_extern;
     /*@null@*/ yasm_objfmt *objfmt;
-    yasm_errwarns *errwarns;
 } symtab_finalize_info;
 
 static int
@@ -327,9 +307,8 @@
 	if (info->undef_extern && info->objfmt)
 	    yasm_objfmt_extern_declare(info->objfmt, sym->name, NULL, 1);
 	else {
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("undefined symbol `%s' (first use)"), sym->name);
-	    yasm_errwarn_propagate(info->errwarns, sym->line);
+	    yasm__error(sym->line, N_("undefined symbol `%s' (first use)"),
+			sym->name);
 	    if (sym->line < info->firstundef_line)
 		info->firstundef_line = sym->line;
 	}
@@ -340,19 +319,16 @@
 
 void
 yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
-			    yasm_objfmt *objfmt, yasm_errwarns *errwarns)
+			    yasm_objfmt *objfmt)
 {
     symtab_finalize_info info;
     info.firstundef_line = ULONG_MAX;
     info.undef_extern = undef_extern;
     info.objfmt = objfmt;
-    info.errwarns = errwarns;
     yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym);
-    if (info.firstundef_line < ULONG_MAX) {
-	yasm_error_set(YASM_ERROR_GENERAL,
-		       N_(" (Each undefined symbol is reported only once.)"));
-	yasm_errwarn_propagate(errwarns, info.firstundef_line);
-    }
+    if (info.firstundef_line < ULONG_MAX)
+	yasm__error(info.firstundef_line,
+		    N_(" (Each undefined symbol is reported only once.)"));
 }
 
 void
diff --git a/libyasm/symrec.h b/libyasm/symrec.h
index a4d9739..da5c8ee 100644
--- a/libyasm/symrec.h
+++ b/libyasm/symrec.h
@@ -154,40 +154,15 @@
     (yasm_symtab *symtab, /*@null@*/ void *d,
      yasm_symtab_traverse_callback func);
 
-/** Symbol table iterator (opaque type). */
-typedef struct yasm_symtab_iter yasm_symtab_iter;
-
-/** Get an iterator pointing to the first symbol in the symbol table.
- * \param symtab    symbol table
- * \return Iterator for the symbol table.
- */
-const yasm_symtab_iter *yasm_symtab_first(const yasm_symtab *symtab);
-
-/** Move a symbol table iterator to the next symbol in the symbol table.
- * \param prev		Previous iterator value
- * \return Next iterator value, or NULL if no more symbols in the table.
- */
-/*@null@*/ const yasm_symtab_iter *yasm_symtab_next
-    (const yasm_symtab_iter *prev);
-
-/** Get the symbol corresponding to the current symbol table iterator value.
- * \param cur		iterator value
- * \return Corresponding symbol.
- */
-yasm_symrec *yasm_symtab_iter_value(const yasm_symtab_iter *cur);
-
 /** Finalize symbol table after parsing stage.  Checks for symbols that are
  * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
  * \param symtab	symbol table
  * \param undef_extern	if nonzero, all undef syms should be declared extern
  * \param objfmt	object format to notify about new extern decls
  *			(may be NULL if undef_extern is 0)
- * \param errwarns	error/warning set
- * \note Errors/warnings are stored into errwarns.
  */
 void yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
-				 /*@null@*/ yasm_objfmt *objfmt,
-				 yasm_errwarns *errwarns);
+				 /*@null@*/ yasm_objfmt *objfmt);
 
 /** Print the symbol table.  For debugging purposes.
  * \param symtab	symbol table
diff --git a/libyasm/tests/Makefile.inc b/libyasm/tests/Makefile.inc
index 0b0a68f..8301624 100644
--- a/libyasm/tests/Makefile.inc
+++ b/libyasm/tests/Makefile.inc
@@ -15,9 +15,6 @@
 EXTRA_DIST += libyasm/tests/charconst64.hex
 EXTRA_DIST += libyasm/tests/duplabel-err.asm
 EXTRA_DIST += libyasm/tests/duplabel-err.errwarn
-EXTRA_DIST += libyasm/tests/emptydata.asm
-EXTRA_DIST += libyasm/tests/emptydata.errwarn
-EXTRA_DIST += libyasm/tests/emptydata.hex
 EXTRA_DIST += libyasm/tests/expr-wide-ident.asm
 EXTRA_DIST += libyasm/tests/expr-wide-ident.errwarn
 EXTRA_DIST += libyasm/tests/expr-wide-ident.hex
diff --git a/libyasm/tests/absloop-err.errwarn b/libyasm/tests/absloop-err.errwarn
index 7998339..6cda28a 100644
--- a/libyasm/tests/absloop-err.errwarn
+++ b/libyasm/tests/absloop-err.errwarn
@@ -1 +1,2 @@
--:6: circular reference detected in memory expression
+-:1: circular reference detected
+-:6: (used in memory expression)
diff --git a/libyasm/tests/emptydata.asm b/libyasm/tests/emptydata.asm
deleted file mode 100644
index 27b5651..0000000
--- a/libyasm/tests/emptydata.asm
+++ /dev/null
@@ -1 +0,0 @@
-db ''
diff --git a/libyasm/tests/emptydata.errwarn b/libyasm/tests/emptydata.errwarn
deleted file mode 100644
index e69de29..0000000
--- a/libyasm/tests/emptydata.errwarn
+++ /dev/null
diff --git a/libyasm/tests/emptydata.hex b/libyasm/tests/emptydata.hex
deleted file mode 100644
index e69de29..0000000
--- a/libyasm/tests/emptydata.hex
+++ /dev/null
diff --git a/libyasm/tests/floatnum_test.c b/libyasm/tests/floatnum_test.c
index a7bdb69..48a20d8 100644
--- a/libyasm/tests/floatnum_test.c
+++ b/libyasm/tests/floatnum_test.c
@@ -295,7 +295,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0, 0) !=
 	    vals[i].ret32)
 	    return 1;
 	if (get_common_check_result(4, outval, vals[i].result32) != 0)
@@ -313,7 +313,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 4, 32, 0, 0, 0, 0) !=
 	    vals[i].ret32)
 	    return 1;
 	if (get_common_check_result(4, outval, vals[i].result32) != 0)
@@ -335,7 +335,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0, 0) !=
 	    vals[i].ret64)
 	    return 1;
 	if (get_common_check_result(8, outval, vals[i].result64) != 0)
@@ -353,7 +353,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 8, 64, 0, 0, 0, 0) !=
 	    vals[i].ret64)
 	    return 1;
 	if (get_common_check_result(8, outval, vals[i].result64) != 0)
@@ -375,7 +375,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0, 0) !=
 	    vals[i].ret80)
 	    return 1;
 	if (get_common_check_result(10, outval, vals[i].result80) != 0)
@@ -393,7 +393,7 @@
 
     for (i=0; i<num; i++) {
 	get_common_setup(vals, i);
-	if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0) !=
+	if (yasm_floatnum_get_sized(flt, outval, 10, 80, 0, 0, 0, 0) !=
 	    vals[i].ret80)
 	    return 1;
 	if (get_common_check_result(10, outval, vals[i].result80) != 0)
diff --git a/libyasm/tests/leb128_test.c b/libyasm/tests/leb128_test.c
index f2e4585..b572eff 100644
--- a/libyasm/tests/leb128_test.c
+++ b/libyasm/tests/leb128_test.c
@@ -83,7 +83,7 @@
 run_output_test(Test_Entry *test)
 {
     char *valstr = yasm__xstrdup(test->input);
-    yasm_intnum *intn = yasm_intnum_create_hex(valstr);
+    yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
     unsigned long size, i;
     unsigned char out[100];
     int bad;
@@ -91,7 +91,7 @@
     yasm_xfree(valstr);
 
     if (test->negate)
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);
 
     size = yasm_intnum_size_leb128(intn, test->sign);
     if (size != test->outsize) {
@@ -133,16 +133,16 @@
 run_input_test(Test_Entry *test)
 {
     char *valstr = yasm__xstrdup(test->input);
-    yasm_intnum *intn = yasm_intnum_create_hex(valstr);
+    yasm_intnum *intn = yasm_intnum_create_hex(valstr, 0);
     yasm_intnum *testn;
     unsigned long size;
 
     yasm_xfree(valstr);
 
     if (test->negate)
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, 0);
 
-    testn = yasm_intnum_create_leb128(test->result, test->sign, &size);
+    testn = yasm_intnum_create_leb128(test->result, test->sign, &size, 0);
     if (size != test->outsize) {
 	yasm_intnum_destroy(testn);
 	yasm_intnum_destroy(intn);
@@ -152,7 +152,7 @@
 	return 1;
     }
 
-    yasm_intnum_calc(intn, YASM_EXPR_EQ, testn);
+    yasm_intnum_calc(intn, YASM_EXPR_EQ, testn, 0);
     if (!yasm_intnum_is_pos1(intn)) {
 	yasm_intnum_destroy(testn);
 	yasm_intnum_destroy(intn);
diff --git a/libyasm/tests/value-err.errwarn b/libyasm/tests/value-err.errwarn
index a753552..ae659a9 100644
--- a/libyasm/tests/value-err.errwarn
+++ b/libyasm/tests/value-err.errwarn
@@ -1,3 +1,3 @@
 -:2: effective address too complex
 -:3: immediate expression too complex
--:8: data expression too complex
+-:8: expression too complex
diff --git a/libyasm/value.c b/libyasm/value.c
index 1a0c8b6..9bae80a 100644
--- a/libyasm/value.c
+++ b/libyasm/value.c
@@ -356,18 +356,20 @@
 }
 
 int
-yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size)
+yasm_value_finalize_expr(yasm_value *value, yasm_expr *e)
 {
+    int error = 0;
+
     if (!e) {
-	yasm_value_initialize(value, NULL, size);
+	yasm_value_initialize(value, NULL);
 	return 0;
     }
 
     yasm_value_initialize(value, yasm_expr__level_tree
-			  (e, 1, 1, 0, NULL, NULL, NULL, NULL), size);
+			  (e, 1, 1, 0, NULL, NULL, NULL, NULL, &error));
 
     /* quit early if there was an issue in simplify() */
-    if (yasm_error_occurred())
+    if (error)
 	return 1;
 
     /* Handle trivial (IDENT) cases immediately */
@@ -406,7 +408,7 @@
 	return 1;
 
     value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, NULL, NULL, NULL,
-				       NULL);
+				       NULL, NULL);
 
     /* Simplify 0 in abs to NULL */
     if (value->abs->op == YASM_EXPR_IDENT
@@ -419,29 +421,26 @@
 }
 
 int
-yasm_value_finalize(yasm_value *value)
-{
-    unsigned int valsize = value->size;
-    return yasm_value_finalize_expr(value, value->abs, valsize);
-}
-
-int
 yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
-			size_t destsize, yasm_bytecode *bc, int warn,
-			yasm_arch *arch, yasm_calc_bc_dist_func calc_bc_dist)
+			size_t destsize, size_t valsize, int shift,
+			yasm_bytecode *bc, int warn, yasm_arch *arch,
+			yasm_calc_bc_dist_func calc_bc_dist)
 {
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
     /*@only@*/ yasm_intnum *outval;
     int sym_local;
     int retval = 1;
-    unsigned int valsize = value->size;
 
     if (value->abs) {
 	/* Handle floating point expressions */
 	if (!value->rel && value->abs->op == YASM_EXPR_IDENT
 	    && value->abs->terms[0].type == YASM_EXPR_FLOAT) {
+	    if (shift < 0)
+		yasm_internal_error(N_("attempting to negative shift a float"));
 	    if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt,
-					   buf, destsize, valsize, 0, warn))
+					   buf, destsize, valsize,
+					   (unsigned int)shift, warn,
+					   bc->line))
 		return -1;
 	    else
 		return 1;
@@ -449,16 +448,14 @@
 
 	/* Check for complex float expressions */
 	if (yasm_expr__contains(value->abs, YASM_EXPR_FLOAT)) {
-	    yasm_error_set(YASM_ERROR_FLOATING_POINT,
-			   N_("floating point expression too complex"));
+	    yasm__error(bc->line, N_("floating point expression too complex"));
 	    return -1;
 	}
 
 	/* Handle integer expressions */
 	intn = yasm_expr_get_intnum(&value->abs, calc_bc_dist);
 	if (!intn) {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("expression too complex"));
+	    yasm__error(bc->line, N_("expression too complex"));
 	    return -1;
 	}
     }
@@ -482,7 +479,7 @@
 	dist = rel_prevbc->offset + rel_prevbc->len;
 	if (dist < bc->offset) {
 	    outval = yasm_intnum_create_uint(bc->offset - dist);
-	    yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
+	    yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL, bc->line);
 	} else {
 	    dist -= bc->offset;
 	    outval = yasm_intnum_create_uint(dist);
@@ -491,27 +488,27 @@
 	if (value->rshift > 0) {
 	    /*@only@*/ yasm_intnum *shamt =
 		yasm_intnum_create_uint((unsigned long)value->rshift);
-	    yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
+	    yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt, bc->line);
 	    yasm_intnum_destroy(shamt);
 	}
 	/* Add in absolute portion */
 	if (intn)
-	    yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
+	    yasm_intnum_calc(outval, YASM_EXPR_ADD, intn, bc->line);
 	/* Output! */
-	if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
-				     bc, warn))
+	if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
+				     shift, bc, warn, bc->line))
 	    retval = -1;
 	yasm_intnum_destroy(outval);
     } else if (intn) {
 	/* Output just absolute portion */
-	if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc,
-				     warn))
+	if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize,
+				     shift, bc, warn, bc->line))
 	    retval = -1;
     } else {
 	/* No absolute or relative portions: output 0 */
 	outval = yasm_intnum_create_uint(0);
-	if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
-				     bc, warn))
+	if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
+				     shift, bc, warn, bc->line))
 	    retval = -1;
 	yasm_intnum_destroy(outval);
     }
diff --git a/libyasm/value.h b/libyasm/value.h
index 8687f9c..10f33b3 100644
--- a/libyasm/value.h
+++ b/libyasm/value.h
@@ -43,11 +43,9 @@
  * the value.
  * \param value	    value to be initialized
  * \param e	    expression (kept)
- * \param size	    value size (in bits)
  */
 void yasm_value_initialize(/*@out@*/ yasm_value *value,
-			   /*@null@*/ /*@kept@*/ yasm_expr *e,
-			   unsigned int size);
+			   /*@null@*/ /*@kept@*/ yasm_expr *e);
 
 /** Initialize a #yasm_value with just a symrec.  No processing is performed,
  * the symrec is simply stuck into value.rel and the other fields are
@@ -79,7 +77,6 @@
  * symrec offset within the absolute section.
  * \param value		value to store split portions into
  * \param e		expression input
- * \param size		value size (in bits)
  * \return Nonzero if the expr could not be split into a value for some
  *         reason (e.g. the relative portion was not added, but multiplied,
  *         etc).
@@ -89,8 +86,7 @@
  *       before the parse is complete will usually result in an error return.
  */
 int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
-			     /*@null@*/ /*@kept@*/ yasm_expr *e,
-			     unsigned int size);
+			     /*@null@*/ /*@kept@*/ yasm_expr *e);
 
 /** Output value if constant or PC-relative section-local.  This should be
  * used from objfmt yasm_output_value_func() functions.
@@ -98,6 +94,9 @@
  * \param value		value
  * \param buf		buffer for byte representation
  * \param destsize	destination size (in bytes)
+ * \param valsize	size (in bits)
+ * \param shift		left shift (in bits); may be negative to specify right
+ *			shift (standard warnings include truncation to boundary)
  * \param bc		current bytecode (usually passed into higher-level
  *			calling function)
  * \param warn		enables standard warnings: zero for none;
@@ -115,7 +114,7 @@
  */
 int yasm_value_output_basic
     (yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
-     yasm_bytecode *bc, int warn, yasm_arch *arch,
+     size_t valsize, int shift, yasm_bytecode *bc, int warn, yasm_arch *arch,
      yasm_calc_bc_dist_func calc_bc_dist);
 
 /** Print a value.  For debugging purposes.
@@ -127,7 +126,7 @@
 
 
 #ifndef YASM_DOXYGEN
-#define yasm_value_initialize(value, e, sz) \
+#define yasm_value_initialize(value, e) \
     do { \
 	(value)->abs = e; \
 	(value)->rel = NULL; \
@@ -137,10 +136,9 @@
 	(value)->curpos_rel = 0; \
 	(value)->ip_rel = 0; \
 	(value)->section_rel = 0; \
-	(value)->size = sz; \
     } while(0)
 
-#define yasm_value_init_sym(value, sym, sz) \
+#define yasm_value_init_sym(value, sym) \
     do { \
 	(value)->abs = NULL; \
 	(value)->rel = sym; \
@@ -150,7 +148,6 @@
 	(value)->curpos_rel = 0; \
 	(value)->ip_rel = 0; \
 	(value)->section_rel = 0; \
-	(value)->size = sz; \
     } while(0)
 
 #define yasm_value_delete(value) \
@@ -159,6 +156,9 @@
 	(value)->abs = NULL; \
 	(value)->rel = NULL; \
     } while(0)
+
+#define yasm_value_finalize(value) \
+    yasm_value_finalize_expr(value, (value)->abs)
 #endif
 
 #endif
diff --git a/m4/Makefile.inc b/m4/Makefile.inc
index 4dac7a1..6cd2152 100644
--- a/m4/Makefile.inc
+++ b/m4/Makefile.inc
@@ -26,5 +26,3 @@
 EXTRA_DIST += m4/progtest.m4
 EXTRA_DIST += m4/stdint_h.m4
 EXTRA_DIST += m4/uintmax_t.m4
-EXTRA_DIST += m4/pythonhead.m4
-EXTRA_DIST += m4/pyrex.m4
diff --git a/m4/pyrex.m4 b/m4/pyrex.m4
deleted file mode 100644
index b7610c2..0000000
--- a/m4/pyrex.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-dnl a macro to check for the installed Pyrex version; note PYTHON needs to
-dnl be set before this function is called.
-dnl  PYREX_CHECK_VERSION([MIN-VERSION], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
-AC_DEFUN([PYREX_CHECK_VERSION],
- [prog="import sys
-from Pyrex.Compiler.Version import version
-# split strings by '.' and convert to numeric.  Append some zeros
-# because we need at least 4 digits for the hex conversion.
-pyrexver = map(int, version.split('.')) + [[0, 0, 0]]
-pyrexverhex = 0
-for i in xrange(0, 4): pyrexverhex = (pyrexverhex << 8) + pyrexver[[i]]
-minver = map(int, '$1'.split('.')) + [[0, 0, 0]]
-minverhex = 0
-for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]]
-sys.exit(pyrexverhex < minverhex)"
-  AS_IF([AM_RUN_LOG([$PYTHON -c "$prog"])], [$2], [$3])])
-
diff --git a/m4/pythonhead.m4 b/m4/pythonhead.m4
deleted file mode 100644
index 1e0f2b6..0000000
--- a/m4/pythonhead.m4
+++ /dev/null
@@ -1,24 +0,0 @@
-dnl a macro to check for ability to create python extensions
-dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
-dnl function also defines PYTHON_INCLUDES
-AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
-[AC_REQUIRE([AM_PATH_PYTHON])
-AC_MSG_CHECKING(for headers required to compile python extensions)
-dnl deduce PYTHON_INCLUDES
-py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
-py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"`
-PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
-if test "$py_prefix" != "$py_exec_prefix"; then
-  PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
-fi
-AC_SUBST(PYTHON_INCLUDES)
-dnl check if the headers exist:
-save_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
-AC_TRY_CPP([#include <Python.h>],dnl
-[AC_MSG_RESULT(found)
-$1],dnl
-[AC_MSG_RESULT(not found)
-$2])
-CPPFLAGS="$save_CPPFLAGS"
-])
diff --git a/modules/arch/lc3b/lc3barch.c b/modules/arch/lc3b/lc3barch.c
index 4792b07..8d0aba5 100644
--- a/modules/arch/lc3b/lc3barch.c
+++ b/modules/arch/lc3b/lc3barch.c
@@ -99,42 +99,35 @@
 lc3b_get_fill(const yasm_arch *arch)
 {
     /* NOP pattern is all 0's per LC-3b Assembler 3.50 output */
-    static const unsigned char *fill[16] = {
+    static const char *fill[16] = {
 	NULL,		/* unused */
 	NULL,		/* 1 - illegal; all opcodes are 2 bytes long */
-	(const unsigned char *)
 	"\x00\x00",			/* 4 */
 	NULL,				/* 3 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00",		/* 4 */
 	NULL,				/* 5 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00\x00\x00",	/* 6 */
 	NULL,				/* 7 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00\x00\x00"	/* 8 */
 	"\x00\x00",
 	NULL,				/* 9 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00\x00\x00"	/* 10 */
 	"\x00\x00\x00\x00",
 	NULL,				/* 11 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00\x00\x00"	/* 12 */
 	"\x00\x00\x00\x00\x00\x00",
 	NULL,				/* 13 - illegal */
-	(const unsigned char *)
 	"\x00\x00\x00\x00\x00\x00"	/* 14 */
 	"\x00\x00\x00\x00\x00\x00\x00\x00",
 	NULL				/* 15 - illegal */
     };
-    return fill;
+    return (const unsigned char **)fill;
 }
 
 static unsigned int
 lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
 {
-    return 16;
+    return 2;
 }
 
 static unsigned long
@@ -154,10 +147,9 @@
 static int
 lc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
 		      unsigned char *buf, size_t destsize, size_t valsize,
-		      size_t shift, int warn)
+		      size_t shift, int warn, unsigned long line)
 {
-    yasm_error_set(YASM_ERROR_FLOATING_POINT,
-		   N_("LC-3b does not support floating point"));
+    yasm__error(line, N_("LC-3b does not support floating point"));
     return 1;
 }
 
@@ -198,6 +190,6 @@
     lc3b_ea_create_expr,
     lc3b_machines,
     "lc3b",
-    16,
+    2,
     2
 };
diff --git a/modules/arch/lc3b/lc3barch.h b/modules/arch/lc3b/lc3barch.h
index 7d199bb..52e918a 100644
--- a/modules/arch/lc3b/lc3barch.h
+++ b/modules/arch/lc3b/lc3barch.h
@@ -53,12 +53,15 @@
 
 void yasm_lc3b__bc_transform_insn(yasm_bytecode *bc, lc3b_insn *insn);
 
-void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
+void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+			  unsigned long line);
 
 yasm_arch_insnprefix yasm_lc3b__parse_check_insnprefix
-    (yasm_arch *arch, unsigned long data[4], const char *id, size_t id_len);
+    (yasm_arch *arch, unsigned long data[4], const char *id, size_t id_len,
+     unsigned long line);
 yasm_arch_regtmod yasm_lc3b__parse_check_regtmod
-    (yasm_arch *arch, unsigned long *data, const char *id, size_t id_len);
+    (yasm_arch *arch, unsigned long *data, const char *id, size_t id_len,
+     unsigned long line);
 
 void yasm_lc3b__finalize_insn
     (yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
@@ -69,5 +72,5 @@
 int yasm_lc3b__intnum_tobytes
     (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
      size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
-     int warn);
+     int warn, unsigned long line);
 #endif
diff --git a/modules/arch/lc3b/lc3bbc.c b/modules/arch/lc3b/lc3bbc.c
index 59e607f..f3ce2f1 100644
--- a/modules/arch/lc3b/lc3bbc.c
+++ b/modules/arch/lc3b/lc3bbc.c
@@ -52,8 +52,7 @@
     lc3b_bc_insn_print,
     yasm_bc_finalize_common,
     lc3b_bc_insn_resolve,
-    lc3b_bc_insn_tobytes,
-    0
+    lc3b_bc_insn_tobytes
 };
 
 
@@ -157,12 +156,11 @@
 	/*@dependent@*/ /*@null@*/ yasm_intnum *num2;
 	num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
 	if (!num2) {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("jump target too complex"));
+	    yasm__error(bc->line, N_("jump target too complex"));
 	    yasm_expr_destroy(temp);
 	    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
 	}
-	yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
+	yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
 	yasm_expr_destroy(temp);
     }
 
@@ -171,7 +169,7 @@
     rel -= 2;
     /* 9-bit signed, word-multiple displacement */
     if (rel < -512 || rel > 511) {
-	yasm_error_set(YASM_ERROR_OVERFLOW, N_("target out of range"));
+	yasm__error(bc->line, N_("target out of range"));
 	return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
     return YASM_BC_RESOLVE_MIN_LEN;
@@ -193,33 +191,28 @@
 	case LC3B_IMM_NONE:
 	    break;
 	case LC3B_IMM_4:
-	    insn->imm.size = 4;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 4, 0, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_5:
-	    insn->imm.size = 5;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 5, 0, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_6_WORD:
-	    insn->imm.size = 6;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 6, -1, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_6_BYTE:
-	    insn->imm.size = 6;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 6, 0, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_8:
-	    insn->imm.size = 8;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 8, -1, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_9_PC:
 	    /* Adjust relative displacement to end of bytecode */
-	    delta = yasm_intnum_create_int(-1);
+	    delta = yasm_intnum_create_int(-(long)bc->len);
 	    if (!insn->imm.abs)
 		insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta),
 						       bc->line);
@@ -229,13 +222,11 @@
 				     yasm_expr_expr(insn->imm.abs),
 				     yasm_expr_int(delta), bc->line);
 
-	    insn->imm.size = 9;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, d))
 		return 1;
 	    break;
 	case LC3B_IMM_9:
-	    insn->imm.size = 9;
-	    if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
+	    if (output_value(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, d))
 		return 1;
 	    break;
 	default:
@@ -249,9 +240,11 @@
 int
 yasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
 			  unsigned char *buf, size_t destsize, size_t valsize,
-			  int shift, const yasm_bytecode *bc, int warn)
+			  int shift, const yasm_bytecode *bc, int warn,
+			  unsigned long line)
 {
     /* Write value out. */
-    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
+    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
+			  line);
     return 0;
 }
diff --git a/modules/arch/lc3b/lc3bid.re b/modules/arch/lc3b/lc3bid.re
index 0c7e82a..f4f16fe 100644
--- a/modules/arch/lc3b/lc3bid.re
+++ b/modules/arch/lc3b/lc3bid.re
@@ -232,14 +232,14 @@
 
     if (!found) {
 	/* Didn't find a matching one */
-	yasm_error_set(YASM_ERROR_TYPE,
-		       N_("invalid combination of opcode and operands"));
+	yasm__error(bc->line,
+		    N_("invalid combination of opcode and operands"));
 	return;
     }
 
     /* Copy what we can from info */
     insn = yasm_xmalloc(sizeof(lc3b_insn));
-    yasm_value_initialize(&insn->imm, NULL, 0);
+    yasm_value_initialize(&insn->imm, NULL);
     insn->imm_type = LC3B_IMM_NONE;
     insn->origin_prevbc = NULL;
     insn->opcode = info->opcode;
@@ -258,7 +258,6 @@
     if (operands) {
 	for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
 	    op = yasm_operand_next(op), i++) {
-
 	    switch ((int)(info->operands[i] & OPA_MASK)) {
 		case OPA_None:
 		    /* Throw away the operand contents */
@@ -276,27 +275,18 @@
 		    insn->opcode |= ((unsigned int)(op->data.reg & 0x7)) << 6;
 		    break;
 		case OPA_Imm:
-		    insn->imm_type = (info->operands[i] & OPI_MASK)>>3;
 		    switch (op->type) {
 			case YASM_INSN__OPERAND_IMM:
-			    if (insn->imm_type == LC3B_IMM_6_WORD
-				|| insn->imm_type == LC3B_IMM_8
-				|| insn->imm_type == LC3B_IMM_9
-				|| insn->imm_type == LC3B_IMM_9_PC)
-				op->data.val = yasm_expr_create(YASM_EXPR_SHR,
-				    yasm_expr_expr(op->data.val),
-				    yasm_expr_int(yasm_intnum_create_uint(1)),
-				    op->data.val->line);
 			    if (yasm_value_finalize_expr(&insn->imm,
-							 op->data.val, 0))
-				yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				    N_("immediate expression too complex"));
+							 op->data.val))
+				yasm__error(bc->line,
+					    N_("immediate expression too complex"));
 			    break;
 			case YASM_INSN__OPERAND_REG:
 			    if (yasm_value_finalize_expr(&insn->imm,
 				    yasm_expr_create_ident(yasm_expr_int(
 				    yasm_intnum_create_uint(op->data.reg & 0x7)),
-				    bc->line), 0))
+				    bc->line)))
 				yasm_internal_error(N_("reg expr too complex?"));
 			    break;
 			default:
@@ -306,14 +296,15 @@
 		default:
 		    yasm_internal_error(N_("unknown operand action"));
 	    }
-	}
 
-	if (insn->imm_type == LC3B_IMM_9_PC) {
-	    insn->origin_prevbc = prev_bc;
-	    if (insn->imm.seg_of || insn->imm.rshift > 1
-		|| insn->imm.curpos_rel)
-		yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
-	    insn->imm.curpos_rel = 1;
+	    insn->imm_type = (info->operands[i] & OPI_MASK)>>3;
+	    if (insn->imm_type == LC3B_IMM_9_PC) {
+		insn->origin_prevbc = prev_bc;
+		if (insn->imm.seg_of || insn->imm.rshift
+		    || insn->imm.curpos_rel)
+		    yasm__error(bc->line, N_("invalid jump target"));
+		insn->imm.curpos_rel = 1;
+	    }
 	}
     }
 
@@ -329,13 +320,15 @@
 #define YYFILL(n)	(void)(n)
 
 void
-yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len)
+yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+		     unsigned long line)
 {
 }
 
 yasm_arch_regtmod
 yasm_lc3b__parse_check_regtmod(yasm_arch *arch, unsigned long *data,
-			       const char *oid, size_t id_len)
+			       const char *oid, size_t id_len,
+			       unsigned long line)
 {
     const YYCTYPE *id = (const YYCTYPE *)oid;
     /*const char *marker;*/
@@ -358,7 +351,8 @@
 
 yasm_arch_insnprefix
 yasm_lc3b__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
-				  const char *oid, size_t id_len)
+				  const char *oid, size_t id_len,
+				  unsigned long line)
 {
     const YYCTYPE *id = (const YYCTYPE *)oid;
     /*const char *marker;*/
diff --git a/modules/arch/lc3b/tests/lc3b-basic.asm b/modules/arch/lc3b/tests/lc3b-basic.asm
index 4cfa775..93b6f40 100644
--- a/modules/arch/lc3b/tests/lc3b-basic.asm
+++ b/modules/arch/lc3b/tests/lc3b-basic.asm
@@ -2,7 +2,7 @@
 add r4, r3, 22
 label:
 and r2, r1, r0
-and r2, r5, 5
+and r2, r5, 22
 brz label
 br label2
 
diff --git a/modules/arch/lc3b/tests/lc3b-basic.errwarn b/modules/arch/lc3b/tests/lc3b-basic.errwarn
index 8a232a0..e69de29 100644
--- a/modules/arch/lc3b/tests/lc3b-basic.errwarn
+++ b/modules/arch/lc3b/tests/lc3b-basic.errwarn
@@ -1 +0,0 @@
--:2: warning: value does not fit in signed 5 bit field
diff --git a/modules/arch/lc3b/tests/lc3b-basic.hex b/modules/arch/lc3b/tests/lc3b-basic.hex
index 9e90c96..d23ea43 100644
--- a/modules/arch/lc3b/tests/lc3b-basic.hex
+++ b/modules/arch/lc3b/tests/lc3b-basic.hex
@@ -4,7 +4,7 @@
 18 
 40 
 54 
-65 
+76 
 55 
 fd 
 05 
diff --git a/modules/arch/x86/x86arch.c b/modules/arch/x86/x86arch.c
index 52e486c..82b9ca5 100644
--- a/modules/arch/x86/x86arch.c
+++ b/modules/arch/x86/x86arch.c
@@ -119,8 +119,7 @@
 		    yasm_valparamhead *valparams,
 		    /*@unused@*/ /*@null@*/
 		    yasm_valparamhead *objext_valparams,
-		    /*@unused@*/ yasm_object *object,
-		    /*@unused@*/ unsigned long line)
+		    /*@unused@*/ yasm_object *object, unsigned long line)
 {
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     yasm_valparam *vp;
@@ -135,8 +134,7 @@
 	    (lval == 16 || lval == 32 || lval == 64))
 	    arch_x86->mode_bits = (unsigned char)lval;
 	else
-	    yasm_error_set(YASM_ERROR_VALUE, N_("invalid argument to [%s]"),
-			   "BITS");
+	    yasm__error(line, N_("invalid argument to [%s]"), "BITS");
 	return 0;
     } else
 	return 1;
@@ -148,166 +146,115 @@
     const yasm_arch_x86 *arch_x86 = (const yasm_arch_x86 *)arch;
 
     /* Fill patterns that GAS uses. */
-    static const unsigned char *fill16[16] = {
+    static const char *fill16[16] = {
 	NULL,				/* unused			*/
-	(const unsigned char *)
 	"\x90",				/* 1 - nop			*/
-	(const unsigned char *)
 	"\x89\xf6",			/* 2 - mov si, si		*/
-	(const unsigned char *)
 	"\x8d\x74\x00",			/* 3 - lea si, [si+byte 0]	*/
-	(const unsigned char *)
 	"\x8d\xb4\x00\x00",		/* 4 - lea si, [si+word 0]	*/
-	(const unsigned char *)
 	"\x90"				/* 5 - nop			*/
 	"\x8d\xb4\x00\x00",		/*     lea si, [si+word 0]	*/
-	(const unsigned char *)
 	"\x89\xf6"			/* 6 - mov si, si		*/
 	"\x8d\xbd\x00\x00",		/*     lea di, [di+word 0]	*/
-	(const unsigned char *)
 	"\x8d\x74\x00"			/* 7 - lea si, [si+byte 0]	*/
 	"\x8d\xbd\x00\x00",		/*     lea di, [di+word 0]	*/
-	(const unsigned char *)
 	"\x8d\xb4\x00\x00"		/* 8 - lea si, [si+word 0]	*/
 	"\x8d\xbd\x00\x00",		/*     lea di, [di+word 0]	*/
-	(const unsigned char *)
 	"\xeb\x07\x90\x90\x90\x90\x90"	/* 9 - jmp $+9; nop fill	*/
 	"\x90\x90",
-	(const unsigned char *)
 	"\xeb\x08\x90\x90\x90\x90\x90"	/* 10 - jmp $+10; nop fill	*/
 	"\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x09\x90\x90\x90\x90\x90"	/* 11 - jmp $+11; nop fill	*/
 	"\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0a\x90\x90\x90\x90\x90"	/* 12 - jmp $+12; nop fill	*/
 	"\x90\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0b\x90\x90\x90\x90\x90"	/* 13 - jmp $+13; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0c\x90\x90\x90\x90\x90"	/* 14 - jmp $+14; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0d\x90\x90\x90\x90\x90"	/* 15 - jmp $+15; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90\x90\x90"
     };
-    static const unsigned char *fill32[16] = {
+    static const char *fill32[16] = {
 	NULL,				/* unused			*/
-	(const unsigned char *)
 	"\x90",				/* 1 - nop			*/
-	(const unsigned char *)
 	"\x89\xf6",			/* 2 - mov esi, esi		*/
-	(const unsigned char *)
 	"\x8d\x76\x00",			/* 3 - lea esi, [esi+byte 0]	*/
-	(const unsigned char *)
 	"\x8d\x74\x26\x00",		/* 4 - lea esi, [esi*1+byte 0]	*/
-	(const unsigned char *)
 	"\x90"				/* 5 - nop			*/
 	"\x8d\x74\x26\x00",		/*     lea esi, [esi*1+byte 0]	*/
-	(const unsigned char *)
 	"\x8d\xb6\x00\x00\x00\x00",	/* 6 - lea esi, [esi+dword 0]	*/
-	(const unsigned char *)
 	"\x8d\xb4\x26\x00\x00\x00\x00",	/* 7 - lea esi, [esi*1+dword 0]	*/
-	(const unsigned char *)
 	"\x90"				/* 8 - nop			*/
 	"\x8d\xb4\x26\x00\x00\x00\x00",	/*     lea esi, [esi*1+dword 0]	*/
 #if 0
 	/* GAS uses these */
-	(const unsigned char *)
 	"\x89\xf6"			/* 9 - mov esi, esi		*/
 	"\x8d\xbc\x27\x00\x00\x00\x00",	/*     lea edi, [edi*1+dword 0]	*/
-	(const unsigned char *)
 	"\x8d\x76\x00"			/* 10 - lea esi, [esi+byte 0]	*/
 	"\x8d\xbc\x27\x00\x00\x00\x00",	/*      lea edi, [edi+dword 0]	*/
-	(const unsigned char *)
 	"\x8d\x74\x26\x00"		/* 11 - lea esi, [esi*1+byte 0]	*/
 	"\x8d\xbc\x27\x00\x00\x00\x00",	/*      lea edi, [edi*1+dword 0]*/
-	(const unsigned char *)
 	"\x8d\xb6\x00\x00\x00\x00"	/* 12 - lea esi, [esi+dword 0]	*/
 	"\x8d\xbf\x00\x00\x00\x00",	/*      lea edi, [edi+dword 0]	*/
-	(const unsigned char *)
 	"\x8d\xb6\x00\x00\x00\x00"	/* 13 - lea esi, [esi+dword 0]	*/
 	"\x8d\xbc\x27\x00\x00\x00\x00",	/*      lea edi, [edi*1+dword 0]*/
-	(const unsigned char *)
 	"\x8d\xb4\x26\x00\x00\x00\x00"	/* 14 - lea esi, [esi*1+dword 0]*/
 	"\x8d\xbc\x27\x00\x00\x00\x00",	/*      lea edi, [edi*1+dword 0]*/
 #else
 	/* But on newer processors, these are recommended */
-	(const unsigned char *)
 	"\xeb\x07\x90\x90\x90\x90\x90"	/* 9 - jmp $+9; nop fill	*/
 	"\x90\x90",
-	(const unsigned char *)
 	"\xeb\x08\x90\x90\x90\x90\x90"	/* 10 - jmp $+10; nop fill	*/
 	"\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x09\x90\x90\x90\x90\x90"	/* 11 - jmp $+11; nop fill	*/
 	"\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0a\x90\x90\x90\x90\x90"	/* 12 - jmp $+12; nop fill	*/
 	"\x90\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0b\x90\x90\x90\x90\x90"	/* 13 - jmp $+13; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90",
-	(const unsigned char *)
 	"\xeb\x0c\x90\x90\x90\x90\x90"	/* 14 - jmp $+14; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90\x90",
 #endif
-	(const unsigned char *)
 	"\xeb\x0d\x90\x90\x90\x90\x90"	/* 15 - jmp $+15; nop fill	*/
 	"\x90\x90\x90\x90\x90\x90\x90\x90"
     };
-    static const unsigned char *fill64[16] = {
+    static const char *fill64[16] = {
 	NULL,				/* unused			*/
-	(const unsigned char *)
 	"\x90",				/* 1 - nop			*/
-	(const unsigned char *)
 	"\x66\x90",			/* 2 - o16; nop			*/
-	(const unsigned char *)
 	"\x66\x66\x90",			/* 3 - o16; o16; nop		*/
-	(const unsigned char *)
 	"\x66\x66\x66\x90",		/* 4 - o16; o16; o16; nop	*/
-	(const unsigned char *)
 	"\x66\x66\x90\x66\x90",		/* 5 */
-	(const unsigned char *)
 	"\x66\x66\x90\x66\x66\x90",	/* 6 */
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x90",	/* 7 */
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x66"	/* 8 */
 	"\x90",
-	(const unsigned char *)
 	"\x66\x66\x90\x66\x66\x90\x66"	/* 9 */
 	"\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x90"	/* 10 */
 	"\x66\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x66"	/* 11 */
 	"\x90\x66\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x66"	/* 12 */
 	"\x90\x66\x66\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x90"	/* 13 */
 	"\x66\x66\x90\x66\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x66"	/* 14 */
 	"\x90\x66\x66\x90\x66\x66\x90",
-	(const unsigned char *)
 	"\x66\x66\x66\x90\x66\x66\x66"	/* 15 */
 	"\x90\x66\x66\x66\x90\x66\x66\x90"
     };
     switch (arch_x86->mode_bits) {
 	case 16:
-	    return fill16;
+	    return (const unsigned char **)fill16;
 	case 32:
-	    return fill32;
+	    return (const unsigned char **)fill32;
 	case 64:
-	    return fill64;
+	    return (const unsigned char **)fill64;
 	default:
-	    yasm_error_set(YASM_ERROR_VALUE,
-			   N_("Invalid mode_bits in x86_get_fill"));
+	    yasm_internal_error(N_("Invalid mode_bits in x86_get_fill"));
+	    /*@notreached@*/
 	    return NULL;
     }
 }
@@ -318,23 +265,23 @@
     switch ((x86_expritem_reg_size)(reg & ~0xFUL)) {
 	case X86_REG8:
 	case X86_REG8X:
-	    return 8;
+	    return 1;
 	case X86_REG16:
-	    return 16;
+	    return 2;
 	case X86_REG32:
 	case X86_CRREG:
 	case X86_DRREG:
 	case X86_TRREG:
-	    return 32;
+	    return 4;
 	case X86_REG64:
 	case X86_MMXREG:
-	    return 64;
+	    return 8;
 	case X86_XMMREG:
-	    return 128;
+	    return 16;
 	case X86_FPUREG:
-	    return 80;
+	    return 10;
 	default:
-	    yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size"));
+	    yasm_internal_error(N_("unknown register size"));
     }
     return 0;
 }
@@ -358,7 +305,7 @@
 		return 0;
 	    return reggroup | (regindex & 7);
 	default:
-	    yasm_error_set(YASM_ERROR_VALUE, N_("bad register group"));
+	    yasm_internal_error(N_("bad register group"));
     }
     return 0;
 }
@@ -419,7 +366,7 @@
 	    fprintf(f, "st%d", (int)(reg&0xF));
 	    break;
 	default:
-	    yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size"));
+	    yasm_internal_error(N_("unknown register size"));
     }
 }
 
@@ -461,6 +408,6 @@
     yasm_x86__ea_create_expr,
     x86_machines,
     "x86",
-    16,
+    2,
     1
 };
diff --git a/modules/arch/x86/x86arch.h b/modules/arch/x86/x86arch.h
index 88ed771..7e0229a 100644
--- a/modules/arch/x86/x86arch.h
+++ b/modules/arch/x86/x86arch.h
@@ -154,7 +154,8 @@
 				   0xff if unknown */
 } x86_effaddr;
 
-void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare);
+void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
+		       unsigned long line);
 
 void yasm_x86__ea_set_disponly(x86_effaddr *x86_ea);
 x86_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
@@ -169,7 +170,8 @@
 void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc,
 					 unsigned int addrsize);
 void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc,
-					  unsigned int prefix);
+					  unsigned int prefix,
+					  unsigned long line);
 
 /* Bytecode types */
 typedef struct x86_common {
@@ -274,7 +276,7 @@
 
 void yasm_x86__bc_apply_prefixes
     (x86_common *common, unsigned char *rex, int num_prefixes,
-     unsigned long **prefixes);
+     unsigned long **prefixes, unsigned long line);
 
 /* Check an effective address.  Returns 0 if EA was successfully determined,
  * 1 if invalid EA, or 2 if indeterminate EA.
@@ -282,16 +284,17 @@
 int yasm_x86__expr_checkea
     (x86_effaddr *x86_ea, unsigned char *addrsize, unsigned int bits,
      int address16_op, unsigned char *rex,
-     yasm_calc_bc_dist_func calc_bc_dist);
+     yasm_calc_bc_dist_func calc_bc_dist, unsigned long line);
 
-void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
+void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+			 unsigned long line);
 
 yasm_arch_insnprefix yasm_x86__parse_check_insnprefix
     (yasm_arch *arch, /*@out@*/ unsigned long data[4], const char *id,
-     size_t id_len);
+     size_t id_len, unsigned long line);
 yasm_arch_regtmod yasm_x86__parse_check_regtmod
     (yasm_arch *arch, /*@out@*/ unsigned long *data, const char *id,
-     size_t id_len);
+     size_t id_len, unsigned long line);
 
 void yasm_x86__finalize_insn
     (yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
@@ -301,11 +304,12 @@
 
 int yasm_x86__floatnum_tobytes
     (yasm_arch *arch, const yasm_floatnum *flt, unsigned char *buf,
-     size_t destsize, size_t valsize, size_t shift, int warn);
+     size_t destsize, size_t valsize, size_t shift, int warn,
+     unsigned long line);
 int yasm_x86__intnum_tobytes
     (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
      size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
-     int warn);
+     int warn, unsigned long line);
 
 unsigned int yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg);
 #endif
diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c
index 62ef563..4e6962f 100644
--- a/modules/arch/x86/x86bc.c
+++ b/modules/arch/x86/x86bc.c
@@ -83,8 +83,7 @@
     x86_bc_insn_print,
     yasm_bc_finalize_common,
     x86_bc_insn_resolve,
-    x86_bc_insn_tobytes,
-    0
+    x86_bc_insn_tobytes
 };
 
 static const yasm_bytecode_callback x86_bc_callback_jmp = {
@@ -92,8 +91,7 @@
     x86_bc_jmp_print,
     yasm_bc_finalize_common,
     x86_bc_jmp_resolve,
-    x86_bc_jmp_tobytes,
-    0
+    x86_bc_jmp_tobytes
 };
 
 static const yasm_bytecode_callback x86_bc_callback_jmpfar = {
@@ -101,8 +99,7 @@
     x86_bc_jmpfar_print,
     yasm_bc_finalize_common,
     x86_bc_jmpfar_resolve,
-    x86_bc_jmpfar_tobytes,
-    0
+    x86_bc_jmpfar_tobytes
 };
 
 int
@@ -149,11 +146,10 @@
 }
 
 void
-yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare)
+yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, unsigned long line)
 {
     if (yasm_value_finalize(&x86_ea->ea.disp))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("effective address too complex"));
+	yasm__error(line, N_("effective address too complex"));
     x86_ea->modrm &= 0xC7;		    /* zero spare/reg bits */
     x86_ea->modrm |= (spare << 3) & 0x38;   /* plug in provided bits */
 }
@@ -180,8 +176,8 @@
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
     x86_ea->ea.callback = &x86_ea_callback;
-    yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
-    x86_ea->ea.need_nonzero_len = 0;
+    yasm_value_initialize(&x86_ea->ea.disp, NULL);
+    x86_ea->ea.disp_len = 0;
     x86_ea->ea.need_disp = 0;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -220,8 +216,8 @@
 				 yasm_expr_reg(X86_RIP), e->line);
 	}
     }
-    yasm_value_initialize(&x86_ea->ea.disp, e, 0);
-    x86_ea->ea.need_nonzero_len = 0;
+    yasm_value_initialize(&x86_ea->ea.disp, e);
+    x86_ea->ea.disp_len = 0;
     x86_ea->ea.need_disp = 1;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -248,7 +244,8 @@
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
     x86_ea->ea.callback = &x86_ea_callback;
-    yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
+    yasm_value_initialize(&x86_ea->ea.disp, imm);
+    x86_ea->ea.disp_len = (unsigned char)im_len;
     x86_ea->ea.need_disp = 1;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -266,7 +263,8 @@
 
 void
 yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
-			    int num_prefixes, unsigned long **prefixes)
+			    int num_prefixes, unsigned long **prefixes,
+			    unsigned long line)
 {
     int i;
     int first = 1;
@@ -275,7 +273,7 @@
 	switch ((x86_parse_insn_prefix)prefixes[i][0]) {
 	    case X86_LOCKREP:
 		if (common->lockrep_pre != 0)
-		    yasm_warn_set(YASM_WARN_GENERAL,
+		    yasm__warning(YASM_WARN_GENERAL, line,
 			N_("multiple LOCK or REP prefixes, using leftmost"));
 		common->lockrep_pre = (unsigned char)prefixes[i][1];
 		break;
@@ -293,18 +291,18 @@
 		break;
 	    case X86_REX:
 		if (!rex)
-		    yasm_warn_set(YASM_WARN_GENERAL,
-				  N_("ignoring REX prefix on jump"));
+		    yasm__warning(YASM_WARN_GENERAL, line,
+			N_("ignoring REX prefix on jump"));
 		else if (*rex == 0xff)
-		    yasm_warn_set(YASM_WARN_GENERAL,
+		    yasm__warning(YASM_WARN_GENERAL, line,
 			N_("REX prefix not allowed on this instruction, ignoring"));
 		else {
 		    if (*rex != 0) {
 			if (first)
-			    yasm_warn_set(YASM_WARN_GENERAL,
+			    yasm__warning(YASM_WARN_GENERAL, line,
 				N_("overriding generated REX prefix"));
 			else
-			    yasm_warn_set(YASM_WARN_GENERAL,
+			    yasm__warning(YASM_WARN_GENERAL, line,
 				N_("multiple REX prefixes, using leftmost"));
 		    }
 		    /* Here we assume that we can't get this prefix in non
@@ -408,7 +406,8 @@
 	indent_level++;
 	fprintf(f, "\n");
 	yasm_value_print(&insn->imm->val, f, indent_level);
-	fprintf(f, "%*sSign=%u\n", indent_level, "",
+	fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
+		(unsigned int)insn->imm->len,
 		(unsigned int)insn->imm->sign);
 	indent_level--;
     }
@@ -534,7 +533,7 @@
 	 */
 	switch (yasm_x86__expr_checkea(&eat, &insn->common.addrsize,
 		insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
-		&insn->rex, calc_bc_dist)) {
+		&insn->rex, calc_bc_dist, bc->line)) {
 	    case 1:
 		yasm_expr_destroy(eat.ea.disp.abs);
 		/* failed, don't bother checking rest of insn */
@@ -549,13 +548,13 @@
 		break;
 	}
 
-	if (eat.ea.disp.size != 8) {
+	if (eat.ea.disp_len != 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 (eat.ea.need_nonzero_len)
-		eat.ea.disp.size = (insn->common.addrsize == 16) ? 16 : 32;
+	    if (eat.ea.disp_len == 0xff)
+		eat.ea.disp_len = (insn->common.addrsize == 16) ? 2U : 4U;
 	}
 
 	/* Handle address16 postop case */
@@ -563,28 +562,27 @@
 	    insn->common.addrsize = 0;
 
 	/* If we had forced ea->len but had to override, save it now */
-	if (x86_ea->ea.disp.size != 0 &&
-	    x86_ea->ea.disp.size != eat.ea.disp.size)
-	    x86_ea->ea.disp.size = eat.ea.disp.size;
+	if (x86_ea->ea.disp_len != 0 && x86_ea->ea.disp_len != eat.ea.disp_len)
+	    x86_ea->ea.disp_len = eat.ea.disp_len;
 
 	if (save) {
 	    eat.ea.disp.abs = x86_ea->ea.disp.abs; /* Copy back original */
 	    *x86_ea = eat;	/* structure copy */
-	    if (x86_ea->ea.disp.size == 0) {
+	    if (x86_ea->ea.disp_len == 0) {
 		yasm_value_delete(&x86_ea->ea.disp);
 		x86_ea->ea.need_disp = 0;
 	    }
 	}
 
 	/* Compute length of ea and add to total */
-	bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + eat.ea.disp.size/8;
+	bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + eat.ea.disp_len;
 	bc->len += (eat.ea.segreg != 0) ? 1 : 0;
     }
 
     if (imm) {
 	/*@null@*/ yasm_expr *temp = NULL;
 	const yasm_intnum *num = NULL;
-	unsigned int immlen = imm->val.size;
+	unsigned int immlen = imm->len;
 	long val;
 
 	if (imm->val.abs) {
@@ -608,11 +606,11 @@
 		    /* We can use the sign-extended byte form: shorten
 		     * the immediate length to 1.
 		     */
-		    immlen = 8;
+		    immlen = 1;
 		    if (save) {
 			/* Make the byte form permanent. */
 			insn->opcode.opcode[0] = insn->opcode.opcode[1];
-			imm->val.size = 8;
+			imm->len = 1;
 			if (insn->opcode.opcode[2] != 0) {
 			    insn->opcode.opcode[1] = insn->opcode.opcode[2];
 			    insn->opcode.len++;
@@ -629,7 +627,7 @@
 		/* Handle signext_imm32 postop special-casing */
 		if (!num || yasm_intnum_check_size(num, 32, 0, 1)) {
 		    bc->len++;  /* Due to ModRM byte */
-		    immlen = 32;
+		    immlen = 4;
 		    if (save) {
 			/* Throwaway REX byte */
 			unsigned char rex_temp = 0;
@@ -643,7 +641,7 @@
 
 			/* Make the imm32s form permanent. */
 			insn->opcode.opcode[0] = insn->opcode.opcode[1];
-			imm->val.size = 32;
+			imm->len = 4;
 		    }
 		}
 		/* Not really necessary, but saves confusion over it. */
@@ -679,7 +677,7 @@
 
 	yasm_expr_destroy(temp);
 
-	bc->len += immlen/8;
+	bc->len += immlen;
     }
 
     bc->len += insn->opcode.len;
@@ -722,8 +720,7 @@
 	    if (save) {
 		/* does a short form exist? */
 		if (jmp->shortop.len == 0) {
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("short jump does not exist"));
+		    yasm__error(bc->line, N_("short jump does not exist"));
 		    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
 		}
 
@@ -746,12 +743,11 @@
 		    num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
 		    if (!num2) {
 			yasm_expr_destroy(temp);
-			yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				       N_("jump target too complex"));
+			yasm__error(bc->line, N_("jump target too complex"));
 			return YASM_BC_RESOLVE_ERROR |
 			    YASM_BC_RESOLVE_UNKNOWN_LEN;
 		    }
-		    yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
+		    yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
 		    yasm_expr_destroy(temp);
 		}
 
@@ -760,8 +756,7 @@
 		rel -= jmp->shortop.len+1;
 		/* short displacement must fit in -128 <= rel <= +127 */
 		if (rel < -128 || rel > 127) {
-		    yasm_error_set(YASM_ERROR_OVERFLOW,
-				   N_("short jump out of range"));
+		    yasm__error(bc->line, N_("short jump out of range"));
 		    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
 		}
 	    }
@@ -771,8 +766,7 @@
 	    jrtype = JMP_NEAR;
 	    if (save) {
 		if (jmp->nearop.len == 0) {
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("near jump does not exist"));
+		    yasm__error(bc->line, N_("near jump does not exist"));
 		    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
 		}
 	    }
@@ -802,11 +796,10 @@
 		num2 = yasm_expr_get_intnum(&temp, calc_bc_dist);
 		if (!num2) {
 		    yasm_expr_destroy(temp);
-		    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				   N_("jump target too complex"));
+		    yasm__error(bc->line, N_("jump target too complex"));
 		    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
 		}
-		yasm_intnum_calc(num, YASM_EXPR_ADD, num2);
+		yasm_intnum_calc(num, YASM_EXPR_ADD, num2, bc->line);
 		yasm_expr_destroy(temp);
 	    }
 
@@ -944,7 +937,6 @@
 	if (x86_ea->ea.need_disp) {
 	    x86_effaddr eat = *x86_ea;  /* structure copy */
 	    unsigned char addrsize = insn->common.addrsize;
-	    unsigned int disp_len = x86_ea->ea.disp.size/8;
 
 	    eat.valid_modrm = 0;    /* force checkea to actually run */
 
@@ -956,7 +948,7 @@
 		if (yasm_x86__expr_checkea
 		    (&eat, &addrsize, insn->common.mode_bits,
 		     insn->postop == X86_POSTOP_ADDRESS16, &insn->rex,
-		     yasm_common_calc_bc_dist))
+		     yasm_common_calc_bc_dist, bc->line))
 		    yasm_internal_error(N_("checkea failed"));
 		x86_ea->ea.disp.abs = eat.ea.disp.abs;
 	    }
@@ -974,21 +966,21 @@
 					 yasm_expr_expr(x86_ea->ea.disp.abs),
 					 yasm_expr_int(delta), bc->line);
 	    }
-	    if (output_value(&x86_ea->ea.disp, *bufp, disp_len,
+	    if (output_value(&x86_ea->ea.disp, *bufp, x86_ea->ea.disp_len,
+			     (size_t)(x86_ea->ea.disp_len*8), 0,
 			     (unsigned long)(*bufp-bufp_orig), bc, 1, d))
 		return 1;
-	    *bufp += disp_len;
+	    *bufp += x86_ea->ea.disp_len;
 	}
     }
 
     /* Immediate (if required) */
     if (imm) {
-	unsigned int imm_len = imm->val.size/8;
-	if (output_value(&imm->val, *bufp, imm_len,
+	if (output_value(&imm->val, *bufp, imm->len, (size_t)(imm->len*8), 0,
 			 (unsigned long)(*bufp-bufp_orig), bc, imm->sign?-1:1,
 			 d))
 	    return 1;
-	*bufp += imm_len;
+	*bufp += imm->len;
     }
 
     return 0;
@@ -1034,8 +1026,7 @@
 				     yasm_expr_expr(jmp->target.abs),
 				     yasm_expr_int(delta), bc->line);
 
-	    jmp->target.size = 8;
-	    if (output_value(&jmp->target, *bufp, 1,
+	    if (output_value(&jmp->target, *bufp, 1, 8, 0,
 			     (unsigned long)(*bufp-bufp_orig), bc, -1, d))
 		return 1;
 	    *bufp += 1;
@@ -1044,8 +1035,7 @@
 	case JMP_NEAR:
 	    /* 2/4 byte relative displacement (depending on operand size) */
 	    if (jmp->nearop.len == 0) {
-		yasm_error_set(YASM_ERROR_TYPE,
-			       N_("near jump does not exist"));
+		yasm__error(bc->line, N_("near jump does not exist"));
 		return 1;
 	    }
 
@@ -1065,8 +1055,7 @@
 				     yasm_expr_expr(jmp->target.abs),
 				     yasm_expr_int(delta), bc->line);
 
-	    jmp->target.size = i*8;
-	    if (output_value(&jmp->target, *bufp, i,
+	    if (output_value(&jmp->target, *bufp, i, i*8, 0,
 			     (unsigned long)(*bufp-bufp_orig), bc, -1, d))
 		return 1;
 	    *bufp += i;
@@ -1096,13 +1085,11 @@
 
     /* Absolute displacement: segment and offset */
     i = (opersize == 16) ? 2 : 4;
-    jmpfar->offset.size = i*8;
-    if (output_value(&jmpfar->offset, *bufp, i,
+    if (output_value(&jmpfar->offset, *bufp, i, i*8, 0,
 		     (unsigned long)(*bufp-bufp_orig), bc, 1, d))
 	return 1;
     *bufp += i;
-    jmpfar->segment.size = 16;
-    if (output_value(&jmpfar->segment, *bufp, 2,
+    if (output_value(&jmpfar->segment, *bufp, 2, 2*8, 0,
 		     (unsigned long)(*bufp-bufp_orig), bc, 1, d))
 	return 1;
     *bufp += 2;
@@ -1113,9 +1100,11 @@
 int
 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
 			 unsigned char *buf, size_t destsize, size_t valsize,
-			 int shift, const yasm_bytecode *bc, int warn)
+			 int shift, const yasm_bytecode *bc, int warn,
+			 unsigned long line)
 {
     /* Write value out. */
-    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
+    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
+			  line);
     return 0;
 }
diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c
index b83d797..67ad42c 100644
--- a/modules/arch/x86/x86expr.c
+++ b/modules/arch/x86/x86expr.c
@@ -261,7 +261,7 @@
 
     /*@-unqualifiedtrans@*/
     *ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, calc_bc_dist, NULL,
-				NULL, NULL);
+				NULL, NULL, NULL);
 
     /* Check for WRT rip first */
     wrt = yasm_expr_extract_wrt(ep);
@@ -297,7 +297,7 @@
 	case 2:
 	    /* Need to simplify again */
 	    *ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, NULL, NULL,
-					NULL, NULL);
+					NULL, NULL, NULL);
 	    e = *ep;
 	    break;
 	default:
@@ -401,7 +401,7 @@
 /* Calculate the displacement length, if possible.
  * Takes several extra inputs so it can be used by both 32-bit and 16-bit
  * expressions:
- *  wordsize=16 for 16-bit, =32 for 32-bit.
+ *  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).
  * Returns 0 if successfully calculated, 1 if not.
@@ -409,42 +409,42 @@
 /*@-nullstate@*/
 static int
 x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
-			 int dispreq)
+			 int dispreq, unsigned long line)
 {
     /*@null@*/ const yasm_intnum *intn = NULL;
     long dispval;
 
     x86_ea->valid_modrm = 0;	/* default to not yet valid */
 
-    switch (x86_ea->ea.disp.size) {
+    switch (x86_ea->ea.disp_len) {
 	case 0:
 	    break;
 	/* If not 0, the displacement length was forced; set the Mod bits
 	 * appropriately and we're done with the ModRM byte.
 	 */
-	case 8:
+	case 1:
 	    /* Byte is not valid override in noreg case; fix it. */
 	    if (noreg) {
-		x86_ea->ea.disp.size = 0;
-		yasm_warn_set(YASM_WARN_GENERAL,
+		x86_ea->ea.disp_len = 0;
+		yasm__warning(YASM_WARN_GENERAL, line,
 			      N_("invalid displacement size; fixed"));
 	    } else
 		x86_ea->modrm |= 0100;
 	    x86_ea->valid_modrm = 1;
 	    break;
-	case 16:
-	case 32:
-	    if (wordsize != x86_ea->ea.disp.size) {
-		yasm_error_set(YASM_ERROR_VALUE,
+	case 2:
+	case 4:
+	    if (wordsize != x86_ea->ea.disp_len) {
+		yasm__error(line,
 		    N_("invalid effective address (displacement size)"));
 		return 1;
 	    }
 	    /* 2/4 is not valid override in noreg case; fix it. */
 	    if (noreg) {
-		if (wordsize != x86_ea->ea.disp.size)
-		    yasm_warn_set(YASM_WARN_GENERAL,
+		if (wordsize != x86_ea->ea.disp_len)
+		    yasm__warning(YASM_WARN_GENERAL, line,
 				  N_("invalid displacement size; fixed"));
-		x86_ea->ea.disp.size = 0;
+		x86_ea->ea.disp_len = 0;
 	    } else
 		x86_ea->modrm |= 0200;
 	    x86_ea->valid_modrm = 1;
@@ -454,7 +454,7 @@
 	    yasm_internal_error(N_("strange EA displacement size"));
     }
 
-    if (x86_ea->ea.disp.size == 0) {
+    if (x86_ea->ea.disp_len == 0) {
 	/* the displacement length hasn't been forced (or the forcing wasn't
 	 * valid), try to determine what it is.
 	 */
@@ -463,14 +463,16 @@
 	     * and as the Mod bits are set to 0 by the caller, we're done
 	     * with the ModRM byte.
 	     */
-	    x86_ea->ea.disp.size = wordsize;
+	    x86_ea->ea.disp_len = wordsize;
 	    x86_ea->valid_modrm = 1;
 	    return 0;
 	} 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.
 	     */
-	    x86_ea->ea.need_nonzero_len = 1;
+	    x86_ea->ea.disp_len = 0xff;
 	}
 
 	if (x86_ea->ea.disp.rel ||
@@ -479,7 +481,7 @@
 	    /* expr still has unknown values or is relative:
 	     * assume 16/32-bit disp
 	     */
-	    x86_ea->ea.disp.size = wordsize;
+	    x86_ea->ea.disp_len = wordsize;
 	    x86_ea->modrm |= 0200;
 	    x86_ea->valid_modrm = 1;
 	    return 0;
@@ -488,8 +490,8 @@
 	/* don't try to find out what size displacement we have if
 	 * displen is known.
 	 */
-	if (x86_ea->ea.disp.size != 0) {
-	    if (x86_ea->ea.disp.size == 8)
+	if (x86_ea->ea.disp_len != 0 && x86_ea->ea.disp_len != 0xff) {
+	    if (x86_ea->ea.disp_len == 1)
 		x86_ea->modrm |= 0100;
 	    else
 		x86_ea->modrm |= 0200;
@@ -503,7 +505,7 @@
 	    dispval = 0;
 
 	/* Figure out what size displacement we will have. */
-	if (!x86_ea->ea.need_nonzero_len && dispval == 0) {
+	if (x86_ea->ea.disp_len != 0xff && dispval == 0) {
 	    /* if we know that the displacement is 0 right now,
 	     * go ahead and delete the expr and make it so no
 	     * displacement value is included in the output.
@@ -518,11 +520,11 @@
 	    x86_ea->ea.need_disp = 0;
 	} else if (dispval >= -128 && dispval <= 127) {
 	    /* It fits into a signed byte */
-	    x86_ea->ea.disp.size = 8;
+	    x86_ea->ea.disp_len = 1;
 	    x86_ea->modrm |= 0100;
 	} else {
 	    /* It's a 16/32-bit displacement */
-	    x86_ea->ea.disp.size = wordsize;
+	    x86_ea->ea.disp_len = wordsize;
 	    x86_ea->modrm |= 0200;
 	}
 	x86_ea->valid_modrm = 1;	/* We're done with ModRM */
@@ -560,7 +562,7 @@
 int
 yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
 		       unsigned int bits, int address16_op, unsigned char *rex,
-		       yasm_calc_bc_dist_func calc_bc_dist)
+		       yasm_calc_bc_dist_func calc_bc_dist, unsigned long line)
 {
     int retval;
 
@@ -570,23 +572,23 @@
 	 * - what registers are used in the expression
 	 * - the bits setting
 	 */
-	switch (x86_ea->ea.disp.size) {
-	    case 16:
+	switch (x86_ea->ea.disp_len) {
+	    case 2:
 		/* must be 16-bit */
 		*addrsize = 16;
 		break;
-	    case 64:
+	    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 (x86_ea->need_modrm || x86_ea->need_sib) {
-		    yasm_error_set(YASM_ERROR_VALUE,
+		    yasm__error(line,
 			N_("invalid effective address (displacement size)"));
 		    return 1;
 		}
 		*addrsize = 64;
 		break;
-	    case 32:
+	    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).
@@ -644,7 +646,7 @@
 
 	/* We can only do 64-bit addresses in 64-bit mode. */
 	if (*addrsize == 64 && bits != 64) {
-	    yasm_error_set(YASM_ERROR_TYPE,
+	    yasm__error(line,
 		N_("invalid effective address (64-bit in non-64-bit mode)"));
 	    return 1;
 	}
@@ -659,8 +661,7 @@
 		     &reg3264_data, x86_expr_checkea_get_reg3264,
 		     calc_bc_dist)) {
 		case 1:
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("invalid effective address"));
+		    yasm__error(line, N_("invalid effective address"));
 		    return 1;
 		case 2:
 		    if (pcrel) {
@@ -690,8 +691,7 @@
 	 */
 	for (i=0; i<17; i++) {
 	    if (reg3264mult[i] < 0) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("invalid effective address"));
+		yasm__error(line, N_("invalid effective address"));
 		return 1;
 	    }
 	    if (i != indexreg && reg3264mult[i] == 1 &&
@@ -733,8 +733,7 @@
 	 */
 	for (i=0; i<17; i++)
 	    if (i != basereg && i != indexreg && reg3264mult[i] != 0) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("invalid effective address"));
+		yasm__error(line, N_("invalid effective address"));
 		return 1;
 	    }
 
@@ -742,7 +741,7 @@
 	if (indexreg != REG3264_NONE && reg3264mult[indexreg] != 1 &&
 	    reg3264mult[indexreg] != 2 && reg3264mult[indexreg] != 4 &&
 	    reg3264mult[indexreg] != 8) {
-	    yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
+	    yasm__error(line, N_("invalid effective address"));
 	    return 1;
 	}
 
@@ -752,8 +751,7 @@
 	     * legal.
 	     */
 	    if (reg3264mult[REG3264_ESP] > 1 || basereg == REG3264_ESP) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("invalid effective address"));
+		yasm__error(line, N_("invalid effective address"));
 		return 1;
 	    }
 	    /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */
@@ -764,7 +762,7 @@
 	/* RIP is only legal if it's the ONLY register used. */
 	if (indexreg == REG64_RIP ||
 	    (basereg == REG64_RIP && indexreg != REG3264_NONE)) {
-	    yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
+	    yasm__error(line, N_("invalid effective address"));
 	    return 1;
 	}
 
@@ -795,7 +793,7 @@
 	    x86_ea->need_sib = 0;
 	    /* RIP always requires a 32-bit displacement */
 	    x86_ea->valid_modrm = 1;
-	    x86_ea->ea.disp.size = 32;
+	    x86_ea->ea.disp_len = 4;
 	    return 0;
 	} else if (indexreg == REG3264_NONE) {
 	    /* basereg only */
@@ -806,7 +804,7 @@
 	    if (yasm_x86__set_rex_from_reg(rex, &low3,
 					   (unsigned int)(X86_REG64 | basereg),
 					   bits, X86_REX_B)) {
-		yasm_error_set(YASM_ERROR_TYPE,
+		yasm__error(line,
 		    N_("invalid combination of operands and effective address"));
 		return 1;
 	    }
@@ -836,7 +834,7 @@
 		if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int)
 					       (X86_REG64 | basereg), bits,
 					       X86_REX_B)) {
-		    yasm_error_set(YASM_ERROR_TYPE,
+		    yasm__error(line,
 			N_("invalid combination of operands and effective address"));
 		    return 1;
 		}
@@ -851,7 +849,7 @@
 		if (yasm_x86__set_rex_from_reg(rex, &low3, (unsigned int)
 					       (X86_REG64 | indexreg), bits,
 					       X86_REX_X)) {
-		    yasm_error_set(YASM_ERROR_TYPE,
+		    yasm__error(line,
 			N_("invalid combination of operands and effective address"));
 		    return 1;
 		}
@@ -875,8 +873,8 @@
 
 	/* Calculate displacement length (if possible) */
 	retval = x86_checkea_calc_displen
-	    (x86_ea, 32, basereg == REG3264_NONE,
-	     basereg == REG3264_EBP || basereg == REG64_R13);
+	    (x86_ea, 4, basereg == REG3264_NONE,
+	     basereg == REG3264_EBP || basereg == REG64_R13, line);
 	return retval;
     } else if (*addrsize == 16 && x86_ea->need_modrm && !x86_ea->valid_modrm) {
 	static const unsigned char modrm16[16] = {
@@ -898,7 +896,7 @@
 
 	/* 64-bit mode does not allow 16-bit addresses */
 	if (bits == 64 && !address16_op) {
-	    yasm_error_set(YASM_ERROR_TYPE,
+	    yasm__error(line,
 		N_("16-bit addresses not supported in 64-bit mode"));
 	    return 1;
 	}
@@ -914,8 +912,7 @@
 		    (&x86_ea->ea.disp.abs, (int *)NULL, &pcrel, bits,
 		     &reg16mult, x86_expr_checkea_get_reg16, calc_bc_dist)) {
 		case 1:
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("invalid effective address"));
+		    yasm__error(line, N_("invalid effective address"));
 		    return 1;
 		case 2:
 		    if (pcrel) {
@@ -935,7 +932,7 @@
 	/* reg multipliers not 0 or 1 are illegal. */
 	if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 ||
 	    reg16mult.bp & ~1) {
-	    yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
+	    yasm__error(line, N_("invalid effective address"));
 	    return 1;
 	}
 
@@ -951,7 +948,7 @@
 
 	/* Check the modrm value for invalid combinations. */
 	if (modrm16[havereg] & 0070) {
-	    yasm_error_set(YASM_ERROR_VALUE, N_("invalid effective address"));
+	    yasm__error(line, N_("invalid effective address"));
 	    return 1;
 	}
 
@@ -960,30 +957,30 @@
 
 	/* Calculate displacement length (if possible) */
 	retval = x86_checkea_calc_displen
-	    (x86_ea, 16, havereg == HAVE_NONE, havereg == HAVE_BP);
+	    (x86_ea, 2, havereg == HAVE_NONE, havereg == HAVE_BP, line);
 	return retval;
     } else if (!x86_ea->need_modrm && !x86_ea->need_sib) {
 	/* Special case for MOV MemOffs opcode: displacement but no modrm. */
 	switch (*addrsize) {
 	    case 64:
 		if (bits != 64) {
-		    yasm_error_set(YASM_ERROR_TYPE,
+		    yasm__error(line,
 			N_("invalid effective address (64-bit in non-64-bit mode)"));
 		    return 1;
 		}
-		x86_ea->ea.disp.size = 64;
+		x86_ea->ea.disp_len = 8;
 		break;
 	    case 32:
-		x86_ea->ea.disp.size = 32;
+		x86_ea->ea.disp_len = 4;
 		break;
 	    case 16:
 		/* 64-bit mode does not allow 16-bit addresses */
 		if (bits == 64 && !address16_op) {
-		    yasm_error_set(YASM_ERROR_TYPE,
+		    yasm__error(line,
 			N_("16-bit addresses not supported in 64-bit mode"));
 		    return 1;
 		}
-		x86_ea->ea.disp.size = 16;
+		x86_ea->ea.disp_len = 2;
 		break;
 	}
     }
@@ -993,14 +990,13 @@
 int
 yasm_x86__floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
 			   unsigned char *buf, size_t destsize, size_t valsize,
-			   size_t shift, int warn)
+			   size_t shift, int warn, unsigned long line)
 {
     if (!yasm_floatnum_check_size(flt, valsize)) {
-	yasm_error_set(YASM_ERROR_FLOATING_POINT,
-		       N_("invalid floating point constant size"));
+	yasm__error(line, N_("invalid floating point constant size"));
 	return 1;
     }
 
-    yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn);
+    yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn, line);
     return 0;
 }
diff --git a/modules/arch/x86/x86id.c b/modules/arch/x86/x86id.c
index ebabf2b..5262f1e 100644
--- a/modules/arch/x86/x86id.c
+++ b/modules/arch/x86/x86id.c
@@ -2072,10 +2072,9 @@
 	case X86_FAR:
 	    /* "FAR imm" target needs to become "seg imm:imm". */
 	    if (yasm_value_finalize_expr(&jmpfar->offset,
-					 yasm_expr_copy(op->data.val), 0)
-		|| yasm_value_finalize_expr(&jmpfar->segment, op->data.val, 16))
-		yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			       N_("jump target expression too complex"));
+					 yasm_expr_copy(op->data.val))
+		|| yasm_value_finalize_expr(&jmpfar->segment, op->data.val))
+		yasm__error(bc->line, N_("jump target expression too complex"));
 	    jmpfar->segment.seg_of = 1;
 	    break;
 	case X86_FAR_SEGOFF:
@@ -2083,19 +2082,17 @@
 	    segment = yasm_expr_extract_segoff(&op->data.val);
 	    if (!segment)
 		yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
-	    if (yasm_value_finalize_expr(&jmpfar->segment, segment, 16))
-		yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			       N_("jump target segment too complex"));
-	    if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, 0))
-		yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			       N_("jump target offset too complex"));
+	    if (yasm_value_finalize_expr(&jmpfar->segment, segment))
+		yasm__error(bc->line, N_("jump target segment too complex"));
+	    if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val))
+		yasm__error(bc->line, N_("jump target offset too complex"));
 	    break;
 	default:
 	    yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
     }
 
     yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL, num_prefixes,
-				prefixes);
+				prefixes, bc->line);
 
     /* Transform the bytecode */
     yasm_x86__bc_transform_jmpfar(bc, jmpfar);
@@ -2124,11 +2121,10 @@
 
     jmp = yasm_xmalloc(sizeof(x86_jmp));
     x86_finalize_common(&jmp->common, jinfo, mode_bits);
-    if (yasm_value_finalize_expr(&jmp->target, op->data.val, 0))
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("jump target expression too complex"));
+    if (yasm_value_finalize_expr(&jmp->target, op->data.val))
+	yasm__error(bc->line, N_("jump target expression too complex"));
     if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
-	yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
+	yasm__error(bc->line, N_("invalid jump target"));
     jmp->target.curpos_rel = 1;
 
     /* Need to save jump origin for relative jumps. */
@@ -2198,11 +2194,11 @@
     }
 
     if ((jmp->op_sel == JMP_SHORT_FORCED) && (jmp->nearop.len == 0))
-	yasm_error_set(YASM_ERROR_TYPE,
-		       N_("no SHORT form of that jump instruction exists"));
+	yasm__error(bc->line,
+		    N_("no SHORT form of that jump instruction exists"));
     if ((jmp->op_sel == JMP_NEAR_FORCED) && (jmp->shortop.len == 0))
-	yasm_error_set(YASM_ERROR_TYPE,
-		       N_("no NEAR form of that jump instruction exists"));
+	yasm__error(bc->line,
+		    N_("no NEAR form of that jump instruction exists"));
 
     if (jmp->op_sel == JMP_NONE) {
 	if (jmp->nearop.len == 0)
@@ -2212,7 +2208,7 @@
     }
 
     yasm_x86__bc_apply_prefixes((x86_common *)jmp, NULL, num_prefixes,
-				prefixes);
+				prefixes, bc->line);
 
     /* Transform the bytecode */
     yasm_x86__bc_transform_jmp(bc, jmp);
@@ -2240,9 +2236,9 @@
     unsigned char im_sign;
     unsigned char spare;
     int i;
-    unsigned int size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
+    unsigned int size_lookup[] = {0, 1, 2, 4, 8, 10, 16, 0};
 
-    size_lookup[7] = mode_bits;
+    size_lookup[7] = mode_bits>>3;
 
     if (!info) {
 	num_info = 1;
@@ -2253,7 +2249,7 @@
      * of 3 operands.
      */
     if (num_operands > 3) {
-	yasm_error_set(YASM_ERROR_TYPE, N_("too many operands"));
+	yasm__error(bc->line, N_("too many operands"));
 	return;
     }
     ops[0] = ops[1] = ops[2] = ops[3] = NULL;
@@ -2282,7 +2278,7 @@
 	    if (!op->deref && (op->type == YASM_INSN__OPERAND_REG
 			       || (op->type == YASM_INSN__OPERAND_MEMORY
 				   && op->data.ea->strong)))
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, bc->line,
 			      N_("indirect call without `*'"));
 	    if (!op->deref && op->type == YASM_INSN__OPERAND_MEMORY
 		&& !op->data.ea->strong) {
@@ -2290,7 +2286,7 @@
 		 * actually an immediate for the purposes of relative jumps.
 		 */
 		if (op->data.ea->segreg != 0)
-		    yasm_warn_set(YASM_WARN_GENERAL,
+		    yasm__warning(YASM_WARN_GENERAL, bc->line,
 				  N_("skipping prefixes on this instruction"));
 		imm = op->data.ea->disp.abs;
 		op->data.ea->disp.abs = NULL;
@@ -2560,9 +2556,9 @@
 	    /* Check for 64-bit effective address size in NASM mode */
 	    if (suffix == 0 && op->type == YASM_INSN__OPERAND_MEMORY) {
 		if ((info->operands[i] & OPEAS_MASK) == OPEAS_64) {
-		    if (op->data.ea->disp.size != 64)
+		    if (op->data.ea->disp_len != 8)
 			mismatch = 1;
-		} else if (op->data.ea->disp.size == 64)
+		} else if (op->data.ea->disp_len == 8)
 		    mismatch = 1;
 	    }
 
@@ -2605,8 +2601,8 @@
 
     if (!found) {
 	/* Didn't find a matching one */
-	yasm_error_set(YASM_ERROR_TYPE,
-		       N_("invalid combination of opcode and operands"));
+	yasm__error(bc->line,
+		    N_("invalid combination of opcode and operands"));
 	return;
     }
 
@@ -2619,12 +2615,10 @@
 	    switch ((int)((info->modifiers & MOD_ExtIndex_MASK)
 			  >> MOD_ExtIndex_SHIFT)) {
 		case 0:
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("mismatch in operand sizes"));
+		    yasm__error(bc->line, N_("mismatch in operand sizes"));
 		    break;
 		case 1:
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("operand size not specified"));
+		    yasm__error(bc->line, N_("operand size not specified"));
 		    break;
 		default:
 		    yasm_internal_error(N_("unrecognized x86 ext mod index"));
@@ -2704,7 +2698,7 @@
     if (info->modifiers & MOD_Imm8) {
 	imm = yasm_expr_create_ident(yasm_expr_int(
 	    yasm_intnum_create_uint(mod_data & 0xFF)), bc->line);
-	im_len = 8;
+	im_len = 1;
 	mod_data >>= 8;
     }
     if (info->modifiers & MOD_DOpS64R) {
@@ -2783,7 +2777,7 @@
 		    else if (op->type == YASM_INSN__OPERAND_REG) {
 			if (yasm_x86__set_rex_from_reg(&insn->rex, &spare,
 				op->data.reg, mode_bits, X86_REX_R)) {
-			    yasm_error_set(YASM_ERROR_TYPE,
+			    yasm__error(bc->line,
 				N_("invalid combination of opcode and operands"));
 			    return;
 			}
@@ -2795,7 +2789,7 @@
 			unsigned char opadd;
 			if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
 				op->data.reg, mode_bits, X86_REX_B)) {
-			    yasm_error_set(YASM_ERROR_TYPE,
+			    yasm__error(bc->line,
 				N_("invalid combination of opcode and operands"));
 			    return;
 			}
@@ -2808,7 +2802,7 @@
 			unsigned char opadd;
 			if (yasm_x86__set_rex_from_reg(&insn->rex, &opadd,
 				op->data.reg, mode_bits, X86_REX_B)) {
-			    yasm_error_set(YASM_ERROR_TYPE,
+			    yasm__error(bc->line,
 				N_("invalid combination of opcode and operands"));
 			    return;
 			}
@@ -2824,7 +2818,7 @@
 			if (!insn->x86_ea ||
 			    yasm_x86__set_rex_from_reg(&insn->rex, &spare,
 				op->data.reg, mode_bits, X86_REX_R)) {
-			    yasm_error_set(YASM_ERROR_TYPE,
+			    yasm__error(bc->line,
 				N_("invalid combination of opcode and operands"));
 			    if (insn->x86_ea)
 				yasm_xfree(insn->x86_ea);
@@ -2867,27 +2861,28 @@
     }
 
     if (insn->x86_ea) {
-	yasm_x86__ea_init(insn->x86_ea, spare);
+	yasm_x86__ea_init(insn->x86_ea, spare, bc->line);
 	for (i=0; i<num_segregs; i++)
-	    yasm_ea_set_segreg(&insn->x86_ea->ea, segregs[i]);
+	    yasm_ea_set_segreg(&insn->x86_ea->ea, segregs[i], bc->line);
     } else if (num_segregs > 0 && insn->special_prefix == 0) {
 	if (num_segregs > 1)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, bc->line,
 			  N_("multiple segment overrides, using leftmost"));
 	insn->special_prefix = segregs[num_segregs-1]>>8;
     }
     if (imm) {
 	insn->imm = yasm_imm_create_expr(imm);
-	insn->imm->val.size = im_len;
+	insn->imm->len = im_len;
 	insn->imm->sign = im_sign;
     } else
 	insn->imm = NULL;
 
     yasm_x86__bc_apply_prefixes((x86_common *)insn, &insn->rex, num_prefixes,
-				prefixes);
+				prefixes, bc->line);
 
     if (insn->postop == X86_POSTOP_ADDRESS16 && insn->common.addrsize) {
-	yasm_warn_set(YASM_WARN_GENERAL, N_("address size override ignored"));
+	yasm__warning(YASM_WARN_GENERAL, bc->line,
+		      N_("address size override ignored"));
 	insn->common.addrsize = 0;
     }
 
@@ -2962,7 +2957,8 @@
 
 yasm_arch_insnprefix
 yasm_x86__parse_check_insnprefix(yasm_arch *arch, unsigned long data[4],
-				 const char *id, size_t id_len)
+				 const char *id, size_t id_len,
+				 unsigned long line)
 {
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     /*@null@*/ const insnprefix_parse_data *pdata;
@@ -2992,13 +2988,12 @@
 	unsigned long cpu = pdata->data2;
 
 	if ((cpu & CPU_64) && arch_x86->mode_bits != 64) {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("`%s' is an instruction in 64-bit mode"), id);
 	    return YASM_ARCH_NOTINSNPREFIX;
 	}
 	if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("`%s' invalid in 64-bit mode"), id);
+	    yasm__error(line, N_("`%s' invalid in 64-bit mode"), id);
 	    data[0] = (unsigned long)not64_insn;
 	    data[1] = NELEMS(not64_insn);
 	    data[2] = CPU_Not64;
@@ -3016,13 +3011,13 @@
 	unsigned long value = pdata->data2;
 
 	if (arch_x86->mode_bits == 64 && type == X86_OPERSIZE && value == 32) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
+	    yasm__error(line,
 		N_("Cannot override data size to 32 bits in 64-bit mode"));
 	    return YASM_ARCH_NOTINSNPREFIX;
 	}
 
 	if (arch_x86->mode_bits == 64 && type == X86_ADDRSIZE && value == 16) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
+	    yasm__error(line,
 		N_("Cannot override address size to 16 bits in 64-bit mode"));
 	    return YASM_ARCH_NOTINSNPREFIX;
 	}
@@ -3030,7 +3025,7 @@
 	if ((type == X86_REX ||
 	     (value == 64 && (type == X86_OPERSIZE || type == X86_ADDRSIZE)))
 	    && arch_x86->mode_bits != 64) {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("`%s' is a prefix in 64-bit mode"), id);
 	    return YASM_ARCH_NOTINSNPREFIX;
 	}
@@ -3041,7 +3036,8 @@
 }
 
 void
-yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len)
+yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len,
+		    unsigned long line)
 {
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     /*@null@*/ const cpu_parse_data *pdata;
@@ -3056,7 +3052,7 @@
 
     pdata = cpu_find(lcaseid, cpuid_len);
     if (!pdata) {
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("unrecognized CPU identifier `%s'"), cpuid);
 	return;
     }
@@ -3076,7 +3072,7 @@
 
 yasm_arch_regtmod
 yasm_x86__parse_check_regtmod(yasm_arch *arch, unsigned long *data,
-			      const char *id, size_t id_len)
+			      const char *id, size_t id_len, unsigned long line)
 {
     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     /*@null@*/ const regtmod_parse_data *pdata;
@@ -3099,13 +3095,13 @@
     bits = (pdata->regtmod >> 16) & 0xFF;
 
     if (type == YASM_ARCH_REG && bits != 0 && arch_x86->mode_bits != bits) {
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("`%s' is a register in %u-bit mode"), id, bits);
 	return YASM_ARCH_NOTREGTMOD;
     }
 
     if (type == YASM_ARCH_SEGREG && bits != 0 && arch_x86->mode_bits == bits) {
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("`%s' segment register ignored in %u-bit mode"), id,
 		      bits);
     }
diff --git a/modules/dbgfmts/codeview/cv-dbgfmt.c b/modules/dbgfmts/codeview/cv-dbgfmt.c
index c42db19..ccf148c 100644
--- a/modules/dbgfmts/codeview/cv-dbgfmt.c
+++ b/modules/dbgfmts/codeview/cv-dbgfmt.c
@@ -98,11 +98,11 @@
 }
 
 static void
-cv_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
+cv_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
 {
     yasm_dbgfmt_cv *dbgfmt_cv = (yasm_dbgfmt_cv *)dbgfmt;
 
-    yasm_cv__generate_symline(dbgfmt_cv, errwarns);
+    yasm_cv__generate_symline(dbgfmt_cv);
 
     yasm_cv__generate_type(dbgfmt_cv);
 }
diff --git a/modules/dbgfmts/codeview/cv-dbgfmt.h b/modules/dbgfmts/codeview/cv-dbgfmt.h
index 246bbdf..0cf9899 100644
--- a/modules/dbgfmts/codeview/cv-dbgfmt.h
+++ b/modules/dbgfmts/codeview/cv-dbgfmt.h
@@ -54,8 +54,7 @@
 yasm_bytecode *yasm_cv__append_bc(yasm_section *sect, yasm_bytecode *bc);
 
 /* Symbol/Line number functions */
-yasm_section *yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv,
-					yasm_errwarns *errwarns);
+yasm_section *yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv);
 
 /* Type functions */
 yasm_section *yasm_cv__generate_type(yasm_dbgfmt_cv *dbgfmt_cv);
diff --git a/modules/dbgfmts/codeview/cv-symline.c b/modules/dbgfmts/codeview/cv-symline.c
index dc0c3ab..323e6f6 100644
--- a/modules/dbgfmts/codeview/cv-symline.c
+++ b/modules/dbgfmts/codeview/cv-symline.c
@@ -208,8 +208,7 @@
     cv8_symhead_bc_print,
     yasm_bc_finalize_common,
     cv8_symhead_bc_resolve,
-    cv8_symhead_bc_tobytes,
-    0
+    cv8_symhead_bc_tobytes
 };
 
 static const yasm_bytecode_callback cv8_fileinfo_bc_callback = {
@@ -217,8 +216,7 @@
     cv8_fileinfo_bc_print,
     yasm_bc_finalize_common,
     cv8_fileinfo_bc_resolve,
-    cv8_fileinfo_bc_tobytes,
-    0
+    cv8_fileinfo_bc_tobytes
 };
 
 static const yasm_bytecode_callback cv8_lineinfo_bc_callback = {
@@ -226,8 +224,7 @@
     cv8_lineinfo_bc_print,
     yasm_bc_finalize_common,
     cv8_lineinfo_bc_resolve,
-    cv8_lineinfo_bc_tobytes,
-    0
+    cv8_lineinfo_bc_tobytes
 };
 
 static const yasm_bytecode_callback cv_sym_bc_callback = {
@@ -235,8 +232,7 @@
     cv_sym_bc_print,
     yasm_bc_finalize_common,
     cv_sym_bc_resolve,
-    cv_sym_bc_tobytes,
-    0
+    cv_sym_bc_tobytes
 };
 
 static cv8_symhead *cv8_add_symhead(yasm_dbgfmt_cv *dbgfmt_cv,
@@ -411,7 +407,7 @@
     yasm_dvs_initialize(&dvs);
     yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str),
 						strlen(str)));
-    bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0);
+    bc = yasm_bc_create_data(&dvs, 1, 1, 0);
     yasm_bc_finalize(bc, yasm_cv__append_bc(sect, bc));
     yasm_bc_resolve(bc, 0, NULL);
     return bc;
@@ -420,7 +416,6 @@
 typedef struct cv_line_info {
     yasm_section *debug_symline;
     yasm_dbgfmt_cv *dbgfmt_cv;
-    yasm_errwarns *errwarns;
     unsigned int num_lineinfos;
     STAILQ_HEAD(, cv8_lineinfo) cv8_lineinfos;
     /*@null@*/ cv8_lineinfo *cv8_cur_li;
@@ -513,6 +508,7 @@
 cv_generate_line_section(yasm_section *sect, /*@null@*/ void *d)
 {
     cv_line_info *info = (cv_line_info *)d;
+    yasm_dbgfmt_cv *dbgfmt_cv = info->dbgfmt_cv;
 
     if (!yasm_section_is_code(sect))
 	return 0;	/* not code, so no line data for this section */
@@ -520,7 +516,7 @@
     info->cv8_cur_li = NULL;
     info->cv8_cur_ls = NULL;
 
-    yasm_section_bcs_traverse(sect, info->errwarns, info, cv_generate_line_bc);
+    yasm_section_bcs_traverse(sect, info, cv_generate_line_bc);
 
     return 0;
 }
@@ -553,7 +549,7 @@
 }
 
 yasm_section *
-yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv, yasm_errwarns *errwarns)
+yasm_cv__generate_symline(yasm_dbgfmt_cv *dbgfmt_cv)
 {
     cv_line_info info;
     int new;
@@ -568,7 +564,6 @@
 				    cv_generate_filename);
 
     info.dbgfmt_cv = dbgfmt_cv;
-    info.errwarns = errwarns;
     info.debug_symline = yasm_object_get_general(dbgfmt_cv->object,
 						 ".debug$S", 0, 1, 0, 0, &new,
 						 0);
@@ -583,9 +578,7 @@
     off = 1;
     for (i=0; i<dbgfmt_cv->filenames_size; i++) {
 	if (!dbgfmt_cv->filenames[i].pathname) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("codeview file number %d unassigned"), i+1);
-	    yasm_errwarn_propagate(errwarns, 0);
+	    yasm__error(0, N_("codeview file number %d unassigned"), i+1);
 	    continue;
 	}
 	bc = cv_append_str(info.debug_symline,
@@ -662,15 +655,15 @@
     yasm_value val;
 
     /* sym in its section */
-    yasm_value_init_sym(&val, sym, 32);
+    yasm_value_init_sym(&val, sym);
     val.section_rel = 1;
-    output_value(&val, *bufp, 4, off, bc, 0, d);
+    output_value(&val, *bufp, 4, 32, 0, off, bc, 0, d);
     *bufp += 4;
 
     /* section index */
-    yasm_value_init_sym(&val, sym, 16);
+    yasm_value_init_sym(&val, sym);
     val.seg_of = 1;
-    output_value(&val, *bufp, 2, off+4, bc, 0, d);
+    output_value(&val, *bufp, 2, 16, 0, off+4, bc, 0, d);
     *bufp += 2;
 }
 
@@ -738,20 +731,21 @@
     cval = yasm_intnum_create_uint(4);
     /* Output "version" if first */
     if (head->first) {
-	yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+	yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0,
+				 0);
 	buf += 4;
     }
 
     /* Type contained - 4 bytes */
     yasm_intnum_set_uint(cval, head->type);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Total length of info (following this field) - 4 bytes */
     yasm_intnum_set_uint(cval, bc->len);
     intn = yasm_common_calc_bc_dist(head->start_prevbc, head->end_prevbc);
-    yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, intn, buf, 4, 32, 0, bc, 0);
+    yasm_intnum_calc(intn, YASM_EXPR_SUB, cval, bc->line);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, intn, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
     yasm_intnum_destroy(intn);
 
@@ -813,12 +807,12 @@
 
     /* Offset in filename string table */
     cval = yasm_intnum_create_uint(fi->fn->str_off);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Checksum type/length */
     yasm_intnum_set_uint(cval, 0x0110);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0, 0);
     buf += 2;
 
     /* Checksum */
@@ -889,22 +883,22 @@
     /* Section length covered by line number info */
     cval = yasm_common_calc_bc_dist(yasm_section_bcs_first(li->sect),
 				    yasm_section_bcs_last(li->sect));
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Offset of source file in info table */
     yasm_intnum_set_uint(cval, li->fn->info_off);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Number of line number pairs */
     yasm_intnum_set_uint(cval, li->num_linenums);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Number of bytes of line number pairs + 12 (no, I don't know why) */
     yasm_intnum_set_uint(cval, li->num_linenums*8+12);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 0, 0);
     buf += 4;
 
     /* Offset / line number pairs */
@@ -915,13 +909,13 @@
 	    /* offset in section */
 	    yasm_intnum_set_uint(cval, ls->pairs[j].offset);
 	    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc,
-				     0);
+				     0, 0);
 	    buf += 4;
 
 	    /* line number in file */
 	    yasm_intnum_set_uint(cval, ls->pairs[j].line);
 	    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc,
-				     0);
+				     0, 0);
 	    buf += 4;
 	}
     }
@@ -1038,12 +1032,12 @@
 
     /* Total length of record (following this field) - 2 bytes */
     cval = yasm_intnum_create_uint(bc->len-2);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1, 0);
     buf += 2;
 
     /* Type contained - 2 bytes */
     yasm_intnum_set_uint(cval, cvs->type);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 0, 0);
     buf += 2;
 
     while (*ch) {
@@ -1055,24 +1049,23 @@
 	    case 'h':
 		yasm_intnum_set_uint(cval, cvs->args[arg++].i);
 		yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0,
-					 bc, 0);
+					 bc, 0, 0);
 		buf += 2;
 		break;
 	    case 'w':
 		yasm_intnum_set_uint(cval, cvs->args[arg++].i);
 		yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0,
-					 bc, 0);
+					 bc, 0, 0);
 		buf += 4;
 		break;
 	    case 'Y':
-		cv_out_sym((yasm_symrec *)cvs->args[arg++].p,
-			   (unsigned long)(buf-(*bufp)), bc, &buf, d,
-			   output_value);
+		cv_out_sym((yasm_symrec *)cvs->args[arg++].p, buf-(*bufp), bc,
+			   &buf, d, output_value);
 		break;
 	    case 'T':
 		yasm_intnum_set_uint(cval, cvs->args[arg++].i);
 		yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0,
-					 bc, 0);
+					 bc, 0, 0);
 		buf += 4;	/* XXX: will be 2 in CV4 */
 		break;
 	    case 'S':
diff --git a/modules/dbgfmts/codeview/cv-type.c b/modules/dbgfmts/codeview/cv-type.c
index 51cb897..dfd4110 100644
--- a/modules/dbgfmts/codeview/cv-type.c
+++ b/modules/dbgfmts/codeview/cv-type.c
@@ -496,8 +496,7 @@
     cv_type_bc_print,
     yasm_bc_finalize_common,
     cv_type_bc_resolve,
-    cv_type_bc_tobytes,
-    0
+    cv_type_bc_tobytes
 };
 
 static cv_type *cv_type_create(yasm_dbgfmt_cv *dbgfmt_cv, unsigned long indx);
@@ -619,7 +618,7 @@
 
     /* leaf type */
     yasm_intnum_set_uint(cval, leaf->type);
-    yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
+    yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0, 0);
     buf += 2;
 
     while (*ch) {
@@ -630,12 +629,12 @@
 		break;
 	    case 'h':
 		yasm_intnum_set_uint(cval, leaf->args[arg++].i);
-		yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0);
+		yasm_arch_intnum_tobytes(arch, cval, buf, 2, 16, 0, bc, 0, 0);
 		buf += 2;
 		break;
 	    case 'w':
 		yasm_intnum_set_uint(cval, leaf->args[arg++].i);
-		yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
+		yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0, 0);
 		buf += 4;
 		break;
 	    case 'L':
@@ -645,7 +644,7 @@
 	    case 'T':
 		yasm_intnum_set_uint(cval,
 		    ((const cv_type *)leaf->args[arg++].p)->indx);
-		yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0);
+		yasm_arch_intnum_tobytes(arch, cval, buf, 4, 32, 0, bc, 0, 0);
 		buf += 4;	/* XXX: will be 2 in CV4 */
 		break;
 	    case 'S':
@@ -747,14 +746,15 @@
 
     cval = yasm_intnum_create_uint(4);	    /* version */
     if (type->indx == CV_FIRST_NONPRIM) {
-	yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 1);
+	yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 4, 32, 0, bc, 1,
+				 0);
 	buf += 4;
 	reclen -= 4;
     }
 
     /* Total length of record (following this field) - 2 bytes */
     yasm_intnum_set_uint(cval, reclen);
-    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1);
+    yasm_arch_intnum_tobytes(dbgfmt_cv->arch, cval, buf, 2, 16, 0, bc, 1, 0);
     buf += 2;
 
     /* Leaves */
diff --git a/modules/dbgfmts/dwarf2/dwarf2-aranges.c b/modules/dbgfmts/dwarf2/dwarf2-aranges.c
index 7c4010b..0d434c2 100644
--- a/modules/dbgfmts/dwarf2/dwarf2-aranges.c
+++ b/modules/dbgfmts/dwarf2/dwarf2-aranges.c
@@ -44,7 +44,7 @@
     yasm_dvs_initialize(&dvs);
     yasm_dvs_append(&dvs, yasm_dv_create_expr(start));
     yasm_dvs_append(&dvs, yasm_dv_create_expr(length));
-    bc = yasm_bc_create_data(&dvs, sizeof_address, 0, NULL, 0);
+    bc = yasm_bc_create_data(&dvs, sizeof_address, 0, 0);
     yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
     yasm_bc_resolve(bc, 0, NULL);
 }
@@ -108,7 +108,6 @@
 
     info.debug_aranges = debug_aranges;
     info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
-
     yasm_object_sections_traverse(dbgfmt_dwarf2->object, (void *)&info,
 				  dwarf2_generate_aranges_section);
 
diff --git a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
index f9e9dac..8b5a519 100644
--- a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
+++ b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
@@ -59,8 +59,7 @@
     dwarf2_head_bc_print,
     yasm_bc_finalize_common,
     dwarf2_head_bc_resolve,
-    dwarf2_head_bc_tobytes,
-    0
+    dwarf2_head_bc_tobytes
 };
 
 /* Section data callback function prototypes */
@@ -153,7 +152,7 @@
 }
 
 static void
-dwarf2_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
+dwarf2_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
 {
     yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)dbgfmt;
     size_t num_line_sections;
@@ -162,7 +161,7 @@
     /* If we don't have any .file directives, generate line information
      * based on the asm source.
      */
-    debug_line = yasm_dwarf2__generate_line(dbgfmt_dwarf2, errwarns,
+    debug_line = yasm_dwarf2__generate_line(dbgfmt_dwarf2,
 					    dbgfmt_dwarf2->filenames_size == 0,
 					    &main_code, &num_line_sections);
 
@@ -236,6 +235,7 @@
 static void
 dwarf2_head_bc_destroy(void *contents)
 {
+    dwarf2_head *head = (dwarf2_head *)contents;
     yasm_xfree(contents);
 }
 
@@ -274,16 +274,17 @@
     /* Total length of aranges info (following this field) */
     cval = yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_offset);
     intn = yasm_common_calc_bc_dist(head->start_prevbc, head->end_prevbc);
-    yasm_intnum_calc(intn, YASM_EXPR_SUB, cval);
+    yasm_intnum_calc(intn, YASM_EXPR_SUB, cval, bc->line);
     yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, intn, buf,
 			     dbgfmt_dwarf2->sizeof_offset,
-			     dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
+			     dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0, 0);
     buf += dbgfmt_dwarf2->sizeof_offset;
     yasm_intnum_destroy(intn);
 
     /* DWARF version */
     yasm_intnum_set_uint(cval, 2);
-    yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf, 2, 16, 0, bc, 0);
+    yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf, 2, 16, 0, bc, 0,
+			     0);
     buf += 2;
 
     /* Pointer to another debug section */
@@ -291,9 +292,9 @@
 	yasm_value value;
 	yasm_value_init_sym(&value,
 	    yasm_dwarf2__bc_sym(dbgfmt_dwarf2->symtab,
-				yasm_section_bcs_first(head->debug_ptr)),
-	    dbgfmt_dwarf2->sizeof_offset*8);
+				yasm_section_bcs_first(head->debug_ptr)));
 	output_value(&value, buf, dbgfmt_dwarf2->sizeof_offset,
+		     dbgfmt_dwarf2->sizeof_offset*8, 0,
 		     (unsigned long)(buf-*bufp), bc, 0, d);
 	buf += dbgfmt_dwarf2->sizeof_offset;
     }
diff --git a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
index 4f6ad1b..5de6cca 100644
--- a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
+++ b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.h
@@ -109,9 +109,8 @@
 
 /* Line number functions */
 yasm_section *yasm_dwarf2__generate_line
-    (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, yasm_errwarns *errwarns,
-     int asm_source, /*@out@*/ yasm_section **main_code,
-     /*@out@*/ size_t *num_line_sections);
+    (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, int asm_source,
+     /*@out@*/ yasm_section **main_code, /*@out@*/ size_t *num_line_sections);
 int yasm_dwarf2__line_directive
     (yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, const char *name, yasm_section *sect,
      yasm_valparamhead *valparams, unsigned long line);
diff --git a/modules/dbgfmts/dwarf2/dwarf2-info.c b/modules/dbgfmts/dwarf2/dwarf2-info.c
index c2692fe..a53d6ff 100644
--- a/modules/dbgfmts/dwarf2/dwarf2-info.c
+++ b/modules/dbgfmts/dwarf2/dwarf2-info.c
@@ -222,8 +222,7 @@
     dwarf2_abbrev_bc_print,
     yasm_bc_finalize_common,
     dwarf2_abbrev_bc_resolve,
-    dwarf2_abbrev_bc_tobytes,
-    0
+    dwarf2_abbrev_bc_tobytes
 };
 
 
@@ -248,7 +247,7 @@
     yasm_dvs_initialize(&dvs);
     yasm_dvs_append(&dvs, yasm_dv_create_expr(expr));
     if (leb == 0)
-	bc = yasm_bc_create_data(&dvs, size, 0, NULL, 0);
+	bc = yasm_bc_create_data(&dvs, size, 0, 0);
     else
 	bc = yasm_bc_create_leb128(&dvs, leb<0, 0);
     yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc));
@@ -264,7 +263,7 @@
     yasm_dvs_initialize(&dvs);
     yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(str),
 						strlen(str)));
-    bc = yasm_bc_create_data(&dvs, 1, 1, NULL, 0);
+    bc = yasm_bc_create_data(&dvs, 1, 1, 0);
     yasm_bc_finalize(bc, yasm_dwarf2__append_bc(sect, bc));
     yasm_bc_resolve(bc, 0, NULL);
 }
diff --git a/modules/dbgfmts/dwarf2/dwarf2-line.c b/modules/dbgfmts/dwarf2/dwarf2-line.c
index 5245a73..6601d19 100644
--- a/modules/dbgfmts/dwarf2/dwarf2-line.c
+++ b/modules/dbgfmts/dwarf2/dwarf2-line.c
@@ -153,8 +153,7 @@
     dwarf2_spp_bc_print,
     yasm_bc_finalize_common,
     dwarf2_spp_bc_resolve,
-    dwarf2_spp_bc_tobytes,
-    0
+    dwarf2_spp_bc_tobytes
 };
 
 static const yasm_bytecode_callback dwarf2_line_op_bc_callback = {
@@ -162,8 +161,7 @@
     dwarf2_line_op_bc_print,
     yasm_bc_finalize_common,
     dwarf2_line_op_bc_resolve,
-    dwarf2_line_op_bc_tobytes,
-    0
+    dwarf2_line_op_bc_tobytes
 };
 
 
@@ -378,8 +376,7 @@
 	/* Set the starting address for the section */
 	if (!loc->sym) {
 	    /* shouldn't happen! */
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("could not find label prior to loc"));
+	    yasm__error(loc->line, N_("could not find label prior to loc"));
 	    return 1;
 	}
 	dwarf2_dbgfmt_append_line_ext_op(debug_line, DW_LNE_set_address,
@@ -499,7 +496,6 @@
 typedef struct dwarf2_line_info {
     yasm_section *debug_line;	/* section to which line number info goes */
     yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
-    yasm_errwarns *errwarns;
 
     /* Generate based on bytecodes (1) or locs (0)?  Use bytecodes if we're
      * generating line numbers for the actual assembly source file.
@@ -573,8 +569,7 @@
 	    }
 	}
 
-	yasm_section_bcs_traverse(sect, info->errwarns, &bcinfo,
-				  dwarf2_generate_line_bc);
+	yasm_section_bcs_traverse(sect, &bcinfo, dwarf2_generate_line_bc);
     } else {
 	/*@null@*/ dwarf2_loc *loc;
 
@@ -616,8 +611,7 @@
 }
 
 yasm_section *
-yasm_dwarf2__generate_line(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2,
-			   yasm_errwarns *errwarns, int asm_source,
+yasm_dwarf2__generate_line(yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2, int asm_source,
 			   /*@out@*/ yasm_section **main_code,
 			   /*@out@*/ size_t *num_line_sections)
 {
@@ -661,9 +655,7 @@
     /* filename list */
     for (i=0; i<dbgfmt_dwarf2->filenames_size; i++) {
 	if (!dbgfmt_dwarf2->filenames[i].filename) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("dwarf2 file number %d unassigned"), i+1);
-	    yasm_errwarn_propagate(errwarns, 0);
+	    yasm__error(0, N_("dwarf2 file number %d unassigned"), i+1);
 	    continue;
 	}
 	sppbc->len += strlen(dbgfmt_dwarf2->filenames[i].filename) + 1 +
@@ -724,7 +716,7 @@
 				   dbgfmt_dwarf2->sizeof_offset);
     yasm_arch_intnum_tobytes(dbgfmt_dwarf2->arch, cval, buf,
 			     dbgfmt_dwarf2->sizeof_offset,
-			     dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0);
+			     dbgfmt_dwarf2->sizeof_offset*8, 0, bc, 0, 0);
     buf += dbgfmt_dwarf2->sizeof_offset;
 
     YASM_WRITE_8(buf, dbgfmt_dwarf2->min_insn_len);	/* minimum_instr_len */
@@ -806,9 +798,9 @@
 	YASM_WRITE_8(buf, line_op->ext_opcode);
 	if (line_op->ext_operand) {
 	    yasm_value value;
-	    yasm_value_init_sym(&value, line_op->ext_operand,
-				line_op->ext_operandsize*8);
+	    yasm_value_init_sym(&value, line_op->ext_operand);
 	    output_value(&value, buf, line_op->ext_operandsize,
+			 line_op->ext_operandsize*8, 0,
 			 (unsigned long)(buf-*bufp), bc, 0, d);
 	    buf += line_op->ext_operandsize;
 	}
@@ -831,20 +823,18 @@
 	/* File number (required) */
 	yasm_valparam *vp = yasm_vps_first(valparams);
 	if (!vp || !vp->param) {
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("file number required"));
+	    yasm__error(line, N_("file number required"));
 	    yasm_xfree(loc);
 	    return 0;
 	}
 	intn = yasm_expr_get_intnum(&vp->param, NULL);
 	if (!intn) {
-	    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			   N_("file number is not a constant"));
+	    yasm__error(line, N_("file number is not a constant"));
 	    yasm_xfree(loc);
 	    return 0;
 	}
 	if (yasm_intnum_sign(intn) != 1) {
-	    yasm_error_set(YASM_ERROR_VALUE,
-			   N_("file number less than one"));
+	    yasm__error(line, N_("file number less than one"));
 	    yasm_xfree(loc);
 	    return 0;
 	}
@@ -853,14 +843,13 @@
 	/* Line number (required) */
 	vp = yasm_vps_next(vp);
 	if (!vp || !vp->param) {
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("line number required"));
+	    yasm__error(line, N_("line number required"));
 	    yasm_xfree(loc);
 	    return 0;
 	}
 	intn = yasm_expr_get_intnum(&vp->param, NULL);
 	if (!intn) {
-	    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			   N_("file number is not a constant"));
+	    yasm__error(line, N_("file number is not a constant"));
 	    yasm_xfree(loc);
 	    return 0;
 	}
@@ -888,8 +877,7 @@
 	if (vp && vp->param) {
 	    intn = yasm_expr_get_intnum(&vp->param, NULL);
 	    if (!intn) {
-		yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			       N_("column number is not a constant"));
+		yasm__error(line, N_("column number is not a constant"));
 		yasm_xfree(loc);
 		return 0;
 	    }
@@ -907,15 +895,13 @@
 		loc->epilogue_begin = 1;
 	    else if (yasm__strcasecmp(vp->val, "is_stmt") == 0) {
 		if (!vp->param) {
-		    yasm_error_set(YASM_ERROR_SYNTAX,
-				   N_("is_stmt requires value"));
+		    yasm__error(line, N_("is_stmt requires value"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
 		intn = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!intn) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-				   N_("is_stmt value is not a constant"));
+		    yasm__error(line, N_("is_stmt value is not a constant"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
@@ -924,34 +910,31 @@
 		else if (yasm_intnum_is_pos1(intn))
 		    loc->is_stmt = IS_STMT_CLEAR;
 		else {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("is_stmt value not 0 or 1"));
+		    yasm__error(line, N_("is_stmt value not 0 or 1"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
 	    } else if (yasm__strcasecmp(vp->val, "isa") == 0) {
 		if (!vp->param) {
-		    yasm_error_set(YASM_ERROR_SYNTAX, N_("isa requires value"));
+		    yasm__error(line, N_("isa requires value"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
 		intn = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!intn) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-				   N_("isa value is not a constant"));
+		    yasm__error(line, N_("isa value is not a constant"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
 		if (yasm_intnum_sign(intn) < 0) {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("isa value less than zero"));
+		    yasm__error(line, N_("isa value less than zero"));
 		    yasm_xfree(loc);
 		    return 0;
 		}
 		loc->isa_change = 1;
 		loc->isa = yasm_intnum_get_uint(intn);
 	    } else
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, line,
 			      N_("unrecognized loc option `%s'"), vp->val);
 	}
 
@@ -977,16 +960,14 @@
 	/* Otherwise.. first vp is the file number */
 	file_intn = yasm_expr_get_intnum(&vp->param, NULL);
 	if (!file_intn) {
-	    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			   N_("file number is not a constant"));
+	    yasm__error(line, N_("file number is not a constant"));
 	    return 0;
 	}
 	filenum = (size_t)yasm_intnum_get_uint(file_intn);
 
 	vp = yasm_vps_next(vp);
 	if (!vp || !vp->val) {
-	    yasm_error_set(YASM_ERROR_SYNTAX,
-			   N_("file number given but no filename"));
+	    yasm__error(line, N_("file number given but no filename"));
 	    return 0;
 	}
 
diff --git a/modules/dbgfmts/null/null-dbgfmt.c b/modules/dbgfmts/null/null-dbgfmt.c
index 0ec4928..e5c9e4c 100644
--- a/modules/dbgfmts/null/null-dbgfmt.c
+++ b/modules/dbgfmts/null/null-dbgfmt.c
@@ -57,7 +57,7 @@
 }
 
 static void
-null_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
+null_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
 {
 }
 
diff --git a/modules/dbgfmts/stabs/stabs-dbgfmt.c b/modules/dbgfmts/stabs/stabs-dbgfmt.c
index 30d2c8d..22f70a6 100644
--- a/modules/dbgfmts/stabs/stabs-dbgfmt.c
+++ b/modules/dbgfmts/stabs/stabs-dbgfmt.c
@@ -104,7 +104,6 @@
     yasm_bytecode *basebc;      /* base bytecode from which to track SLINEs */
 
     yasm_dbgfmt_stabs *dbgfmt_stabs;
-    yasm_errwarns *errwarns;
 } stabs_info;
 
 typedef struct {
@@ -146,8 +145,7 @@
     stabs_bc_str_print,
     yasm_bc_finalize_common,
     stabs_bc_str_resolve,
-    stabs_bc_str_tobytes,
-    0
+    stabs_bc_str_tobytes
 };
 
 static const yasm_bytecode_callback stabs_bc_stab_callback = {
@@ -155,8 +153,7 @@
     stabs_bc_stab_print,
     yasm_bc_finalize_common,
     stabs_bc_stab_resolve,
-    stabs_bc_stab_tobytes,
-    0
+    stabs_bc_stab_tobytes
 };
 
 yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt;
@@ -302,8 +299,7 @@
     /* handle first (pseudo) bc separately */
     stabs_dbgfmt_generate_n_fun(d, yasm_section_bcs_first(sect));
 
-    yasm_section_bcs_traverse(sect, info->errwarns, d,
-			      stabs_dbgfmt_generate_bcs);
+    yasm_section_bcs_traverse(sect, d, stabs_dbgfmt_generate_bcs);
 
     if (yasm__strcasecmp(sectname, ".text")==0) {
         /* Close out last function by appending a null SO stab after last bc */
@@ -318,7 +314,7 @@
 }
 
 static void
-stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt, yasm_errwarns *errwarns)
+stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
 {
     yasm_dbgfmt_stabs *dbgfmt_stabs = (yasm_dbgfmt_stabs *)dbgfmt;
     stabs_info info;
@@ -337,39 +333,30 @@
 	return;
 
     info.dbgfmt_stabs = dbgfmt_stabs;
-    info.errwarns = errwarns;
     info.lastline = 0;
     info.stabcount = 0;
     info.stab = yasm_object_get_general(dbgfmt_stabs->object, ".stab", 0, 4, 0,
 					0, &new, 0);
     if (!new) {
 	yasm_bytecode *last = yasm_section_bcs_last(info.stab);
-	if (last == NULL) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
+	if (last == NULL)
+	    yasm__error(yasm_section_bcs_first(info.stab)->line,
 		N_("stabs debugging conflicts with user-defined section .stab"));
-	    yasm_errwarn_propagate(errwarns,
-				   yasm_section_bcs_first(info.stab)->line);
-	} else {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	else
+	    yasm__warning(YASM_WARN_GENERAL, 0,
 		N_("stabs debugging overrides empty section .stab"));
-	    yasm_errwarn_propagate(errwarns, 0);
-	}
     }
 
     info.stabstr = yasm_object_get_general(dbgfmt_stabs->object, ".stabstr", 0,
 					   1, 0, 0, &new, 0);
     if (!new) {
 	yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
-	if (last == NULL) {
-	    yasm_error_set(YASM_ERROR_GENERAL,
+	if (last == NULL)
+	    yasm__error(yasm_section_bcs_first(info.stabstr)->line,
 		N_("stabs debugging conflicts with user-defined section .stabstr"));
-	    yasm_errwarn_propagate(errwarns,
-				   yasm_section_bcs_first(info.stab)->line);
-	} else {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	else
+	    yasm__warning(YASM_WARN_GENERAL, 0,
 		N_("stabs debugging overrides empty section .stabstr"));
-	    yasm_errwarn_propagate(errwarns, 0);
-	}
     }
 
 
diff --git a/modules/listfmts/nasm/nasm-listfmt.c b/modules/listfmts/nasm/nasm-listfmt.c
index 0f19723..4d4a5d8 100644
--- a/modules/listfmts/nasm/nasm-listfmt.c
+++ b/modules/listfmts/nasm/nasm-listfmt.c
@@ -82,18 +82,18 @@
 
 static int
 nasm_listfmt_output_value(yasm_value *value, unsigned char *buf,
-			  size_t destsize, unsigned long offset,
-			  yasm_bytecode *bc, int warn, /*@null@*/ void *d)
+			  size_t destsize, size_t valsize, int shift,
+			  unsigned long offset, yasm_bytecode *bc, int warn,
+			  /*@null@*/ void *d)
 {
     /*@null@*/ nasm_listfmt_output_info *info = (nasm_listfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
-    unsigned int valsize = value->size;
 
     assert(info != NULL);
 
     /* Output */
-    switch (yasm_value_output_basic(value, buf, destsize, bc, warn, info->arch,
-				    NULL)) {
+    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
+				    warn, info->arch, NULL)) {
 	case -1:
 	    return 1;
 	case 0:
@@ -124,17 +124,16 @@
 	intn = yasm_expr_get_intnum(&value->abs, NULL);
 	if (intn)
 	    return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
-					    valsize, 0, bc, 0);
+					    valsize, shift, bc, 0, bc->line);
 	else {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("relocation too complex"));
+	    yasm__error(bc->line, N_("relocation too complex"));
 	    return 1;
 	}
     } else {
 	int retval;
 	intn = yasm_intnum_create_uint(0);
 	retval = yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
-					  valsize, 0, bc, 0);
+					  valsize, shift, bc, 0, bc->line);
 	yasm_intnum_destroy(intn);
 	return retval;
     }
diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c
index da84def..5239663 100644
--- a/modules/objfmts/bin/bin-objfmt.c
+++ b/modules/objfmts/bin/bin-objfmt.c
@@ -136,6 +136,7 @@
 
 static int
 bin_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
+			size_t valsize, int shift,
 			/*@unused@*/ unsigned long offset, yasm_bytecode *bc,
 			int warn, /*@null@*/ void *d)
 {
@@ -162,11 +163,12 @@
     /* Simplify absolute portion of value, transforming symrecs */
     if (value->abs)
 	value->abs = yasm_expr__level_tree
-	    (value->abs, 1, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
+	    (value->abs, 1, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL,
+	     NULL);
 
     /* Output */
-    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
-				    info->objfmt_bin->arch, NULL)) {
+    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift,
+				    bc, warn, info->objfmt_bin->arch, NULL)) {
 	case -1:
 	    return 1;
 	case 0:
@@ -176,7 +178,7 @@
     }
 
     /* Couldn't output, assume it contains an external reference. */
-    yasm_error_set(YASM_ERROR_GENERAL,
+    yasm__error(bc->line,
 	N_("binary object format does not support external references"));
     return 1;
 }
@@ -204,7 +206,7 @@
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
 	unsigned long left;
-	yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
+	yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
 	    N_("uninitialized space declared in code/data section: zeroing"));
 	/* Write out in chunks */
 	memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
@@ -228,7 +230,7 @@
 
 static void
 bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, /*@unused@*/ int all_syms,
-		  /*@unused@*/ yasm_dbgfmt *df, yasm_errwarns *errwarns)
+		  /*@unused@*/ yasm_dbgfmt *df)
 {
     yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
     /*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect;
@@ -263,9 +265,7 @@
     assert(startexpr != NULL);
     startnum = yasm_expr_get_intnum(&startexpr, NULL);
     if (!startnum) {
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("ORG expression too complex"));
-	yasm_errwarn_propagate(errwarns, startexpr->line);
+	yasm__error(startexpr->line, N_("ORG expression too complex"));
 	return;
     }
     start = yasm_intnum_get_uint(startnum);
@@ -296,8 +296,7 @@
     /* Output .text first. */
     info.sect = text;
     info.start = textstart;
-    yasm_section_bcs_traverse(text, errwarns, &info,
-			      bin_objfmt_output_bytecode);
+    yasm_section_bcs_traverse(text, &info, bin_objfmt_output_bytecode);
 
     /* If .data is present, output it */
     if (data) {
@@ -310,8 +309,7 @@
 	/* Output .data bytecodes */
 	info.sect = data;
 	info.start = datastart;
-	yasm_section_bcs_traverse(data, errwarns,
-				  &info, bin_objfmt_output_bytecode);
+	yasm_section_bcs_traverse(data, &info, bin_objfmt_output_bytecode);
     }
 
     /* If .bss is present, check it for non-reserve bytecodes */
@@ -381,15 +379,15 @@
 	    resonly = 1;
 	} else {
 	    /* other section names not recognized. */
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("segment name `%s' not recognized"), sectname);
+	    yasm__error(line, N_("segment name `%s' not recognized"),
+			sectname);
 	    return NULL;
 	}
 
 	/* Check for ALIGN qualifier */
 	while ((vp = yasm_vps_next(vp))) {
 	    if (!vp->val) {
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, line,
 			      N_("Unrecognized numeric qualifier"));
 		continue;
 	    }
@@ -398,7 +396,7 @@
 		/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
 
 		if (strcmp(sectname, ".text") == 0) {
-		    yasm_error_set(YASM_ERROR_GENERAL,
+		    yasm__error(line,
 			N_("cannot specify an alignment to the `%s' section"),
 			sectname);
 		    return NULL;
@@ -406,7 +404,7 @@
 		
 		align_expr = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!align_expr) {
-		    yasm_error_set(YASM_ERROR_VALUE,
+		    yasm__error(line,
 				N_("argument to `%s' is not a power of two"),
 				vp->val);
 		    return NULL;
@@ -415,7 +413,7 @@
 
 		/* Alignments must be a power of two. */
 		if ((align & (align - 1)) != 0) {
-		    yasm_error_set(YASM_ERROR_VALUE,
+		    yasm__error(line,
 				N_("argument to `%s' is not a power of two"),
 				vp->val);
 		    return NULL;
@@ -437,7 +435,7 @@
 	    yasm_section_set_default(retval, 0);
 	    yasm_section_set_align(retval, align, line);
 	} else if (have_align)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 		N_("alignment value ignored on section redeclaration"));
 
 	return retval;
@@ -454,7 +452,7 @@
     yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
     yasm_symrec *sym;
 
-    yasm_warn_set(YASM_WARN_GENERAL,
+    yasm__warning(YASM_WARN_GENERAL, line,
 		  N_("binary object format does not support extern variables"));
 
     sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_EXTERN, line);
@@ -470,7 +468,7 @@
     yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
     yasm_symrec *sym;
 
-    yasm_warn_set(YASM_WARN_GENERAL,
+    yasm__warning(YASM_WARN_GENERAL, line,
 		  N_("binary object format does not support global variables"));
 
     sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_GLOBAL, line);
@@ -487,7 +485,7 @@
     yasm_symrec *sym;
 
     yasm_expr_destroy(size);
-    yasm_error_set(YASM_ERROR_TYPE,
+    yasm__error(line,
 	N_("binary object format does not support common variables"));
 
     sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_COMMON, line);
@@ -519,8 +517,7 @@
 	}
 
 	if (!start) {
-	    yasm_error_set(YASM_ERROR_SYNTAX,
-			   N_("argument to ORG must be expression"));
+	    yasm__error(line, N_("argument to ORG must be expression"));
 	    return 0;
 	}
 
diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c
index 6a3a995..64fc27f 100644
--- a/modules/objfmts/coff/coff-objfmt.c
+++ b/modules/objfmts/coff/coff-objfmt.c
@@ -190,7 +190,6 @@
 
 typedef struct coff_objfmt_output_info {
     yasm_objfmt_coff *objfmt_coff;
-    yasm_errwarns *errwarns;
     /*@dependent@*/ FILE *f;
     /*@only@*/ unsigned char *buf;
     yasm_section *sect;
@@ -426,8 +425,8 @@
 
 static int
 coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-			 unsigned long offset, yasm_bytecode *bc, int warn,
-			 /*@null@*/ void *d)
+			 size_t valsize, int shift, unsigned long offset,
+			 yasm_bytecode *bc, int warn, /*@null@*/ void *d)
 {
     /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
     yasm_objfmt_coff *objfmt_coff;
@@ -435,7 +434,6 @@
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_val, intn_minus;
     int retval;
-    unsigned int valsize = value->size;
 
     assert(info != NULL);
     objfmt_coff = info->objfmt_coff;
@@ -447,8 +445,8 @@
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
-				    info->objfmt_coff->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
+				    warn, info->objfmt_coff->arch,
 				    yasm_common_calc_bc_dist)) {
 	case -1:
 	    return 1;
@@ -462,8 +460,7 @@
     if (value->rshift > 0
 	|| (value->seg_of && (value->wrt || value->curpos_rel))
 	|| (value->section_rel && (value->wrt || value->curpos_rel))) {
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("coff: relocation too complex"));
+	yasm__error(bc->line, N_("coff: relocation too complex"));
 	return 1;
     }
 
@@ -484,14 +481,12 @@
 	    /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;
 	    if (!yasm_symrec_get_label(sym, &rel_precbc)
 		|| !yasm_symrec_get_label(value->wrt, &wrt_precbc)) {
-		yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			       N_("coff: wrt expression too complex"));
+		yasm__error(bc->line, N_("coff: wrt expression too complex"));
 		return 1;
 	    }
 	    dist = yasm_common_calc_bc_dist(wrt_precbc, rel_precbc);
 	    if (!dist) {
-		yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			       N_("coff: cannot wrt across sections"));
+		yasm__error(bc->line, N_("coff: cannot wrt across sections"));
 		return 1;
 	    }
 	    sym = value->wrt;
@@ -508,14 +503,12 @@
 		common_size = yasm_expr_get_intnum(&csymd->size,
 						   yasm_common_calc_bc_dist);
 		if (!common_size) {
-		    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-				   N_("coff: common size too complex"));
+		    yasm__error(bc->line, N_("coff: common size too complex"));
 		    return 1;
 		}
 
 		if (yasm_intnum_sign(common_size) < 0) {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("coff: common size is negative"));
+		    yasm__error(bc->line, N_("coff: common size is negative"));
 		    return 1;
 		}
 
@@ -573,14 +566,12 @@
 		if (valsize == 32)
 		    reloc->type = COFF_RELOC_I386_REL32;
 		else {
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("coff: invalid relocation size"));
+		    yasm__error(bc->line, N_("coff: invalid relocation size"));
 		    return 1;
 		}
 	    } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
 		if (valsize != 32) {
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("coff: invalid relocation size"));
+		    yasm__error(bc->line, N_("coff: invalid relocation size"));
 		    return 1;
 		}
 		if (!value->ip_rel)
@@ -605,8 +596,8 @@
 			reloc->type = COFF_RELOC_AMD64_REL32_5;
 			break;
 		    default:
-			yasm_error_set(YASM_ERROR_TYPE,
-				       N_("coff: invalid relocation size"));
+			yasm__error(bc->line,
+				    N_("coff: invalid relocation size"));
 			return 1;
 		}
 	    } else
@@ -640,8 +631,7 @@
 		} else if (valsize == 64)
 		    reloc->type = COFF_RELOC_AMD64_ADDR64;
 		else {
-		    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("coff: invalid relocation size"));
+		    yasm__error(bc->line, N_("coff: invalid relocation size"));
 		    return 1;
 		}
 	    } else
@@ -659,29 +649,28 @@
 	intn = yasm_intnum_create_uint(intn_val-intn_minus);
     else {
 	intn = yasm_intnum_create_uint(intn_minus-intn_val);
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, bc->line);
     }
 
     if (value->abs) {
 	yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
 	if (!intn2) {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("coff: relocation too complex"));
+	    yasm__error(bc->line, N_("coff: relocation too complex"));
 	    yasm_intnum_destroy(intn);
 	    if (dist)
 		yasm_intnum_destroy(dist);
 	    return 1;
 	}
-	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
+	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
     }
 
     if (dist) {
-	yasm_intnum_calc(intn, YASM_EXPR_ADD, dist);
+	yasm_intnum_calc(intn, YASM_EXPR_ADD, dist, bc->line);
 	yasm_intnum_destroy(dist);
     }
 
     retval = yasm_arch_intnum_tobytes(objfmt_coff->arch, intn, buf, destsize,
-				      valsize, 0, bc, warn);
+				      valsize, shift, bc, warn, bc->line);
     yasm_intnum_destroy(intn);
     return retval;
 }
@@ -711,7 +700,7 @@
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
 	unsigned long left;
-	yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
+	yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
 	    N_("uninitialized space declared in code/data section: zeroing"));
 	/* Write out in chunks */
 	memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
@@ -782,8 +771,7 @@
 
 	info->sect = sect;
 	info->csd = csd;
-	yasm_section_bcs_traverse(sect, info->errwarns, info,
-				  coff_objfmt_output_bytecode);
+	yasm_section_bcs_traverse(sect, info, coff_objfmt_output_bytecode);
 
 	/* Sanity check final section size */
 	if (csd->size != (last->offset + last->len))
@@ -832,7 +820,7 @@
 	    yasm_internal_error(
 		N_("coff: no symbol data for relocated symbol"));
 
-	yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0);
+	yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0, 0);
 	localbuf += 4;				/* address of relocation */
 	YASM_WRITE_32_L(localbuf, csymd->index);    /* relocated symbol */
 	YASM_WRITE_16_L(localbuf, reloc->type);	    /* type of relocation */
@@ -922,12 +910,10 @@
 	/* Win32/64 has special handling for this case. */
 	if (objfmt_coff->win32)
 	    csd->flags |= COFF_STYP_NRELOC_OVFL;
-	else {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	else
+	    yasm__warning(YASM_WARN_GENERAL, 0,
 			  N_("too many relocations in section `%s'"),
 			  yasm_section_get_name(sect));
-	    yasm_errwarn_propagate(info->errwarns, 0);
-	}
 	YASM_WRITE_16_L(localbuf, 0xFFFF);	/* max out */
     } else
 	YASM_WRITE_16_L(localbuf, csd->nreloc); /* num of relocation entries */
@@ -1012,12 +998,10 @@
 		    abs_start = yasm_expr_copy(yasm_section_get_start(sect));
 		    intn = yasm_expr_get_intnum(&abs_start,
 						yasm_common_calc_bc_dist);
-		    if (!intn) {
-			yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+		    if (!intn)
+			yasm__error(abs_start->line,
 			    N_("absolute section start not an integer expression"));
-			yasm_errwarn_propagate(info->errwarns,
-					       abs_start->line);
-		    } else
+		    else
 			value = yasm_intnum_get_uint(intn);
 		    yasm_expr_destroy(abs_start);
 
@@ -1032,11 +1016,9 @@
 	    intn = yasm_expr_get_intnum(&equ_val_copy,
 					yasm_common_calc_bc_dist);
 	    if (!intn) {
-		if (vis & YASM_SYM_GLOBAL) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+		if (vis & YASM_SYM_GLOBAL)
+		    yasm__error(equ_val->line,
 			N_("global EQU value not an integer expression"));
-		    yasm_errwarn_propagate(info->errwarns, equ_val->line);
-		}
 	    } else
 		value = yasm_intnum_get_uint(intn);
 	    yasm_expr_destroy(equ_val_copy);
@@ -1046,11 +1028,10 @@
 	    if (vis & YASM_SYM_COMMON) {
 		intn = yasm_expr_get_intnum(&csymd->size,
 					    yasm_common_calc_bc_dist);
-		if (!intn) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+		if (!intn)
+		    yasm__error(csymd->size->line,
 			N_("COMMON data size not an integer expression"));
-		    yasm_errwarn_propagate(info->errwarns, csymd->size->line);
-		} else
+		else
 		    value = yasm_intnum_get_uint(intn);
 		scnum = 0;
 	    }
@@ -1141,8 +1122,7 @@
 }
 
 static void
-coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
-		   yasm_errwarns *errwarns)
+coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
 {
     yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt;
     coff_objfmt_output_info info;
@@ -1165,7 +1145,6 @@
 
     info.strtab_offset = 4;
     info.objfmt_coff = objfmt_coff;
-    info.errwarns = errwarns;
     info.f = f;
     info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
 
@@ -1340,7 +1319,7 @@
 	 * files via "/nnnn" (where nnnn is decimal offset into string table),
 	 * so only warn for regular COFF.
 	 */
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 	    N_("COFF section names limited to 8 characters: truncating"));
 	sectname[8] = '\0';
     }
@@ -1378,7 +1357,7 @@
 	    flags |= COFF_STYP_READ;
 	    align = 8;
 	} else
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 		N_("Standard COFF does not support read-only data sections"));
     } else if (strcmp(sectname, ".drectve") == 0) {
 	flags = COFF_STYP_INFO;
@@ -1415,7 +1394,7 @@
 	win32warn = 0;
 
 	if (!vp->val) {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("Unrecognized numeric qualifier"));
 	    continue;
 	}
@@ -1497,7 +1476,7 @@
 			readonly = 0;
 			break;
 		    default:
-			yasm_warn_set(YASM_WARN_GENERAL,
+			yasm__warning(YASM_WARN_GENERAL, line,
 				      N_("unrecognized section attribute: `%c'"),
 				      vp->val[i]);
 		}
@@ -1526,24 +1505,24 @@
 		/*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
 		align_expr = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!align_expr) {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("argument to `%s' is not a power of two"),
-				   vp->val);
+		    yasm__error(line,
+				N_("argument to `%s' is not a power of two"),
+				vp->val);
 		    return NULL;
 		}
 		align = yasm_intnum_get_uint(align_expr);
 
 		/* Alignments must be a power of two. */
 		if ((align & (align - 1)) != 0) {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("argument to `%s' is not a power of two"),
-				   vp->val);
+		    yasm__error(line,
+				N_("argument to `%s' is not a power of two"),
+				vp->val);
 		    return NULL;
 		}
 
 		/* Check to see if alignment is supported size */
 		if (align > 8192) {
-		    yasm_error_set(YASM_ERROR_VALUE,
+		    yasm__error(line,
 			N_("Win32 does not support alignments > 8192"));
 		    return NULL;
 		}
@@ -1551,11 +1530,11 @@
 	    } else
 		win32warn = 1;
 	} else
-	    yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
-			  vp->val);
+	    yasm__warning(YASM_WARN_GENERAL, line,
+			  N_("Unrecognized qualifier `%s'"), vp->val);
 
 	if (win32warn)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 		N_("Standard COFF does not support qualifier `%s'"), vp->val);
     }
 
@@ -1573,7 +1552,7 @@
 	csd->flags2 = flags2;
 	yasm_section_set_align(retval, align, line);
     } else if (flags_override)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("section flags ignored on section redeclaration"));
     return retval;
 }
@@ -1718,8 +1697,7 @@
 	if (vp->val)
 	    yasm_symtab_use(objfmt_coff->symtab, vp->val, line);
 	else {
-	    yasm_error_set(YASM_ERROR_SYNTAX,
-			   N_("argument to EXPORT must be symbol name"));
+	    yasm__error(line, N_("argument to EXPORT must be symbol name"));
 	    return 0;
 	}
 
@@ -1744,8 +1722,7 @@
 	yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(vp->val),
 						    strlen(vp->val)));
 	yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(" "), 1));
-	yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 1, 0, NULL,
-							  line));
+	yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 1, 0, line));
 
 	return 0;
     } else
diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c
index 3562cbe..525d9eb 100644
--- a/modules/objfmts/dbg/dbg-objfmt.c
+++ b/modules/objfmts/dbg/dbg-objfmt.c
@@ -61,8 +61,7 @@
 }
 
 static void
-dbg_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
-		  yasm_errwarns *errwarns)
+dbg_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
 {
     yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt;
     char buf[1024];
diff --git a/modules/objfmts/elf/elf-machine.h b/modules/objfmts/elf/elf-machine.h
index bec98db..9eb896f 100644
--- a/modules/objfmts/elf/elf-machine.h
+++ b/modules/objfmts/elf/elf-machine.h
@@ -30,12 +30,12 @@
 
 #define YASM_WRITE_32I_L(p, i) do {\
     assert(yasm_intnum_check_size(i, 32, 0, 2)); \
-    yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0); \
+    yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0, 0); \
     p += 4; } while (0)
 
 #define YASM_WRITE_64I_L(p, i) do {\
     assert(yasm_intnum_check_size(i, 64, 0, 2)); \
-    yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0); \
+    yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0, 0); \
     p += 8; } while (0)
 
 #define YASM_WRITE_64C_L(p, hi, lo) do {\
diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c
index 2beeffb..0ca8f1f 100644
--- a/modules/objfmts/elf/elf-objfmt.c
+++ b/modules/objfmts/elf/elf-objfmt.c
@@ -69,7 +69,6 @@
 
 typedef struct {
     yasm_objfmt_elf *objfmt_elf;
-    yasm_errwarns *errwarns;
     FILE *f;
     elf_secthead *shead;
     yasm_section *sect;
@@ -248,16 +247,14 @@
 
     pos = ftell(f);
     if (pos == -1) {
-	yasm_error_set(YASM_ERROR_IO,
-		       N_("could not get file position on output file"));
+	yasm__error(0, N_("could not get file position on output file"));
 	return -1;
     }
     delta = align - (pos & (align-1)); 
     if (delta != align) {
 	pos += delta;
 	if (fseek(f, pos, SEEK_SET) < 0) {
-	    yasm_error_set(YASM_ERROR_IO,
-			   N_("could not set file position on output file"));
+	    yasm__error(0, N_("could not set file position on output file"));
 	    return -1;
 	}
     }
@@ -277,7 +274,7 @@
     reloc = elf_reloc_entry_create(sym, NULL,
 	yasm_intnum_create_uint(bc->offset), 0, valsize);
     if (reloc == NULL) {
-	yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size"));
+	yasm__error(bc->line, N_("elf: invalid relocation size"));
 	return 1;
     }
     /* allocate .rel[a] sections on a need-basis */
@@ -286,22 +283,22 @@
     zero = yasm_intnum_create_uint(0);
     elf_handle_reloc_addend(zero, reloc);
     retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, zero, buf,
-				      destsize, valsize, 0, bc, warn);
+				      destsize, valsize, 0, bc, warn,
+				      bc->line);
     yasm_intnum_destroy(zero);
     return retval;
 }
 
 static int
 elf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-			unsigned long offset, yasm_bytecode *bc, int warn,
-			/*@null@*/ void *d)
+			size_t valsize, int shift, unsigned long offset,
+			yasm_bytecode *bc, int warn, /*@null@*/ void *d)
 {
     /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_val;
     /*@null@*/ elf_reloc_entry *reloc = NULL;
     int retval;
-    unsigned int valsize = value->size;
 
     if (info == NULL)
 	yasm_internal_error("null info struct");
@@ -313,8 +310,8 @@
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
-				    info->objfmt_elf->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
+				    warn, info->objfmt_elf->arch,
 				    yasm_common_calc_bc_dist)) {
 	case -1:
 	    return 1;
@@ -326,8 +323,7 @@
 
     /* Handle other expressions, with relocation if necessary */
     if (value->seg_of || value->section_rel || value->rshift > 0) {
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("elf: relocation too complex"));
+	yasm__error(bc->line, N_("elf: relocation too complex"));
 	return 1;
     }
 
@@ -370,8 +366,7 @@
 	    yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel,
 	    valsize);
 	if (reloc == NULL) {
-	    yasm_error_set(YASM_ERROR_TYPE,
-			   N_("elf: invalid relocation (WRT or size)"));
+	    yasm__error(bc->line, N_("elf: invalid relocation (WRT or size)"));
 	    return 1;
 	}
 	/* allocate .rel[a] sections on a need-basis */
@@ -383,18 +378,18 @@
     if (value->abs) {
 	yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
 	if (!intn2) {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("elf: relocation too complex"));
+	    yasm__error(bc->line, N_("elf: relocation too complex"));
 	    yasm_intnum_destroy(intn);
 	    return 1;
 	}
-	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
+	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
     }
 
     if (reloc)
 	elf_handle_reloc_addend(intn, reloc);
     retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, intn, buf,
-				      destsize, valsize, 0, bc, warn);
+				      destsize, valsize, shift, bc, warn,
+				      bc->line);
     yasm_intnum_destroy(intn);
     return retval;
 }
@@ -429,7 +424,7 @@
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
 	unsigned long left;
-	yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
+	yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
 	    N_("uninitialized space declared in code/data section: zeroing"));
 	/* Write out in chunks */
 	memset(buf, 0, 256);
@@ -452,7 +447,7 @@
 }
 
 static int
-elf_objfmt_create_dbg_secthead(yasm_section *sect, /*@null@*/ void *d)
+elf_objfmt_create_dbg_secthead(yasm_section *sect, void *d)
 {
     /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
     elf_secthead *shead;
@@ -527,27 +522,20 @@
 	return 0;
     }
 
-    if ((pos = ftell(info->f)) == -1) {
-	yasm_error_set(YASM_ERROR_IO,
-		       N_("couldn't read position on output stream"));
-	yasm_errwarn_propagate(info->errwarns, 0);
-    }
+    if ((pos = ftell(info->f)) == -1)
+	yasm__error(0, N_("couldn't read position on output stream"));
     pos = elf_secthead_set_file_offset(shead, pos);
-    if (fseek(info->f, pos, SEEK_SET) < 0) {
-	yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream"));
-	yasm_errwarn_propagate(info->errwarns, 0);
-    }
+    if (fseek(info->f, pos, SEEK_SET) < 0)
+	yasm__error(0, N_("couldn't seek on output stream"));
 
     info->sect = sect;
     info->shead = shead;
-    yasm_section_bcs_traverse(sect, info->errwarns, info,
-			      elf_objfmt_output_bytecode);
+    yasm_section_bcs_traverse(sect, info, elf_objfmt_output_bytecode);
 
     elf_secthead_set_index(shead, ++info->sindex);
 
     /* No relocations to output?  Go on to next section */
-    if (elf_secthead_write_relocs_to_file(info->f, sect, shead,
-					  info->errwarns) == 0)
+    if (elf_secthead_write_relocs_to_file(info->f, sect, shead) == 0)
 	return 0;
     elf_secthead_set_rel_index(shead, ++info->sindex);
 
@@ -591,8 +579,7 @@
 }
 
 static void
-elf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df,
-		  yasm_errwarns *errwarns)
+elf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, yasm_dbgfmt *df)
 {
     yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;
     elf_objfmt_output_info info;
@@ -606,7 +593,6 @@
     unsigned long elf_symtab_nlocal;
 
     info.objfmt_elf = objfmt_elf;
-    info.errwarns = errwarns;
     info.f = f;
 
     /* Update filename strtab */
@@ -615,8 +601,7 @@
 
     /* Allocate space for Ehdr by seeking forward */
     if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) {
-	yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
-	yasm_errwarn_propagate(errwarns, 0);
+	yasm__error(0, N_("could not seek on output file"));
 	return;
     }
 
@@ -647,35 +632,26 @@
 					      ".shstrtab");
 
     /* output .shstrtab */
-    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
-	yasm_errwarn_propagate(errwarns, 0);
+    if ((pos = elf_objfmt_output_align(f, 4)) == -1)
 	return;
-    }
     elf_shstrtab_offset = (unsigned long) pos;
     elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab);
 
     /* output .strtab */
-    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
-	yasm_errwarn_propagate(errwarns, 0);
+    if ((pos = elf_objfmt_output_align(f, 4)) == -1)
 	return;
-    }
     elf_strtab_offset = (unsigned long) pos;
     elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab);
 
     /* output .symtab - last section so all others have indexes */
-    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
-	yasm_errwarn_propagate(errwarns, 0);
+    if ((pos = elf_objfmt_output_align(f, 4)) == -1)
 	return;
-    }
     elf_symtab_offset = (unsigned long) pos;
-    elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab,
-					       errwarns);
+    elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab);
 
     /* output section header table */
-    if ((pos = elf_objfmt_output_align(f, 16)) == -1) {
-	yasm_errwarn_propagate(errwarns, 0);
+    if ((pos = elf_objfmt_output_align(f, 16)) == -1)
 	return;
-    }
     elf_shead_addr = (unsigned long) pos;
 
     /* stabs debugging support */
@@ -732,8 +708,7 @@
 
     /* output Ehdr */
     if (fseek(f, 0, SEEK_SET) < 0) {
-	yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
-	yasm_errwarn_propagate(errwarns, 0);
+	yasm__error(0, N_("could not seek on output file"));
 	return;
     }
 
@@ -848,7 +823,7 @@
 	int match;
 
 	if (!vp->val) {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("Unrecognized numeric qualifier"));
 	    continue;
 	}
@@ -897,7 +872,7 @@
 			flags |= SHF_TLS;
 			break;
 		    default:
-			yasm_warn_set(YASM_WARN_GENERAL,
+			yasm__warning(YASM_WARN_GENERAL, line,
 				      N_("unrecognized section attribute: `%c'"),
 				      vp->val[i]);
 		}
@@ -915,22 +890,22 @@
 
             align_expr = yasm_expr_get_intnum(&vp->param, NULL);
             if (!align_expr) {
-                yasm_error_set(YASM_ERROR_VALUE,
-			       N_("argument to `%s' is not a power of two"),
-			       vp->val);
+                yasm__error(line,
+                            N_("argument to `%s' is not a power of two"),
+                            vp->val);
                 return NULL;
             }
             align = yasm_intnum_get_uint(align_expr);
 
             /* Alignments must be a power of two. */
             if ((align & (align - 1)) != 0) {
-                yasm_error_set(YASM_ERROR_VALUE,
-			       N_("argument to `%s' is not a power of two"),
-                               vp->val);
+                yasm__error(line,
+                            N_("argument to `%s' is not a power of two"),
+                            vp->val);
                 return NULL;
             }
 	} else
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("Unrecognized qualifier `%s'"), vp->val);
     }
 	/* Handle merge entity size */
@@ -940,10 +915,10 @@
 
 		merge_intn = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!merge_intn)
-		    yasm_warn_set(YASM_WARN_GENERAL,
+		    yasm__warning(YASM_WARN_GENERAL, line,
 				  N_("invalid merge entity size"));
 	    } else {
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, line,
 			      N_("entity size for SHF_MERGE not specified"));
 		flags &= ~SHF_MERGE;
 	    }
@@ -966,7 +941,7 @@
 	    elf_secthead_set_entsize(esd, yasm_intnum_get_uint(merge_intn));
 	yasm_section_set_align(retval, align, line);
     } else if (flags_override)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("section flags ignored on section redeclaration"));
     return retval;
 }
@@ -988,8 +963,7 @@
 	for (; vp; vp = yasm_vps_next(vp))
         {
             if (vp->val)
-                yasm_error_set(YASM_ERROR_TYPE,
-			       N_("unrecognized symbol type `%s'"), vp->val);
+                yasm__error(line, N_("unrecognized symbol type `%s'"), vp->val);
         }
     }
     return sym;
@@ -1032,9 +1006,8 @@
                     vis_overrides++;
                 }
                 else
-                    yasm_error_set(YASM_ERROR_TYPE,
-				   N_("unrecognized symbol type `%s'"),
-				   vp->val);
+                    yasm__error(line, N_("unrecognized symbol type `%s'"),
+                                vp->val);
             }
             else if (vp->param && !size) {
                 size = vp->param;
@@ -1042,7 +1015,7 @@
             }
 	}
         if (vis_overrides > 1) {
-            yasm_warn_set(YASM_WARN_GENERAL,
+            yasm__warning(YASM_WARN_GENERAL, line,
                 N_("More than one symbol visibility provided; using last"));
         }
     }
@@ -1073,20 +1046,20 @@
 
                 align_expr = yasm_expr_get_intnum(&vp->param, NULL);
                 if (!align_expr) {
-                    yasm_error_set(YASM_ERROR_VALUE,
-			N_("alignment constraint is not a power of two"));
+                    yasm__error(line,
+                                N_("alignment constraint is not a power of two"));
                     return sym;
                 }
                 addralign = yasm_intnum_get_uint(align_expr);
 
                 /* Alignments must be a power of two. */
                 if ((addralign & (addralign - 1)) != 0) {
-                    yasm_error_set(YASM_ERROR_VALUE,
-                        N_("alignment constraint is not a power of two"));
+                    yasm__error(line,
+                                N_("alignment constraint is not a power of two"));
                     return sym;
                 }
             } else if (vp->val)
-                yasm_warn_set(YASM_WARN_GENERAL,
+                yasm__warning(YASM_WARN_GENERAL, line,
                               N_("Unrecognized qualifier `%s'"), vp->val);
         }
     }
@@ -1111,7 +1084,7 @@
     elf_symtab_entry *entry;
 
     if (!symname) {
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("Symbol name not specified"));
+	yasm__error(line, N_("Symbol name not specified"));
 	return 0;
     }
 
@@ -1135,10 +1108,10 @@
 	    else if (yasm__strcasecmp(vp->val, "object") == 0)
 		elf_sym_set_type(entry, STT_OBJECT);
 	    else
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, line,
 			      N_("unrecognized symbol type `%s'"), vp->val);
 	} else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("no type specified"));
+	    yasm__error(line, N_("no type specified"));
     } else if (yasm__strcasecmp(name, "size") == 0) {
 	/* Get symbol elf data */
 	sym = yasm_symtab_use(objfmt_elf->symtab, symname, line);
@@ -1160,7 +1133,7 @@
 	    elf_sym_set_size(entry, yasm_expr_create_ident(yasm_expr_sym(
 		yasm_symtab_use(objfmt_elf->symtab, vp->val, line)), line));
 	else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("no size specified"));
+	    yasm__error(line, N_("no size specified"));
     } else if (yasm__strcasecmp(name, "weak") == 0) {
 	sym = yasm_symtab_declare(objfmt_elf->symtab, symname, YASM_SYM_GLOBAL,
 				  line);
diff --git a/modules/objfmts/elf/elf-x86-amd64.c b/modules/objfmts/elf/elf-x86-amd64.c
index ac504ed..7894bec 100644
--- a/modules/objfmts/elf/elf-x86-amd64.c
+++ b/modules/objfmts/elf/elf-x86-amd64.c
@@ -116,7 +116,7 @@
 
     nreloc = yasm_intnum_create_uint(shead->nreloc);
     relocsize = yasm_intnum_create_uint(RELOC64A_SIZE);
-    yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc);
+    yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
     YASM_WRITE_64I_L(bufp, relocsize);		/* size */
     yasm_intnum_destroy(nreloc);
     yasm_intnum_destroy(relocsize);
diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c
index f2426c0..97dfb50 100644
--- a/modules/objfmts/elf/elf.c
+++ b/modules/objfmts/elf/elf.c
@@ -422,8 +422,7 @@
 }
 
 unsigned long
-elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab,
-			 yasm_errwarns *errwarns)
+elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
 {
     unsigned char buf[SYMTAB_MAXSIZE], *bufp;
     elf_symtab_entry *entry, *prev;
@@ -442,11 +441,9 @@
 	if (entry->xsize) {
 	    size_intn = yasm_intnum_copy(
 		yasm_expr_get_intnum(&entry->xsize, yasm_common_calc_bc_dist));
-	    if (!size_intn) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("size specifier not an integer expression"));
-		yasm_errwarn_propagate(errwarns, entry->xsize->line);
-	    }
+	    if (!size_intn)
+		yasm__error(entry->xsize->line,
+		    N_("size specifier not an integer expression"));
 	}
 	else
 	    size_intn = yasm_intnum_create_uint(entry->size);
@@ -463,9 +460,8 @@
 						yasm_common_calc_bc_dist);
 
 		if (equ_intn == NULL) {
-		    yasm_error_set(YASM_ERROR_VALUE,
-				   N_("EQU value not an integer expression"));
-		    yasm_errwarn_propagate(errwarns, equ_expr->line);
+		    yasm__error(equ_expr->line,
+				N_("EQU value not an integer expression"));
 		}
 
 		value_intn = yasm_intnum_copy(equ_intn);
@@ -704,7 +700,7 @@
 
 unsigned long
 elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
-				  elf_secthead *shead, yasm_errwarns *errwarns)
+				  elf_secthead *shead)
 {
     elf_reloc_entry *reloc;
     unsigned char buf[RELOC_MAXSIZE], *bufp;
@@ -720,16 +716,11 @@
 
     /* first align section to multiple of 4 */
     pos = ftell(f);
-    if (pos == -1) {
-	yasm_error_set(YASM_ERROR_IO,
-		       N_("couldn't read position on output stream"));
-	yasm_errwarn_propagate(errwarns, 0);
-    }
+    if (pos == -1)
+	yasm__error(0, N_("couldn't read position on output stream"));
     pos = (pos + 3) & ~3;
-    if (fseek(f, pos, SEEK_SET) < 0) {
-	yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream"));
-	yasm_errwarn_propagate(errwarns, 0);
-    }
+    if (fseek(f, pos, SEEK_SET) < 0)
+	yasm__error(0, N_("couldn't seek on output stream"));
     shead->rel_offset = (unsigned long)pos;
 
 
@@ -852,7 +843,7 @@
 elf_secthead_add_size(elf_secthead *shead, yasm_intnum *size)
 {
     if (size) {
-	yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size);
+	yasm_intnum_calc(shead->size, YASM_EXPR_ADD, size, 0);
     }
 }
 
diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h
index 1a75f91..e9af884 100644
--- a/modules/objfmts/elf/elf.h
+++ b/modules/objfmts/elf/elf.h
@@ -436,8 +436,7 @@
 				 elf_symtab_entry *entry);
 void elf_symtab_destroy(elf_symtab_head *head);
 unsigned long elf_symtab_assign_indices(elf_symtab_head *symtab);
-unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab,
-				       yasm_errwarns *errwarns);
+unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab);
 void elf_symtab_set_nonzero(elf_symtab_entry	*entry,
 			    struct yasm_section *sect,
 			    elf_section_index	 sectidx,
@@ -491,8 +490,7 @@
 					     elf_secthead *esd,
 					     elf_section_index sindex);
 unsigned long elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
-						elf_secthead *shead,
-						yasm_errwarns *errwarns);
+						elf_secthead *shead);
 long elf_secthead_set_file_offset(elf_secthead *shead, long pos);
 
 /* program header function */
diff --git a/modules/objfmts/elf/tests/curpos-err.errwarn b/modules/objfmts/elf/tests/curpos-err.errwarn
index fb6f65d..f0d8202 100644
--- a/modules/objfmts/elf/tests/curpos-err.errwarn
+++ b/modules/objfmts/elf/tests/curpos-err.errwarn
@@ -1,2 +1,2 @@
--:15: data expression too complex
--:21: data expression too complex
+-:15: expression too complex
+-:21: expression too complex
diff --git a/modules/objfmts/xdf/xdf-objfmt.c b/modules/objfmts/xdf/xdf-objfmt.c
index 56fe213..27690b1 100644
--- a/modules/objfmts/xdf/xdf-objfmt.c
+++ b/modules/objfmts/xdf/xdf-objfmt.c
@@ -98,7 +98,6 @@
 
 typedef struct xdf_objfmt_output_info {
     yasm_objfmt_xdf *objfmt_xdf;
-    yasm_errwarns *errwarns;
     /*@dependent@*/ FILE *f;
     /*@only@*/ unsigned char *buf;
     yasm_section *sect;
@@ -159,15 +158,14 @@
 
 static int
 xdf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-			unsigned long offset, yasm_bytecode *bc, int warn,
-			/*@null@*/ void *d)
+			size_t valsize, int shift, unsigned long offset,
+			yasm_bytecode *bc, int warn, /*@null@*/ void *d)
 {
     /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
     yasm_objfmt_xdf *objfmt_xdf;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_minus;
     int retval;
-    unsigned int valsize = value->size;
 
     assert(info != NULL);
     objfmt_xdf = info->objfmt_xdf;
@@ -179,8 +177,8 @@
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
-				    info->objfmt_xdf->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
+				    warn, info->objfmt_xdf->arch,
 				    yasm_common_calc_bc_dist)) {
 	case -1:
 	    return 1;
@@ -191,8 +189,7 @@
     }
 
     if (value->section_rel) {
-	yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-		       N_("xdf: relocation too complex"));
+	yasm__error(bc->line, N_("xdf: relocation too complex"));
 	return 1;
     }
 
@@ -226,23 +223,22 @@
 
     if (intn_minus > 0) {
 	intn = yasm_intnum_create_uint(intn_minus);
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, bc->line);
     } else
 	intn = yasm_intnum_create_uint(0);
 
     if (value->abs) {
 	yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, NULL);
 	if (!intn2) {
-	    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-			   N_("xdf: relocation too complex"));
+	    yasm__error(bc->line, N_("xdf: relocation too complex"));
 	    yasm_intnum_destroy(intn);
 	    return 1;
 	}
-	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
+	yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2, bc->line);
     }
 
     retval = yasm_arch_intnum_tobytes(objfmt_xdf->arch, intn, buf, destsize,
-				      valsize, 0, bc, warn);
+				      valsize, shift, bc, warn, bc->line);
     yasm_intnum_destroy(intn);
     return retval;
 }
@@ -272,8 +268,8 @@
     /* Warn that gaps are converted to 0 and write out the 0's. */
     if (gap) {
 	unsigned long left;
-	yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
-		      N_("uninitialized space: zeroing"));
+	yasm__warning(YASM_WARN_UNINIT_CONTENTS, bc->line,
+	    N_("uninitialized space: zeroing"));
 	/* Write out in chunks */
 	memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
 	left = size;
@@ -328,8 +324,7 @@
 
 	info->sect = sect;
 	info->xsd = xsd;
-	yasm_section_bcs_traverse(sect, info->errwarns, info,
-				  xdf_objfmt_output_bytecode);
+	yasm_section_bcs_traverse(sect, info, xdf_objfmt_output_bytecode);
 
 	/* Sanity check final section size */
 	if (xsd->size != (last->offset + last->len))
@@ -365,7 +360,7 @@
 	    yasm_internal_error(
 		N_("xdf: no symbol data for relocated symbol"));
 
-	yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0);
+	yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0, 0);
 	localbuf += 4;				/* address of relocation */
 	YASM_WRITE_32_L(localbuf, xsymd->index);    /* relocated symbol */
 	if (reloc->base) {
@@ -416,17 +411,17 @@
 
     YASM_WRITE_32_L(localbuf, xsymd->index);	/* section name symbol */
     if (xsd->addr) {
-	yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0);
+	yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0);
 	localbuf += 8;				/* physical address */
     } else {
 	YASM_WRITE_32_L(localbuf, 0);
 	YASM_WRITE_32_L(localbuf, 0);
     }
     if (xsd->vaddr) {
-	yasm_intnum_get_sized(xsd->vaddr, localbuf, 8, 64, 0, 0, 0);
+	yasm_intnum_get_sized(xsd->vaddr, localbuf, 8, 64, 0, 0, 0, 0);
 	localbuf += 8;				/* virtual address */
     } else if (xsd->addr) {
-	yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0);
+	yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0);
 	localbuf += 8;				/* VA=PA */
     } else {
 	YASM_WRITE_32_L(localbuf, 0);
@@ -502,11 +497,10 @@
 		    abs_start = yasm_expr_copy(yasm_section_get_start(sect));
 		    intn = yasm_expr_get_intnum(&abs_start,
 						yasm_common_calc_bc_dist);
-		    if (!intn) {
-			yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+		    if (!intn)
+			yasm__error(abs_start->line,
 			    N_("absolute section start not an integer expression"));
-			yasm_errwarn_propagate(info->errwarns, abs_start->line);
-		    } else
+		    else
 			value = yasm_intnum_get_uint(intn);
 		    yasm_expr_destroy(abs_start);
 
@@ -522,11 +516,9 @@
 	    intn = yasm_expr_get_intnum(&equ_val_copy,
 					yasm_common_calc_bc_dist);
 	    if (!intn) {
-		if (vis & YASM_SYM_GLOBAL) {
-		    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
+		if (vis & YASM_SYM_GLOBAL)
+		    yasm__error(equ_val->line,
 			N_("global EQU value not an integer expression"));
-		    yasm_errwarn_propagate(info->errwarns, equ_val->line);
-		}
 	    } else
 		value = yasm_intnum_get_uint(intn);
 	    yasm_expr_destroy(equ_val_copy);
@@ -569,7 +561,7 @@
 
 static void
 xdf_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms,
-		  /*@unused@*/ yasm_dbgfmt *df, yasm_errwarns *errwarns)
+		  /*@unused@*/ yasm_dbgfmt *df)
 {
     yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;
     xdf_objfmt_output_info info;
@@ -577,7 +569,6 @@
     unsigned long symtab_count = 0;
 
     info.objfmt_xdf = objfmt_xdf;
-    info.errwarns = errwarns;
     info.f = f;
     info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
 
@@ -703,7 +694,7 @@
 
     while ((vp = yasm_vps_next(vp))) {
 	if (!vp->val) {
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, line,
 			  N_("Unrecognized numeric qualifier"));
 	    continue;
 	}
@@ -729,17 +720,15 @@
 	    flags |= XDF_SECT_ABSOLUTE;
 	    absaddr = yasm_expr_get_intnum(&vp->param, NULL);
 	    if (!absaddr) {
-		yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			       N_("argument to `%s' is not an integer"),
-			       vp->val);
+		yasm__error(line, N_("argument to `%s' is not an integer"),
+			    vp->val);
 		return NULL;
 	    }
 	} else if (yasm__strcasecmp(vp->val, "virtual") == 0 && vp->param) {
 	    vaddr = yasm_expr_get_intnum(&vp->param, NULL);
 	    if (!vaddr) {
-		yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-			       N_("argument to `%s' is not an integer"),
-			       vp->val);
+		yasm__error(line, N_("argument to `%s' is not an integer"),
+			    vp->val);
 		return NULL;
 	    }
 	} else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
@@ -747,30 +736,28 @@
 
 	    align_expr = yasm_expr_get_intnum(&vp->param, NULL);
 	    if (!align_expr) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("argument to `%s' is not a power of two"),
-			       vp->val);
+		yasm__error(line, N_("argument to `%s' is not a power of two"),
+			    vp->val);
 		return NULL;
 	    }
 	    align = yasm_intnum_get_uint(align_expr);
 
             /* Alignments must be a power of two. */
             if ((align & (align - 1)) != 0) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("argument to `%s' is not a power of two"),
-			       vp->val);
+		yasm__error(line, N_("argument to `%s' is not a power of two"),
+			    vp->val);
 		return NULL;
 	    }
 
 	    /* Check to see if alignment is supported size */
 	    if (align > 4096) {
-		yasm_error_set(YASM_ERROR_VALUE,
-			       N_("XDF does not support alignments > 4096"));
+		yasm__error(line,
+			    N_("XDF does not support alignments > 4096"));
 		return NULL;
 	    }
 	} else
-	    yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
-			  vp->val);
+	    yasm__warning(YASM_WARN_GENERAL, line,
+			  N_("Unrecognized qualifier `%s'"), vp->val);
     }
 
     retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, align, 1,
@@ -796,7 +783,7 @@
 	}
 	yasm_section_set_align(retval, align, line);
     } else if (flags_override)
-	yasm_warn_set(YASM_WARN_GENERAL,
+	yasm__warning(YASM_WARN_GENERAL, line,
 		      N_("section flags ignored on section redeclaration"));
     return retval;
 }
@@ -863,7 +850,7 @@
     yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt;
 
     yasm_expr_destroy(size);
-    yasm_error_set(YASM_ERROR_GENERAL,
+    yasm__error(line,
 	N_("XDF object format does not support common variables"));
 
     return yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_COMMON,
diff --git a/modules/optimizers/basic/basic-optimizer.c b/modules/optimizers/basic/basic-optimizer.c
index 84c94ed..5e2965b 100644
--- a/modules/optimizers/basic/basic-optimizer.c
+++ b/modules/optimizers/basic/basic-optimizer.c
@@ -69,7 +69,8 @@
 		    if (dist < precbc1->offset + precbc1->len) {
 			intn = yasm_intnum_create_uint(precbc1->offset +
 						       precbc1->len - dist);
-			yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+			yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL,
+					 precbc1->line);
 			return intn;
 		    }
 		    dist -= precbc1->offset + precbc1->len;
@@ -85,7 +86,7 @@
 	if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
 	    if (precbc1->opt_flags == BCFLAG_DONE) {
 		intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
-		yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
+		yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
 		return intn;
 	    } else {
 		return NULL;
@@ -99,7 +100,6 @@
 typedef struct basic_optimize_data {
     /*@observer@*/ yasm_bytecode *precbc;
     int saw_unknown;
-    yasm_errwarns *errwarns;
 } basic_optimize_data;
 
 static int
@@ -126,8 +126,7 @@
     bcr_retval = yasm_bc_resolve(bc, 0, basic_optimize_calc_bc_dist_1);
     if (bcr_retval & YASM_BC_RESOLVE_UNKNOWN_LEN) {
 	if (!(bcr_retval & YASM_BC_RESOLVE_ERROR))
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("circular reference detected."));
+	    yasm__error(bc->line, N_("circular reference detected."));
 	data->saw_unknown = -1;
 	return 0;
     }
@@ -140,18 +139,13 @@
 static int
 basic_optimize_section_1(yasm_section *sect, /*@null@*/ void *d)
 {
-    basic_optimize_data *data = (basic_optimize_data *)d;
-    basic_optimize_data localdata;
+    /*@null@*/ int *saw_unknown = (int *)d;
+    basic_optimize_data data;
     unsigned long flags;
     int retval;
 
-    if (!data) {
-	data = &localdata;
-	localdata.saw_unknown = 0;
-	localdata.errwarns = NULL;
-    }
-
-    data->precbc = yasm_section_bcs_first(sect);
+    data.precbc = yasm_section_bcs_first(sect);
+    data.saw_unknown = 0;
 
     /* Don't even bother if we're in-progress or done. */
     flags = yasm_section_get_opt_flags(sect);
@@ -162,11 +156,13 @@
 
     yasm_section_set_opt_flags(sect, SECTFLAG_INPROGRESS);
 
-    retval = yasm_section_bcs_traverse(sect, data->errwarns, data,
-				       basic_optimize_bytecode_1);
+    retval = yasm_section_bcs_traverse(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;
@@ -201,17 +197,13 @@
     if (yasm_section_get_opt_flags(sect) != SECTFLAG_DONE)
 	yasm_internal_error(N_("Optimizer pass 1 missed a section!"));
 
-    return yasm_section_bcs_traverse(sect, NULL, &data,
-				     basic_optimize_bytecode_2);
+    return yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_2);
 }
 
 static void
-basic_optimize(yasm_object *object, yasm_errwarns *errwarns)
+basic_optimize(yasm_object *object)
 {
-    basic_optimize_data data;
-
-    data.saw_unknown = 0;
-    data.errwarns = errwarns;
+    int saw_unknown = 0;
 
     /* Optimization process: (essentially NASM's pass 1)
      *  Determine the size of all bytecodes.
@@ -225,9 +217,9 @@
      *   - not strictly top->bottom scanning; we scan through a section and
      *     hop to other sections as necessary.
      */
-    if (yasm_object_sections_traverse(object, &data,
+    if (yasm_object_sections_traverse(object, &saw_unknown,
 				      basic_optimize_section_1) < 0 ||
-	data.saw_unknown != 0)
+	saw_unknown != 0)
 	return;
 
     /* Check completion of all sections and save bytecode changes */
diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y
index 0eba1c8..5cd0989 100644
--- a/modules/parsers/gas/gas-bison.y
+++ b/modules/parsers/gas/gas-bison.y
@@ -69,8 +69,7 @@
      yasm_valparamhead *valparams,
      /*@null@*/ yasm_valparamhead *objext_valparams);
 
-#define gas_parser_error(s)	\
-    yasm_error_set(YASM_ERROR_PARSE, "%s", s)
+#define gas_parser_error(s)	yasm__parser_error(cur_line, s)
 #define YYPARSE_PARAM	parser_gas_arg
 #define YYLEX_PARAM	parser_gas_arg
 #define parser_gas	((yasm_parser_gas *)parser_gas_arg)
@@ -142,7 +141,6 @@
 %%
 input: /* empty */
     | input line    {
-	yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
 	if (parser_gas->save_input)
 	    yasm_linemap_add_source(parser_gas->linemap,
 		parser_gas->prev_bc,
@@ -154,8 +152,8 @@
 line: '\n'
     | linebcs '\n'
     | error '\n'	{
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("label or instruction expected at start of line"));
+	yasm__error(cur_line,
+		    N_("label or instruction expected at start of line"));
 	yyerrok;
     }
 ;
@@ -193,7 +191,7 @@
     | DIR_LINE INTNUM {
 	$$ = (yasm_bytecode *)NULL;
 	if (yasm_intnum_sign($2) < 0)
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("line number is negative"));
+	    yasm__error(cur_line, N_("line number is negative"));
 	else
 	    yasm_linemap_set(parser_gas->linemap, NULL,
 			     yasm_intnum_get_uint($2), 1);
@@ -204,11 +202,9 @@
 
 	$$ = (yasm_bytecode *)NULL;
 	if (!intn) {
-	    yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-			   N_("rept expression not absolute"));
+	    yasm__error(cur_line, N_("rept expression not absolute"));
 	} else if (yasm_intnum_sign(intn) < 0) {
-	    yasm_error_set(YASM_ERROR_VALUE,
-			   N_("rept expression is negative"));
+	    yasm__error(cur_line, N_("rept expression is negative"));
 	} else {
 	    gas_rept *rept = yasm_xmalloc(sizeof(gas_rept));
 	    STAILQ_INIT(&rept->lines);
@@ -227,7 +223,7 @@
     | DIR_ENDR {
 	$$ = (yasm_bytecode *)NULL;
 	/* Shouldn't ever get here unless we didn't get a DIR_REPT first */
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("endr without matching rept"));
+	yasm__error(cur_line, N_("endr without matching rept"));
     }
     /* Alignment directives */
     | DIR_ALIGN dirvals2 {
@@ -323,41 +319,41 @@
     }
     /* Integer data definition directives */
     | DIR_ASCII strvals {
-	$$ = yasm_bc_create_data(&$2, 1, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 1, 0, cur_line);
     }
     | DIR_ASCIZ strvals {
-	$$ = yasm_bc_create_data(&$2, 1, 1, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 1, 1, cur_line);
     }
     | DIR_BYTE datavals {
-	$$ = yasm_bc_create_data(&$2, 1, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 1, 0, cur_line);
     }
     | DIR_SHORT datavals {
 	/* TODO: This should depend on arch */
-	$$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
     }
     | DIR_WORD datavals {
-	$$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch)/8, 0,
-				 parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch), 0,
+				 cur_line);
     }
     | DIR_INT datavals {
 	/* TODO: This should depend on arch */
-	$$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
     }
     | DIR_VALUE datavals {
 	/* XXX: At least on x86, this is two bytes */
-	$$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
     }
     | DIR_2BYTE datavals {
-	$$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
     }
     | DIR_4BYTE datavals {
-	$$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
     }
     | DIR_QUAD datavals {
-	$$ = yasm_bc_create_data(&$2, 8, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 8, 0, cur_line);
     }
     | DIR_OCTA datavals {
-	$$ = yasm_bc_create_data(&$2, 16, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 16, 0, cur_line);
     }
     | DIR_ZERO expr {
 	yasm_datavalhead dvs;
@@ -365,7 +361,7 @@
 	yasm_dvs_initialize(&dvs);
 	yasm_dvs_append(&dvs, yasm_dv_create_expr(
 	    p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
-	$$ = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&dvs, 1, 0, cur_line);
 
 	yasm_bc_set_multiple($$, $2);
     }
@@ -377,13 +373,13 @@
     }
     /* Floating point data definition directives */
     | DIR_FLOAT datavals {
-	$$ = yasm_bc_create_data(&$2, 4, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
     }
     | DIR_DOUBLE datavals {
-	$$ = yasm_bc_create_data(&$2, 8, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 8, 0, cur_line);
     }
     | DIR_TFLOAT datavals {
-	$$ = yasm_bc_create_data(&$2, 10, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, 10, 0, cur_line);
     }
     /* Empty space / fill data definition directives */
     | DIR_SKIP expr {
@@ -394,7 +390,7 @@
 
 	yasm_dvs_initialize(&dvs);
 	yasm_dvs_append(&dvs, yasm_dv_create_expr($4));
-	$$ = yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line);
+	$$ = yasm_bc_create_data(&dvs, 1, 0, cur_line);
 
 	yasm_bc_set_multiple($$, $2);
     }
@@ -459,10 +455,10 @@
 	    yasm_dvs_append(&dvs, yasm_dv_create_expr(
 		p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
 	    yasm_section_bcs_append(comment,
-		yasm_bc_create_data(&dvs, 1, 0, parser_gas->arch, cur_line));
+				    yasm_bc_create_data(&dvs, 1, 0, cur_line));
 	}
 	yasm_section_bcs_append(comment,
-	    yasm_bc_create_data(&$2, 1, 1, parser_gas->arch, cur_line));
+				yasm_bc_create_data(&$2, 1, 1, cur_line));
 	$$ = NULL;
     }
     | DIR_FILE INTNUM STRING {
@@ -562,15 +558,15 @@
 	$$ = NULL;
     }
     | DIR_ID dirvals	{
-	yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
-		      $1);
+	yasm__warning(YASM_WARN_GENERAL, cur_line,
+		      N_("directive `%s' not recognized"), $1);
 	$$ = (yasm_bytecode *)NULL;
 	yasm_xfree($1);
 	yasm_vps_delete(&$2);
     }
     | DIR_ID error	{
-	yasm_warn_set(YASM_WARN_GENERAL, N_("directive `%s' not recognized"),
-		      $1);
+	yasm__warning(YASM_WARN_GENERAL, cur_line,
+		      N_("directive `%s' not recognized"), $1);
 	$$ = (yasm_bytecode *)NULL;
 	yasm_xfree($1);
     }
@@ -589,7 +585,7 @@
 				 &$2.operands, cur_line);
     }
     | INSN error	{
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
+	yasm__error(cur_line, N_("expression syntax error"));
 	$$ = NULL;
     }
     | PREFIX instr	{
@@ -609,18 +605,15 @@
 	yasm_bc_insn_add_seg_prefix($$, $1[0]);
     }
     | ID {
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("instruction not recognized: `%s'"), $1);
+	yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
 	$$ = NULL;
     }
     | ID operands {
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("instruction not recognized: `%s'"), $1);
+	yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
 	$$ = NULL;
     }
     | ID error {
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("instruction not recognized: `%s'"), $1);
+	yasm__error(cur_line, N_("instruction not recognized: `%s'"), $1);
 	$$ = NULL;
     }
 ;
@@ -702,7 +695,7 @@
     }
     | '(' ',' INTNUM ')'    {
 	if (yasm_intnum_get_uint($3) != 1)
-	    yasm_warn_set(YASM_WARN_GENERAL,
+	    yasm__warning(YASM_WARN_GENERAL, cur_line,
 			  N_("scale factor of %u without an index register"),
 			  yasm_intnum_get_uint($3));
 	$$ = p_expr_new(yasm_expr_int(yasm_intnum_create_uint(0)),
@@ -739,7 +732,7 @@
     }
     | SEGREG ':' memaddr  {
 	$$ = $3;
-	yasm_ea_set_segreg($$, $1[0]);
+	yasm_ea_set_segreg($$, $1[0], cur_line);
     }
 ;
 
@@ -752,8 +745,8 @@
 	    yasm_arch_reggroup_get_reg(parser_gas->arch, $1[0],
 				       yasm_intnum_get_uint($3));
 	if (reg == 0) {
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"),
-			   yasm_intnum_get_uint($3));
+	    yasm__error(cur_line, N_("bad register index `%u'"),
+			yasm_intnum_get_uint($3));
 	    $$ = yasm_operand_create_reg($1[0]);
 	} else
 	    $$ = yasm_operand_create_reg(reg);
@@ -909,8 +902,7 @@
 	parser_gas->cur_section = new_section;
 	parser_gas->prev_bc = yasm_section_bcs_last(new_section);
     } else
-	yasm_error_set(YASM_ERROR_GENERAL, N_("invalid section name `%s'"),
-		       name);
+	yasm__error(cur_line, N_("invalid section name `%s'"), name);
 
     yasm_xfree(name);
 
@@ -962,8 +954,7 @@
     if (bound && boundval) {
 	fill = yasm_vps_next(bound);
     } else {
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("align directive must specify alignment"));
+	yasm__error(cur_line, N_("align directive must specify alignment"));
 	return NULL;
     }
 
@@ -997,8 +988,7 @@
 	/*@dependent@*/ /*@null@*/ yasm_intnum *intn;
 	intn = yasm_expr_get_intnum(&size, NULL);
 	if (!intn) {
-	    yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
-			   N_("size must be an absolute expression"));
+	    yasm__error(cur_line, N_("size must be an absolute expression"));
 	    yasm_expr_destroy(repeat);
 	    yasm_expr_destroy(size);
 	    if (value)
@@ -1015,7 +1005,7 @@
 
     yasm_dvs_initialize(&dvs);
     yasm_dvs_append(&dvs, yasm_dv_create_expr(value));
-    bc = yasm_bc_create_data(&dvs, ssize, 0, parser_gas->arch, cur_line);
+    bc = yasm_bc_create_data(&dvs, ssize, 0, cur_line);
 
     yasm_bc_set_multiple(bc, repeat);
 
@@ -1035,8 +1025,7 @@
 	;
     } else if (yasm_objfmt_directive(parser_gas->objfmt, name, valparams,
 				     objext_valparams, line)) {
-	yasm_error_set(YASM_ERROR_GENERAL, N_("unrecognized directive [%s]"),
-		       name);
+	yasm__error(line, N_("unrecognized directive [%s]"), name);
     }
 
     yasm_vps_delete(valparams);
diff --git a/modules/parsers/gas/gas-parser.c b/modules/parsers/gas/gas-parser.c
index e1a3635..e8f72ed 100644
--- a/modules/parsers/gas/gas-parser.c
+++ b/modules/parsers/gas/gas-parser.c
@@ -40,7 +40,7 @@
 gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
 		    yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
 		    const char *in_filename, int save_input,
-		    yasm_section *def_sect, yasm_errwarns *errwarns)
+		    yasm_section *def_sect)
 {
     yasm_parser_gas parser_gas;
 
@@ -57,7 +57,6 @@
     parser_gas.arch = a;
     parser_gas.objfmt = of;
     parser_gas.dbgfmt = df;
-    parser_gas.errwarns = errwarns;
 
     parser_gas.cur_section = def_sect;
     parser_gas.prev_bc = yasm_section_bcs_first(def_sect);
@@ -88,10 +87,9 @@
     gas_parser_parse(&parser_gas);
 
     /* Check for ending inside a rept */
-    if (parser_gas.rept) {
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("rept without matching endr"));
-	yasm_errwarn_propagate(errwarns, parser_gas.rept->startline);
-    }
+    if (parser_gas.rept)
+	yasm__error(parser_gas.rept->startline,
+		    N_("rept without matching endr"));
 
     gas_parser_cleanup(&parser_gas);
 
diff --git a/modules/parsers/gas/gas-parser.h b/modules/parsers/gas/gas-parser.h
index c26c939..2d3e0a2 100644
--- a/modules/parsers/gas/gas-parser.h
+++ b/modules/parsers/gas/gas-parser.h
@@ -75,7 +75,6 @@
     /*@dependent@*/ yasm_arch *arch;
     /*@dependent@*/ yasm_objfmt *objfmt;
     /*@dependent@*/ yasm_dbgfmt *dbgfmt;
-    /*@dependent@*/ yasm_errwarns *errwarns;
 
     /*@dependent@*/ yasm_linemap *linemap;
     /*@dependent@*/ yasm_symtab *symtab;
diff --git a/modules/parsers/gas/gas-token.re b/modules/parsers/gas/gas-token.re
index 6edbc4c..35c6f86 100644
--- a/modules/parsers/gas/gas-token.re
+++ b/modules/parsers/gas/gas-token.re
@@ -223,8 +223,7 @@
 	      int ch)
 {
     if (cursor == s->eof)
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("unexpected end of file in string"));
+	yasm__error(line, N_("unexpected end of file in string"));
 
     if (count >= strbuf_size) {
 	strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
@@ -280,7 +279,7 @@
 	([1-9] digit*) | "0" {
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_dec(TOK);
+	    lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -289,7 +288,7 @@
 	'0b' bindigit+ {
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_bin(TOK+2);
+	    lvalp->intn = yasm_intnum_create_bin(TOK+2, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -298,7 +297,7 @@
 	"0" octdigit+ {
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_oct(TOK);
+	    lvalp->intn = yasm_intnum_create_oct(TOK, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -308,7 +307,7 @@
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
 	    /* skip 0 and x */
-	    lvalp->intn = yasm_intnum_create_hex(TOK+2);
+	    lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -415,7 +414,8 @@
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
 	    switch (yasm_arch_parse_check_regtmod
-		    (parser_gas->arch, lvalp->arch_data, TOK+1, TOKLEN-1)) {
+		    (parser_gas->arch, lvalp->arch_data, TOK+1, TOKLEN-1,
+		     cur_line)) {
 		case YASM_ARCH_REG:
 		    s->tok[TOKLEN] = savech;
 		    RETURN(REG);
@@ -428,8 +428,8 @@
 		default:
 		    break;
 	    }
-	    yasm_error_set(YASM_ERROR_GENERAL,
-			   N_("Unrecognized register name `%s'"), s->tok);
+	    yasm__error(cur_line, N_("Unrecognized register name `%s'"),
+			s->tok);
 	    s->tok[TOKLEN] = savech;
 	    lvalp->arch_data[0] = 0;
 	    lvalp->arch_data[1] = 0;
@@ -459,7 +459,8 @@
 		savech = s->tok[TOKLEN];
 		s->tok[TOKLEN] = '\0';
 		switch (yasm_arch_parse_check_insnprefix
-			(parser_gas->arch, lvalp->arch_data, TOK, TOKLEN)) {
+			(parser_gas->arch, lvalp->arch_data, TOK, TOKLEN,
+			 cur_line)) {
 		    case YASM_ARCH_INSN:
 			s->tok[TOKLEN] = savech;
 			parser_gas->state = INSTDIR;
@@ -471,8 +472,6 @@
 			s->tok[TOKLEN] = savech;
 		}
 	    }
-	    /* Propagate errors in case we got a warning from the arch */
-	    yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
 	    /* Just an identifier, return as such. */
 	    lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
 	    RETURN(ID);
@@ -490,7 +489,7 @@
 	}
 
 	any {
-	    yasm_warn_set(YASM_WARN_UNREC_CHAR,
+	    yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
 			  N_("ignoring unrecognized character `%s'"),
 			  yasm__conv_unprint(s->tok[0]));
 	    goto scan;
@@ -525,7 +524,7 @@
 	}
 
 	any {
-	    yasm_warn_set(YASM_WARN_UNREC_CHAR,
+	    yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
 			  N_("ignoring unrecognized character `%s'"),
 			  yasm__conv_unprint(s->tok[0]));
 	    goto section_directive;
@@ -570,7 +569,7 @@
 	"\\" digit digit digit	{
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_oct(TOK+1);
+	    lvalp->intn = yasm_intnum_create_oct(TOK+1, cur_line);
 	    s->tok[TOKLEN] = savech;
 
 	    strbuf_append(count++, cursor, s, cur_line,
@@ -581,7 +580,7 @@
 	'\\x' hexdigit+    {
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_hex(TOK+2);
+	    lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
 	    s->tok[TOKLEN] = savech;
 
 	    strbuf_append(count++, cursor, s, cur_line,
@@ -649,9 +648,7 @@
 	    int i;
 	    if (linestart) {
 		/* We don't support nested right now, error */
-		yasm_error_set(YASM_ERROR_GENERAL,
-			       N_("nested rept not supported"));
-		yasm_errwarn_propagate(parser_gas->errwarns, cur_line);
+		yasm__error(cur_line, N_("nested rept not supported"));
 	    }
 	    for (i=0; i<6; i++)
 		strbuf_append(count++, cursor, s, cur_line, s->tok[i]);
diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y
index d874f2e..d2d0665 100644
--- a/modules/parsers/nasm/nasm-bison.y
+++ b/modules/parsers/nasm/nasm-bison.y
@@ -48,7 +48,7 @@
 static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name,
 			 int local);
 
-#define nasm_parser_error(s)	yasm_error_set(YASM_ERROR_PARSE, "%s", s)
+#define nasm_parser_error(s)	yasm__parser_error(cur_line, s)
 #define YYPARSE_PARAM	parser_nasm_arg
 #define YYLEX_PARAM	parser_nasm_arg
 #define parser_nasm	((yasm_parser_nasm *)parser_nasm_arg)
@@ -130,7 +130,6 @@
 %%
 input: /* empty */
     | input line    {
-	yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
 	parser_nasm->temp_bc =
 	    yasm_section_bcs_append(parser_nasm->cur_section, $2);
 	if (parser_nasm->temp_bc)
@@ -161,8 +160,8 @@
 	$$ = (yasm_bytecode *)NULL;
     }
     | error '\n'	{
-	yasm_error_set(YASM_ERROR_SYNTAX,
-		       N_("label or instruction expected at start of line"));
+	yasm__error(cur_line,
+		    N_("label or instruction expected at start of line"));
 	$$ = (yasm_bytecode *)NULL;
 	yyerrok;
     }
@@ -171,8 +170,8 @@
 lineexp: exp
     | TIMES expr exp		{ $$ = $3; yasm_bc_set_multiple($$, $2); }
     | label_id			{
-	yasm_warn_set(YASM_WARN_ORPHAN_LABEL,
-	    N_("label alone on a line without a colon might be in error"));
+	yasm__warning(YASM_WARN_ORPHAN_LABEL, cur_line,
+		      N_("label alone on a line without a colon might be in error"));
 	$$ = (yasm_bytecode *)NULL;
 	define_label(parser_nasm, $1.name, $1.local);
     }
@@ -198,10 +197,10 @@
 
 exp: instr
     | DECLARE_DATA datavals		{
-	$$ = yasm_bc_create_data(&$2, $1/8, 0, parser_nasm->arch, cur_line);
+	$$ = yasm_bc_create_data(&$2, $1, 0, cur_line);
     }
     | RESERVE_SPACE expr		{
-	$$ = yasm_bc_create_reserve($2, $1/8, cur_line);
+	$$ = yasm_bc_create_reserve($2, $1, cur_line);
     }
     | INCBIN string			{
 	$$ = yasm_bc_create_incbin($2.contents, NULL, NULL, cur_line);
@@ -228,7 +227,7 @@
 				 &$2.operands, cur_line);
     }
     | INSN error	{
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
+	yasm__error(cur_line, N_("expression syntax error"));
 	$$ = NULL;
     }
     | PREFIX instr	{
@@ -254,7 +253,7 @@
 	$$ = yasm_dv_create_string($1.contents, $1.len);
     }
     | error		{
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("expression syntax error"));
+	yasm__error(cur_line, N_("expression syntax error"));
 	$$ = (yasm_dataval *)NULL;
     }
 ;
@@ -273,7 +272,7 @@
 	yasm_xfree($1);
     }
     | DIRECTIVE_NAME error		{
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid arguments to [%s]"), $1);
+	yasm__error(cur_line, N_("invalid arguments to [%s]"), $1);
 	yasm_xfree($1);
     }
 ;
@@ -331,7 +330,7 @@
     }
     | SEGREG ':' memaddr    {
 	$$ = $3;
-	yasm_ea_set_segreg($$, $1[0]);
+	yasm_ea_set_segreg($$, $1[0], cur_line);
     }
     | SIZE_OVERRIDE memaddr { $$ = $2; yasm_ea_set_len($$, $1); }
     | NOSPLIT memaddr	    { $$ = $2; yasm_ea_set_nosplit($$, 1); }
@@ -357,8 +356,7 @@
 	$$ = $2;
 	if ($$->type == YASM_INSN__OPERAND_REG &&
 	    yasm_arch_get_reg_size(parser_nasm->arch, $$->data.reg) != $1)
-	    yasm_error_set(YASM_ERROR_TYPE,
-			   N_("cannot override register size"));
+	    yasm__error(cur_line, N_("cannot override register size"));
 	else
 	    $$->size = $1;
     }
@@ -397,7 +395,7 @@
     | FLTNUM		    { $$ = p_expr_new_ident(yasm_expr_float($1)); }
     | ONECHARSTR	    {
 	$$ = p_expr_new_ident(yasm_expr_int(
-	    yasm_intnum_create_charconst_nasm($1.contents)));
+	    yasm_intnum_create_charconst_nasm($1.contents, cur_line)));
 	yasm_xfree($1.contents);
     }
     | explabel		    { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
@@ -439,7 +437,7 @@
     | REG		{ $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
     | string		{
 	$$ = p_expr_new_ident(yasm_expr_int(
-	    yasm_intnum_create_charconst_nasm($1.contents)));
+	    yasm_intnum_create_charconst_nasm($1.contents, cur_line)));
 	yasm_xfree($1.contents);
     }
     | explabel		{ $$ = p_expr_new_ident(yasm_expr_sym($1)); }
@@ -551,24 +549,21 @@
 	    yasm_objfmt_extern_declare(parser_nasm->objfmt, vp->val,
 				       objext_valparams, line);
 	} else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
-			   "EXTERN");
+	    yasm__error(line, N_("invalid argument to [%s]"), "EXTERN");
     } else if (yasm__strcasecmp(name, "global") == 0) {
 	vp = yasm_vps_first(valparams);
 	if (vp->val) {
 	    yasm_objfmt_global_declare(parser_nasm->objfmt, vp->val,
 				       objext_valparams, line);
 	} else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
-			   "GLOBAL");
+	    yasm__error(line, 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_set(YASM_ERROR_SYNTAX,
-			       N_("no size specified in %s declaration"),
-			       "COMMON");
+		yasm__error(line, N_("no size specified in %s declaration"),
+			    "COMMON");
 	    else {
 		if (vp2->val) {
 		    yasm_objfmt_common_declare(parser_nasm->objfmt, vp->val,
@@ -583,8 +578,7 @@
 		}
 	    }
 	} else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
-			   "COMMON");
+	    yasm__error(line, N_("invalid argument to [%s]"), "COMMON");
     } else if (yasm__strcasecmp(name, "section") == 0 ||
 	       yasm__strcasecmp(name, "segment") == 0) {
 	yasm_section *new_section =
@@ -594,8 +588,7 @@
 	    parser_nasm->cur_section = new_section;
 	    parser_nasm->prev_bc = yasm_section_bcs_last(new_section);
 	} else
-	    yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
-			   "SECTION");
+	    yasm__error(line, 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);
@@ -654,18 +647,17 @@
 	yasm_vps_foreach(vp, valparams) {
 	    if (vp->val)
 		yasm_arch_parse_cpu(parser_nasm->arch, vp->val,
-				    strlen(vp->val));
+				    strlen(vp->val), line);
 	    else if (vp->param) {
 		const yasm_intnum *intcpu;
 		intcpu = yasm_expr_get_intnum(&vp->param, NULL);
 		if (!intcpu)
-		    yasm_error_set(YASM_ERROR_SYNTAX,
-				   N_("invalid argument to [%s]"), "CPU");
+		    yasm__error(line, N_("invalid argument to [%s]"), "CPU");
 		else {
 		    char strcpu[16];
 		    sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
 		    yasm_arch_parse_cpu(parser_nasm->arch, strcpu,
-					strlen(strcpu));
+					strlen(strcpu), line);
 		}
 	    }
 	}
@@ -678,8 +670,7 @@
 	;
     } else if (yasm_objfmt_directive(parser_nasm->objfmt, name, valparams,
 				     objext_valparams, line)) {
-	yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive [%s]"),
-		       name);
+	yasm__error(line, N_("unrecognized directive [%s]"), name);
     }
 
     yasm_vps_delete(valparams);
diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c
index ade9a07..107b24a 100644
--- a/modules/parsers/nasm/nasm-parser.c
+++ b/modules/parsers/nasm/nasm-parser.c
@@ -37,7 +37,7 @@
 nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
 		     yasm_objfmt *of, yasm_dbgfmt *df, FILE *f,
 		     const char *in_filename, int save_input,
-		     yasm_section *def_sect, yasm_errwarns *errwarns)
+		     yasm_section *def_sect)
 {
     yasm_parser_nasm parser_nasm;
 
@@ -54,7 +54,6 @@
     parser_nasm.arch = a;
     parser_nasm.objfmt = of;
     parser_nasm.dbgfmt = df;
-    parser_nasm.errwarns = errwarns;
 
     parser_nasm.cur_section = def_sect;
     parser_nasm.prev_bc = yasm_section_bcs_first(def_sect);
diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h
index a8a4a61..d3ae1c2 100644
--- a/modules/parsers/nasm/nasm-parser.h
+++ b/modules/parsers/nasm/nasm-parser.h
@@ -52,7 +52,6 @@
     /*@dependent@*/ yasm_arch *arch;
     /*@dependent@*/ yasm_objfmt *objfmt;
     /*@dependent@*/ yasm_dbgfmt *dbgfmt;
-    /*@dependent@*/ yasm_errwarns *errwarns;
 
     /*@dependent@*/ yasm_linemap *linemap;
     /*@dependent@*/ yasm_symtab *symtab;
diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re
index b8f9b13..e110eb2 100644
--- a/modules/parsers/nasm/nasm-token.re
+++ b/modules/parsers/nasm/nasm-token.re
@@ -186,7 +186,7 @@
 	digit+ {
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_dec(TOK);
+	    lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -194,21 +194,21 @@
 
 	bindigit+ 'b' {
 	    s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
-	    lvalp->intn = yasm_intnum_create_bin(TOK);
+	    lvalp->intn = yasm_intnum_create_bin(TOK, cur_line);
 	    RETURN(INTNUM);
 	}
 
 	/* 777q or 777o - octal number */
 	octdigit+ [qQoO] {
 	    s->tok[TOKLEN-1] = '\0'; /* strip off 'q' or 'o' */
-	    lvalp->intn = yasm_intnum_create_oct(TOK);
+	    lvalp->intn = yasm_intnum_create_oct(TOK, cur_line);
 	    RETURN(INTNUM);
 	}
 
 	/* 0AAh form of hexidecimal number */
 	digit hexdigit* 'h' {
 	    s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
-	    lvalp->intn = yasm_intnum_create_hex(TOK);
+	    lvalp->intn = yasm_intnum_create_hex(TOK, cur_line);
 	    RETURN(INTNUM);
 	}
 
@@ -218,10 +218,10 @@
 	    s->tok[TOKLEN] = '\0';
 	    if (s->tok[1] == 'x')
 		/* skip 0 and x */
-		lvalp->intn = yasm_intnum_create_hex(TOK+2);
+		lvalp->intn = yasm_intnum_create_hex(TOK+2, cur_line);
 	    else
 		/* don't skip 0 */
-		lvalp->intn = yasm_intnum_create_hex(TOK+1);
+		lvalp->intn = yasm_intnum_create_hex(TOK+1, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -249,7 +249,7 @@
 	}
 
 	/* size specifiers */
-	'byte'		{ lvalp->int_info = 8; RETURN(SIZE_OVERRIDE); }
+	'byte'		{ lvalp->int_info = 1; RETURN(SIZE_OVERRIDE); }
 	'hword'		{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
 	    RETURN(SIZE_OVERRIDE);
@@ -266,14 +266,14 @@
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
 	    RETURN(SIZE_OVERRIDE);
 	}
-	'tword'		{ lvalp->int_info = 80; RETURN(SIZE_OVERRIDE); }
+	'tword'		{ lvalp->int_info = 10; RETURN(SIZE_OVERRIDE); }
 	'dqword'	{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
 	    RETURN(SIZE_OVERRIDE);
 	}
 
 	/* pseudo-instructions */
-	'db'		{ lvalp->int_info = 8; RETURN(DECLARE_DATA); }
+	'db'		{ lvalp->int_info = 1; RETURN(DECLARE_DATA); }
 	'dhw'		{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
 	    RETURN(DECLARE_DATA);
@@ -290,13 +290,13 @@
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
 	    RETURN(DECLARE_DATA);
 	}
-	'dt'		{ lvalp->int_info = 80; RETURN(DECLARE_DATA); }
+	'dt'		{ lvalp->int_info = 10; RETURN(DECLARE_DATA); }
 	'ddq'		{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
 	    RETURN(DECLARE_DATA);
 	}
 
-	'resb'		{ lvalp->int_info = 8; RETURN(RESERVE_SPACE); }
+	'resb'		{ lvalp->int_info = 1; RETURN(RESERVE_SPACE); }
 	'reshw'		{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
 	    RETURN(RESERVE_SPACE);
@@ -313,7 +313,7 @@
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
 	    RETURN(RESERVE_SPACE);
 	}
-	'rest'		{ lvalp->int_info = 80; RETURN(RESERVE_SPACE); }
+	'rest'		{ lvalp->int_info = 10; RETURN(RESERVE_SPACE); }
 	'resdq'		{
 	    lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
 	    RETURN(RESERVE_SPACE);
@@ -359,7 +359,7 @@
 		RETURN(ID);
 	    } else if (!parser_nasm->locallabel_base) {
 		lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
-		yasm_warn_set(YASM_WARN_GENERAL,
+		yasm__warning(YASM_WARN_GENERAL, cur_line,
 			      N_("no non-local label before `%s'"),
 			      lvalp->str_val);
 	    } else {
@@ -385,7 +385,8 @@
 	    s->tok[TOKLEN] = '\0';
 	    if (parser_nasm->state != INSTRUCTION)
 		switch (yasm_arch_parse_check_insnprefix
-			(parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN)) {
+			(parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN,
+			 cur_line)) {
 		    case YASM_ARCH_INSN:
 			parser_nasm->state = INSTRUCTION;
 			s->tok[TOKLEN] = savech;
@@ -397,7 +398,8 @@
 			break;
 		}
 	    switch (yasm_arch_parse_check_regtmod
-		    (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN)) {
+		    (parser_nasm->arch, lvalp->arch_data, TOK, TOKLEN,
+		     cur_line)) {
 		case YASM_ARCH_REG:
 		    s->tok[TOKLEN] = savech;
 		    RETURN(REG);
@@ -410,8 +412,6 @@
 		default:
 		    s->tok[TOKLEN] = savech;
 	    }
-	    /* Propagate errors in case we got a warning from the arch */
-	    yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
 	    /* Just an identifier, return as such. */
 	    lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
 	    RETURN(ID);
@@ -429,7 +429,7 @@
 	}
 
 	any {
-	    yasm_warn_set(YASM_WARN_UNREC_CHAR,
+	    yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
 			  N_("ignoring unrecognized character `%s'"),
 			  yasm__conv_unprint(s->tok[0]));
 	    goto scan;
@@ -445,7 +445,7 @@
 	    linechg_numcount++;
 	    savech = s->tok[TOKLEN];
 	    s->tok[TOKLEN] = '\0';
-	    lvalp->intn = yasm_intnum_create_dec(TOK);
+	    lvalp->intn = yasm_intnum_create_dec(TOK, cur_line);
 	    s->tok[TOKLEN] = savech;
 	    RETURN(INTNUM);
 	}
@@ -470,7 +470,7 @@
 	}
 
 	any {
-	    yasm_warn_set(YASM_WARN_UNREC_CHAR,
+	    yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
 			  N_("ignoring unrecognized character `%s'"),
 			  yasm__conv_unprint(s->tok[0]));
 	    goto linechg;
@@ -516,7 +516,7 @@
 	}
 
 	any {
-	    yasm_warn_set(YASM_WARN_UNREC_CHAR,
+	    yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
 			  N_("ignoring unrecognized character `%s'"),
 			  yasm__conv_unprint(s->tok[0]));
 	    goto directive;
@@ -535,10 +535,10 @@
     /*!re2c
 	"\n"	{
 	    if (cursor == s->eof)
-		yasm_error_set(YASM_ERROR_SYNTAX,
-			       N_("unexpected end of file in string"));
+		yasm__error(cur_line,
+			    N_("unexpected end of file in string"));
 	    else
-		yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string"));
+		yasm__error(cur_line, N_("unterminated string"));
 	    strbuf[count] = '\0';
 	    lvalp->str.contents = (char *)strbuf;
 	    lvalp->str.len = count;
diff --git a/modules/preprocs/nasm/nasm-eval.c b/modules/preprocs/nasm/nasm-eval.c
index b85cfbf..333af29 100644
--- a/modules/preprocs/nasm/nasm-eval.c
+++ b/modules/preprocs/nasm/nasm-eval.c
@@ -9,21 +9,217 @@
  */
 #include <util.h>
 #include <libyasm/coretype.h>
-#include <libyasm/intnum.h>
-#include <libyasm/expr.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) {
+	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,
@@ -58,83 +254,104 @@
  *       | number
  */
 
-static yasm_expr *rexp0(void), *rexp1(void), *rexp2(void), *rexp3(void);
+static nasm_expr *rexp0(int), *rexp1(int), *rexp2(int), *rexp3(int);
 
-static yasm_expr *expr0(void), *expr1(void), *expr2(void), *expr3(void);
-static yasm_expr *expr4(void), *expr5(void), *expr6(void);
+static nasm_expr *expr0(int), *expr1(int), *expr2(int), *expr3(int);
+static nasm_expr *expr4(int), *expr5(int), *expr6(int);
 
-static yasm_expr *(*bexpr)(void);
+static nasm_expr *(*bexpr)(int);
 
-static yasm_expr *rexp0(void) 
+static nasm_expr *rexp0(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = rexp1();
+    e = rexp1(critical);
     if (!e)
 	return NULL;
 
     while (i == TOKEN_DBL_OR) 
     {	
 	i = scan(scpriv, tokval);
-	f = rexp1();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
 
-	e = yasm_expr_create_tree(e, YASM_EXPR_LOR, f, 0);
+	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 yasm_expr *rexp1(void)
+static nasm_expr *rexp1(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = rexp2();
+    e = rexp2(critical);
     if (!e)
 	return NULL;
     
     while (i == TOKEN_DBL_XOR) 
     {
 	i = scan(scpriv, tokval);
-	f = rexp2();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
 
-	e = yasm_expr_create_tree(e, YASM_EXPR_LXOR, f, 0);
+	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 yasm_expr *rexp2(void) 
+static nasm_expr *rexp2(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = rexp3();
+    e = rexp3(critical);
     if (!e)
 	return NULL;
     while (i == TOKEN_DBL_AND) 
     {
 	i = scan(scpriv, tokval);
-	f = rexp3();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
-
-	e = yasm_expr_create_tree(e, YASM_EXPR_LAND, f, 0);
+	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 yasm_expr *rexp3(void) 
+static nasm_expr *rexp3(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
+    long v;
 
-    e = expr0();
+    e = expr0(critical);
     if (!e)
 	return NULL;
 
@@ -143,106 +360,137 @@
     {
 	int j = i;
 	i = scan(scpriv, tokval);
-	f = expr0();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	f = expr0(critical);
+	if (!f)
 	    return NULL;
-	}
+
+	e = add_vectors (e, scalar_mult(f, -1L, FALSE));
 
 	switch (j) 
 	{
-	    case TOKEN_EQ:
-		e = yasm_expr_create_tree(e, YASM_EXPR_EQ, f, 0);
-		break;
-	    case TOKEN_LT:
-		e = yasm_expr_create_tree(e, YASM_EXPR_LT, f, 0);
-		break;
-	    case TOKEN_GT:
-		e = yasm_expr_create_tree(e, YASM_EXPR_GT, f, 0);
-		break;
-	    case TOKEN_NE:
-		e = yasm_expr_create_tree(e, YASM_EXPR_NE, f, 0);
-		break;
-	    case TOKEN_LE:
-		e = yasm_expr_create_tree(e, YASM_EXPR_LE, f, 0);
-		break;
-	    case TOKEN_GE:
-		e = yasm_expr_create_tree(e, YASM_EXPR_GE, f, 0);
-		break;
+	  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 yasm_expr *expr0(void) 
+static nasm_expr *expr0(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr1();
+    e = expr1(critical);
     if (!e)
 	return NULL;
 
     while (i == '|') 
     {
 	i = scan(scpriv, tokval);
-	f = expr1();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
-
-	e = yasm_expr_create_tree(e, YASM_EXPR_OR, f, 0);
+	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 yasm_expr *expr1(void) 
+static nasm_expr *expr1(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr2();
+    e = expr2(critical);
     if (!e)
 	return NULL;
 
     while (i == '^') {
 	i = scan(scpriv, tokval);
-	f = expr2();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
-
-	e = yasm_expr_create_tree(e, YASM_EXPR_XOR, f, 0);
+	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 yasm_expr *expr2(void) 
+static nasm_expr *expr2(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr3();
+    e = expr3(critical);
     if (!e)
 	return NULL;
 
     while (i == '&') {
 	i = scan(scpriv, tokval);
-	f = expr3();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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");
 	}
-
-	e = yasm_expr_create_tree(e, YASM_EXPR_AND, f, 0);
+	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 yasm_expr *expr3(void) 
+static nasm_expr *expr3(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr4();
+    e = expr4(critical);
     if (!e)
 	return NULL;
 
@@ -250,57 +498,60 @@
     {
 	int j = i;
 	i = scan(scpriv, tokval);
-	f = expr4();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	f = expr4(critical);
+	if (!f)
 	    return NULL;
-	}
-
-	switch (j) {
-	    case TOKEN_SHL:
-		e = yasm_expr_create_tree(e, YASM_EXPR_SHL, f, 0);
-		break;
-	    case TOKEN_SHR:
-		e = yasm_expr_create_tree(e, YASM_EXPR_SHR, f, 0);
-		break;
+	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 ((long)(((unsigned long)nasm_reloc_value(e)) >>
+			    nasm_reloc_value(f)));
+	    break;
 	}
     }
     return e;
 }
 
-static yasm_expr *expr4(void)
+static nasm_expr *expr4(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr5();
+    e = expr5(critical);
     if (!e)
 	return NULL;
     while (i == '+' || i == '-') 
     {
 	int j = i;
 	i = scan(scpriv, tokval);
-	f = expr5();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	f = expr5(critical);
+	if (!f)
 	    return NULL;
-	}
 	switch (j) {
 	  case '+':
-	    e = yasm_expr_create_tree(e, YASM_EXPR_ADD, f, 0);
+	    e = add_vectors (e, f);
 	    break;
 	  case '-':
-	    e = yasm_expr_create_tree(e, YASM_EXPR_SUB, f, 0);
+	    e = add_vectors (e, scalar_mult(f, -1L, FALSE));
 	    break;
 	}
     }
     return e;
 }
 
-static yasm_expr *expr5(void)
+static nasm_expr *expr5(int critical) 
 {
-    yasm_expr *e, *f;
+    nasm_expr *e, *f;
 
-    e = expr6();
+    e = expr6(critical);
     if (!e)
 	return NULL;
     while (i == '*' || i == '/' || i == '%' ||
@@ -308,61 +559,111 @@
     {
 	int j = i;
 	i = scan(scpriv, tokval);
-	f = expr6();
-	if (!f) {
-	    yasm_expr_destroy(e);
+	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 '*':
-	    e = yasm_expr_create_tree(e, YASM_EXPR_MUL, f, 0);
+	    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 '/':
-	    e = yasm_expr_create_tree(e, YASM_EXPR_DIV, f, 0);
+	    if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
+		e = unknown_expr();
+	    else
+		e = scalarvect ((long)(((unsigned long)nasm_reloc_value(e)) /
+				((unsigned long)nasm_reloc_value(f))));
 	    break;
 	  case '%':
-	    e = yasm_expr_create_tree(e, YASM_EXPR_MOD, f, 0);
+	    if (nasm_is_just_unknown(e) || nasm_is_just_unknown(f))
+		e = unknown_expr();
+	    else
+		e = scalarvect ((long)(((unsigned long)nasm_reloc_value(e)) %
+				((unsigned long)nasm_reloc_value(f))));
 	    break;
 	  case TOKEN_SDIV:
-	    e = yasm_expr_create_tree(e, YASM_EXPR_SIGNDIV, f, 0);
+	    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:
-	    e = yasm_expr_create_tree(e, YASM_EXPR_SIGNMOD, f, 0);
+	    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 yasm_expr *expr6(void)
+static nasm_expr *expr6(int critical) 
 {
-    yasm_expr *e = NULL;
+    long type;
+    nasm_expr *e;
+    long label_seg, label_ofs;
 
     if (i == '-') {
 	i = scan(scpriv, tokval);
-	e = expr6();
+	e = expr6(critical);
 	if (!e)
 	    return NULL;
-	return yasm_expr_create_branch(YASM_EXPR_NEG, e, 0);
+	return scalar_mult (e, -1L, FALSE);
     } else if (i == '+') {
 	i = scan(scpriv, tokval);
-	return expr6();
+	return expr6(critical);
     } else if (i == '~') {
 	i = scan(scpriv, tokval);
-	e = expr6();
+	e = expr6(critical);
 	if (!e)
 	    return NULL;
-	return yasm_expr_create_branch(YASM_EXPR_NOT, e, 0);
+	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();
+	e = expr6(critical);
 	if (!e)
 	    return NULL;
-	error(ERR_NONFATAL, "%s not supported", "SEG");
+	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();
+	e = bexpr(critical);
 	if (!e)
 	    return NULL;
 	if (i != ')') {
@@ -372,34 +673,100 @@
 	i = scan(scpriv, tokval);
 	return e;
     } 
-    else if (i == TOKEN_NUM || i == TOKEN_ID ||
+    else if (i == TOKEN_NUM || i == TOKEN_REG || i == TOKEN_ID ||
 	     i == TOKEN_HERE || i == TOKEN_BASE) 
     {
+	begintemp();
 	switch (i) {
 	  case TOKEN_NUM:
-	    e = yasm_expr_create_ident(yasm_expr_int(tokval->t_integer), 0);
+	    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:
-	    error(ERR_NONFATAL, "%s not supported",
-		  (i == TOKEN_ID ? "symbol references" :
-		   i == TOKEN_HERE ? "`$'" : "`$$'"));
-	    e = yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_int(1)),
-				       0);
+	    /*
+	     * If !location->known, this indicates that no
+	     * symbol, Here or Base references are valid because we
+	     * are in preprocess-only mode.
+	     */
+	    if (!location || !location->known) {
+		error(ERR_NONFATAL,
+		      "%s not supported",
+		      (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 e;
+	return finishtemp();
     } else {
 	error(ERR_NONFATAL, "expression syntax error");
 	return NULL;
     }
 }
 
-yasm_expr *nasm_evaluate (scanner sc, void *scprivate, struct tokenval *tv,
-			  int critical, efunc report_error)
+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;
@@ -410,11 +777,52 @@
     scpriv = scprivate;
     tokval = tv;
     error = report_error;
+    opflags = fwref;
 
     if (tokval->t_type == TOKEN_INVALID)
 	i = scan(scpriv, tokval);
     else
 	i = tokval->t_type;
 
-    return bexpr ();
+    while (ntempexprs) {	       /* initialise temporary storage */
+	ntempexprs--;
+	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/modules/preprocs/nasm/nasm-eval.h b/modules/preprocs/nasm/nasm-eval.h
index 32e3da8..9249593 100644
--- a/modules/preprocs/nasm/nasm-eval.h
+++ b/modules/preprocs/nasm/nasm-eval.h
@@ -10,9 +10,19 @@
 #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.
  */
-yasm_expr *nasm_evaluate (scanner sc, void *scprivate, struct tokenval *tv,
-			  int critical, efunc report_error);
+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/modules/preprocs/nasm/nasm-pp.c b/modules/preprocs/nasm/nasm-pp.c
index 81548d6..21d119e 100644
--- a/modules/preprocs/nasm/nasm-pp.c
+++ b/modules/preprocs/nasm/nasm-pp.c
@@ -35,8 +35,6 @@
  */
 #include <util.h>
 #include <libyasm/coretype.h>
-#include <libyasm/intnum.h>
-#include <libyasm/expr.h>
 #include <libyasm/file.h>
 #include <stdarg.h>
 #include <ctype.h>
@@ -90,7 +88,7 @@
     MMacro *next;
     char *name;
     int casesense;
-    long nparam_min, nparam_max;
+    int nparam_min, nparam_max;
     int plus;			/* is the last parameter greedy? */
     int nolist;			/* is this macro listing-inhibited? */
     int in_progress;
@@ -103,7 +101,7 @@
     MMacro *rep_nest;		/* used for nesting %rep */
     Token **params;		/* actual parameters */
     Token *iline;		/* invocation line */
-    long nparam, rotate, *paramlen;
+    int nparam, rotate, *paramlen;
     unsigned long unique;
     int lineno;			/* Current line number on expansion */
 };
@@ -417,7 +415,7 @@
 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, yasm_intnum *val);
+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);
@@ -1289,6 +1287,7 @@
 inc_fopen(char *file, char **newname)
 {
     FILE *fp;
+    const char *prefix = "";
     char *combine = NULL;
 
     fp = yasm__fopen_include(file, nasm_src_get_fname(), (const char **)ipaths,
@@ -1424,8 +1423,7 @@
     int j, casesense;
     Token *t, *tt, **tptr, *origline;
     struct tokenval tokval;
-    yasm_expr *evalresult;
-    yasm_intnum *intn;
+    nasm_expr *evalresult;
 
     origline = tline;
 
@@ -1592,10 +1590,8 @@
 	    }
 	    else
 	    {
-		intn = nasm_readnum(tline->text, &j);
 		searching.nparam_min = searching.nparam_max =
-		    yasm_intnum_get_int(intn);
-		yasm_intnum_destroy(intn);
+			nasm_readnum(tline->text, &j);
 		if (j)
 		    error(ERR_NONFATAL,
 			  "unable to parse parameter count `%s'",
@@ -1612,9 +1608,7 @@
 			  directives[i]);
 		else
 		{
-		    intn = nasm_readnum(tline->text, &j);
-		    searching.nparam_max = yasm_intnum_get_int(intn);
-		    yasm_intnum_destroy(intn);
+		    searching.nparam_max = nasm_readnum(tline->text, &j);
 		    if (j)
 			error(ERR_NONFATAL,
 				"unable to parse parameter count `%s'",
@@ -1701,25 +1695,21 @@
 	    t = tline = expand_smacro(tline);
 	    tptr = &t;
 	    tokval.t_type = TOKEN_INVALID;
-	    evalresult = evaluate(ppscan, tptr, &tokval, pass | CRITICAL,
-				  error);
+	    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");
-	    intn = yasm_expr_get_intnum(&evalresult, NULL);
-	    if (!intn)
+	    if (!nasm_is_simple(evalresult))
 	    {
 		error(ERR_NONFATAL,
 			"non-constant value given to `%s'", directives[i]);
-		yasm_expr_destroy(evalresult);
 		return -1;
 	    }
-	    j = !yasm_intnum_is_zero(intn);
-	    yasm_expr_destroy(evalresult);
-	    return j;
+	    return nasm_reloc_value(evalresult) != 0;
 
 	default:
 	    error(ERR_FATAL,
@@ -1769,9 +1759,8 @@
     Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;
     Line *l;
     struct tokenval tokval;
-    yasm_expr *evalresult;
+    nasm_expr *evalresult;
     MMacro *tmp_defining;	/* Used when manipulating rep_nest */
-    yasm_intnum *intn;
 
     origline = tline;
 
@@ -2353,10 +2342,8 @@
 	    }
 	    else
 	    {
-		intn = nasm_readnum(tline->text, &j);
 		defining->nparam_min = defining->nparam_max =
-		    yasm_intnum_get_int(intn);
-		yasm_intnum_destroy(intn);
+			nasm_readnum(tline->text, &j);
 		if (j)
 		    error(ERR_NONFATAL,
 			    "unable to parse parameter count `%s'",
@@ -2373,9 +2360,7 @@
 			    (i == PP_IMACRO ? "i" : ""));
 		else
 		{
-		    intn = nasm_readnum(tline->text, &j);
-		    defining->nparam_max = yasm_intnum_get_int(intn);
-		    yasm_intnum_destroy(intn);
+		    defining->nparam_max = nasm_readnum(tline->text, &j);
 		    if (j)
 			error(ERR_NONFATAL,
 				"unable to parse parameter count `%s'",
@@ -2461,18 +2446,17 @@
 	    tline = t;
 	    tptr = &t;
 	    tokval.t_type = TOKEN_INVALID;
-	    evalresult = evaluate(ppscan, tptr, &tokval, pass, error);
+	    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");
-	    intn = yasm_expr_get_intnum(&evalresult, NULL);
-	    if (!intn)
+	    if (!nasm_is_simple(evalresult))
 	    {
 		error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
-		yasm_expr_destroy(evalresult);
 		return DIRECTIVE_FOUND;
 	    }
 	    mmac = istk->mstk;
@@ -2490,14 +2474,13 @@
 	    }
 	    else
 	    {
-		mmac->rotate = mmac->rotate + yasm_intnum_get_int(intn);
+		mmac->rotate = mmac->rotate + nasm_reloc_value(evalresult);
 		
 		if (mmac->rotate < 0)
 		    mmac->rotate = 
 			mmac->nparam - (-mmac->rotate) % mmac->nparam;
 		mmac->rotate %= mmac->nparam;
 	    }
-	    yasm_expr_destroy(evalresult);
 	    return DIRECTIVE_FOUND;
 
 	case PP_REP:
@@ -2520,7 +2503,8 @@
 		t = expand_smacro(tline);
 		tptr = &t;
 		tokval.t_type = TOKEN_INVALID;
-		evalresult = evaluate(ppscan, tptr, &tokval, pass, error);
+		evalresult =
+		    evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
 		if (!evalresult)
 		{
 		    free_tlist(origline);
@@ -2529,15 +2513,12 @@
 		if (tokval.t_type)
 		    error(ERR_WARNING,
 			  "trailing garbage after expression ignored");
-		intn = yasm_expr_get_intnum(&evalresult, NULL);
-		if (!intn)
+		if (!nasm_is_simple(evalresult))
 		{
 		    error(ERR_NONFATAL, "non-constant value given to `%%rep'");
-		    yasm_expr_destroy(evalresult);
 		    return DIRECTIVE_FOUND;
 		}
-		i = (int)yasm_intnum_get_int(intn) + 1;
-		yasm_expr_destroy(evalresult);
+		i = (int)nasm_reloc_value(evalresult) + 1;
 	    }
 	    else
 	    {
@@ -2836,8 +2817,7 @@
 
 	    macro_start = nasm_malloc(sizeof(*macro_start));
 	    macro_start->next = NULL;
-	    make_tok_num(macro_start,
-			 yasm_intnum_create_uint(strlen(t->text) - 2));
+	    make_tok_num(macro_start, (int)strlen(t->text) - 2);
 	    macro_start->mac = NULL;
 
 	    /*
@@ -2917,36 +2897,34 @@
 	    tt = t->next;
 	    tptr = &tt;
 	    tokval.t_type = TOKEN_INVALID;
-	    evalresult = evaluate(ppscan, tptr, &tokval, pass, error);
+	    evalresult =
+		    evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
 	    if (!evalresult)
 	    {
 		free_tlist(tline);
 		free_tlist(origline);
 		return DIRECTIVE_FOUND;
 	    }
-	    intn = yasm_expr_get_intnum(&evalresult, NULL);
-	    if (!intn)
+	    if (!nasm_is_simple(evalresult))
 	    {
 		error(ERR_NONFATAL, "non-constant value given to `%%substr`");
 		free_tlist(tline);
 		free_tlist(origline);
-		yasm_expr_destroy(evalresult);
 		return DIRECTIVE_FOUND;
 	    }
 
 	    macro_start = nasm_malloc(sizeof(*macro_start));
 	    macro_start->next = NULL;
 	    macro_start->text = nasm_strdup("'''");
-	    if (yasm_intnum_sign(intn) == 1
-		    && yasm_intnum_get_uint(intn) < strlen(t->text) - 1)
+	    if (evalresult->value > 0
+		    && evalresult->value < (int)strlen(t->text) - 1)
 	    {
-		macro_start->text[1] = t->text[yasm_intnum_get_uint(intn)];
+		macro_start->text[1] = t->text[evalresult->value];
 	    }
 	    else
 	    {
 		macro_start->text[2] = '\0';
 	    }
-	    yasm_expr_destroy(evalresult);
 	    macro_start->type = TOK_STRING;
 	    macro_start->mac = NULL;
 
@@ -3016,7 +2994,8 @@
 	    t = tline;
 	    tptr = &t;
 	    tokval.t_type = TOKEN_INVALID;
-	    evalresult = evaluate(ppscan, tptr, &tokval, pass, error);
+	    evalresult =
+		    evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
 	    free_tlist(tline);
 	    if (!evalresult)
 	    {
@@ -3028,21 +3007,18 @@
 		error(ERR_WARNING,
 			"trailing garbage after expression ignored");
 
-	    intn = yasm_expr_get_intnum(&evalresult, NULL);
-	    if (!intn)
+	    if (!nasm_is_simple(evalresult))
 	    {
 		error(ERR_NONFATAL,
 			"non-constant value given to `%%%sassign'",
 			(i == PP_IASSIGN ? "i" : ""));
 		free_tlist(origline);
-		yasm_expr_destroy(evalresult);
 		return DIRECTIVE_FOUND;
 	    }
 
 	    macro_start = nasm_malloc(sizeof(*macro_start));
 	    macro_start->next = NULL;
-	    make_tok_num(macro_start, yasm_intnum_copy(intn));
-	    yasm_expr_destroy(evalresult);
+	    make_tok_num(macro_start, nasm_reloc_value(evalresult));
 	    macro_start->mac = NULL;
 
 	    /*
@@ -3093,9 +3069,7 @@
 		free_tlist(origline);
 		return DIRECTIVE_FOUND;
 	    }
-	    intn = nasm_readnum(tline->text, &j);
-	    k = yasm_intnum_get_int(intn);
-	    yasm_intnum_destroy(intn);
+	    k = nasm_readnum(tline->text, &j);
 	    m = 1;
 	    tline = tline->next;
 	    if (tok_is_(tline, "+"))
@@ -3107,9 +3081,7 @@
 		    free_tlist(origline);
 		    return DIRECTIVE_FOUND;
 		}
-		intn = nasm_readnum(tline->text, &j);
-		m = yasm_intnum_get_int(intn);
-		yasm_intnum_destroy(intn);
+		m = nasm_readnum(tline->text, &j);
 		tline = tline->next;
 	    }
 	    skip_white_(tline);
@@ -3216,7 +3188,7 @@
 			 */
 		    case '0':
 			type = TOK_NUMBER;
-			sprintf(tmpbuf, "%ld", mac->nparam);
+			sprintf(tmpbuf, "%d", mac->nparam);
 			text = nasm_strdup(tmpbuf);
 			break;
 		    case '%':
@@ -3449,7 +3421,7 @@
 			if (!strcmp("__LINE__", m->name))
 			{
 			    nasm_free(tline->text);
-			    make_tok_num(tline, yasm_intnum_create_int(nasm_src_get_linnum()));
+			    make_tok_num(tline, nasm_src_get_linnum());
 			    continue;
 			}
 			tline = delete_Token(tline);
@@ -3930,8 +3902,7 @@
     Token **params, *t, *tt;
     MMacro *m;
     Line *l, *ll;
-    int i, nparam;
-    long *paramlen;
+    int i, nparam, *paramlen;
 
     t = tline;
     skip_white_(t);
@@ -4128,7 +4099,7 @@
     istk->mstk = NULL;
     istk->fp = f;
     istk->fname = NULL;
-    nasm_free(nasm_src_set_fname(nasm_strdup(file)));
+    nasm_src_set_fname(nasm_strdup(file));
     nasm_src_set_linnum(0);
     istk->lineinc = 1;
     defining = NULL;
@@ -4536,9 +4507,11 @@
 }
 
 static void
-make_tok_num(Token * tok, yasm_intnum *val)
+make_tok_num(Token * tok, long val)
 {
-    tok->text = yasm_intnum_get_str(val);
+    char numbuf[20];
+    sprintf(numbuf, "%ld", val);
+    tok->text = nasm_strdup(numbuf);
     tok->type = TOK_NUMBER;
 }
 
diff --git a/modules/preprocs/nasm/nasm-preproc.c b/modules/preprocs/nasm/nasm-preproc.c
index 253aebb..505d58b 100644
--- a/modules/preprocs/nasm/nasm-preproc.c
+++ b/modules/preprocs/nasm/nasm-preproc.c
@@ -46,7 +46,6 @@
     int lineinc;
 } yasm_preproc_nasm;
 static yasm_linemap *cur_lm;
-static yasm_errwarns *cur_errwarns;
 int tasm_compatible_mode = 0;
 
 typedef struct preproc_dep {
@@ -107,10 +106,11 @@
     va_start(va, fmt);
     switch (severity & ERR_MASK) {
 	case ERR_WARNING:
-	    yasm_warn_set_va(YASM_WARN_PREPROC, fmt, va);
+	    yasm__warning_va(YASM_WARN_PREPROC,
+			     yasm_linemap_get_current(cur_lm), fmt, va);
 	    break;
 	case ERR_NONFATAL:
-	    yasm_error_set_va(YASM_ERROR_GENERAL, fmt, va);
+	    yasm__error_va(yasm_linemap_get_current(cur_lm), fmt, va);
 	    break;
 	case ERR_FATAL:
 	    yasm_fatal(fmt, va);
@@ -123,12 +123,10 @@
 	    break;
     }
     va_end(va);
-    yasm_errwarn_propagate(cur_errwarns, yasm_linemap_get_current(cur_lm));
 }
 
 static yasm_preproc *
-nasm_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm,
-		    yasm_errwarns *errwarns)
+nasm_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm)
 {
     yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm));
 
@@ -136,7 +134,6 @@
 
     preproc_nasm->in = f;
     cur_lm = lm;
-    cur_errwarns = errwarns;
     preproc_deps = NULL;
     done_dep_preproc = 0;
     preproc_nasm->line = NULL;
@@ -152,6 +149,7 @@
 nasm_preproc_destroy(yasm_preproc *preproc)
 {
     nasmpp.cleanup(0);
+    nasm_eval_cleanup();
     yasm_xfree(preproc);
     if (preproc_deps)
 	yasm_xfree(preproc_deps);
diff --git a/modules/preprocs/nasm/nasm.h b/modules/preprocs/nasm/nasm.h
index 9a83543..d95eee8 100644
--- a/modules/preprocs/nasm/nasm.h
+++ b/modules/preprocs/nasm/nasm.h
@@ -21,6 +21,9 @@
 #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
@@ -36,6 +39,21 @@
 #define IDLEN_MAX 4096
 
 /*
+ * 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
  * -------------------------
@@ -84,6 +102,21 @@
  */
 
 /*
+ * 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 {
@@ -153,7 +186,7 @@
  */
 struct tokenval {
     int t_type;
-    yasm_intnum *t_integer, *t_inttwo;
+    long t_integer, t_inttwo;
     char *t_charptr;
 };
 typedef int (*scanner) (void *private_data, struct tokenval *tv);
@@ -179,12 +212,48 @@
     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
@@ -196,10 +265,27 @@
  * 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 yasm_expr *(*evalfunc) (scanner sc, void *scprivate, struct tokenval *tv,
-			   int critical, efunc error);
+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:
@@ -263,6 +349,478 @@
 };
 
 /*
+ * -----------------------------------------------------------
+ * 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_DL    0x00241001L
+#define REG_DX    0x00241002L
+#define REG_EDX   0x00241004L
+#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
  * -----
@@ -277,4 +835,15 @@
 
 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/modules/preprocs/nasm/nasmlib.c b/modules/preprocs/nasm/nasmlib.c
index 5d9ae4d..19bfeba 100644
--- a/modules/preprocs/nasm/nasmlib.c
+++ b/modules/preprocs/nasm/nasmlib.c
@@ -7,7 +7,6 @@
  */
 #include <util.h>
 #include <libyasm/coretype.h>
-#include <libyasm/intnum.h>
 #include <ctype.h>
 
 #include "nasm.h"
@@ -17,14 +16,14 @@
 #define lib_isnumchar(c)   ( isalnum(c) || (c) == '$')
 #define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
 
-yasm_intnum *nasm_readnum (char *str, int *error) 
+long nasm_readnum (char *str, int *error) 
 {
-    char *r = str, *q, *p;
+    char *r = str, *q;
     long radix;
-    yasm_intnum *intn;
-    char save;
-    int digit;
-    int sign = 0;
+    unsigned long result, checklimit;
+    int digit, last;
+    int warn = FALSE;
+    int sign = 1;
 
     *error = FALSE;
 
@@ -37,7 +36,7 @@
     if (*r == '-')
     {
 	r++;
-	sign = 1;
+	sign = -1;
     }
 
     q = r;
@@ -70,61 +69,237 @@
      */
     if (r >= q) {
 	*error = TRUE;
-	return yasm_intnum_create_uint(0);
+	return 0;
     }
 
-    /* Check for valid number of that radix */
-    p = r;
-    while (*p && p < q) {
-	if (*p<'0' || (*p>'9' && *p<'A') || (digit = numvalue(*p)) >= radix) 
+    /*
+     * `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 yasm_intnum_create_uint(0);
+	    return 0;
 	}
-	p++;
-    }
+	if (result > checklimit ||
+	    (result == checklimit && digit >= last))
+	{
+	    warn = TRUE;
+	}
 
-    /* Use intnum to actually do the conversion */
-    save = *q;
-    *q = '\0';
-    switch (radix) {
-	case 2:
-	    intn = yasm_intnum_create_bin(r);
-	    break;
-	case 8:
-	    intn = yasm_intnum_create_oct(r);
-	    break;
-	case 10:
-	    intn = yasm_intnum_create_dec(r);
-	    break;
-	case 16:
-	    intn = yasm_intnum_create_hex(r);
-	    break;
-	default:
-	    *error = TRUE;
-	    intn = yasm_intnum_create_uint(0);
-	    break;
+	result = radix * result + digit;
+	r++;
     }
-    *q = save;
-
-    if (sign)
-	yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
-    return intn;
+#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;
 }
 
-yasm_intnum *nasm_readstrnum (char *str, int length, int *warn) 
+long nasm_readstrnum (char *str, int length, int *warn) 
 {
-    char save;
-    yasm_intnum *intn;
+    long charconst = 0;
+    int i;
 
     *warn = FALSE;
 
-    save = str[length];
-    str[length] = '\0';
-    intn = yasm_intnum_create_charconst_nasm(str);
-    str[length] = save;
+    str += length;
+    for (i=0; i<length; i++) {
+	if (charconst & 0xff000000UL) {
+	    *warn = TRUE;
+	}
+	charconst = (charconst<<8) + (unsigned char) *--str;
+    }
+    return charconst;
+}
 
-    return intn;
+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;
@@ -190,7 +365,7 @@
     *str = p;
 }
     
-char *nasm_strcat(const char *one, const char *two) 
+char *nasm_strcat(char *one, char *two) 
 {
     char *rslt;
     int l1=strlen(one);
diff --git a/modules/preprocs/nasm/nasmlib.h b/modules/preprocs/nasm/nasmlib.h
index 37538f4..3648fcc 100644
--- a/modules/preprocs/nasm/nasmlib.h
+++ b/modules/preprocs/nasm/nasmlib.h
@@ -32,7 +32,7 @@
  * Convert a string into a number, using NASM number rules. Sets
  * `*error' to TRUE if an error occurs, and FALSE otherwise.
  */
-yasm_intnum *nasm_readnum(char *str, int *error);
+long nasm_readnum(char *str, int *error);
 
 /*
  * Convert a character constant into a number. Sets
@@ -40,7 +40,36 @@
  * str points to and length covers the middle of the string,
  * without the quotes.
  */
-yasm_intnum *nasm_readstrnum(char *str, int length, int *warn);
+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);
 char *nasm_src_get_fname(void);
@@ -55,6 +84,6 @@
 int nasm_src_get(long *xline, char **xname);
 
 void nasm_quote(char **str);
-char *nasm_strcat(const char *one, const char *two);
+char *nasm_strcat(char *one, char *two);
 
 #endif
diff --git a/modules/preprocs/nasm/tests/Makefile.inc b/modules/preprocs/nasm/tests/Makefile.inc
index 2dd9d02..db29295 100644
--- a/modules/preprocs/nasm/tests/Makefile.inc
+++ b/modules/preprocs/nasm/tests/Makefile.inc
@@ -10,9 +10,6 @@
 EXTRA_DIST += modules/preprocs/nasm/tests/longline.hex
 EXTRA_DIST += modules/preprocs/nasm/tests/noinclude-err.asm
 EXTRA_DIST += modules/preprocs/nasm/tests/noinclude-err.errwarn
-EXTRA_DIST += modules/preprocs/nasm/tests/nasmpp-bigint.asm
-EXTRA_DIST += modules/preprocs/nasm/tests/nasmpp-bigint.errwarn
-EXTRA_DIST += modules/preprocs/nasm/tests/nasmpp-bigint.hex
 EXTRA_DIST += modules/preprocs/nasm/tests/orgsect.asm
 EXTRA_DIST += modules/preprocs/nasm/tests/orgsect.errwarn
 EXTRA_DIST += modules/preprocs/nasm/tests/orgsect.hex
diff --git a/modules/preprocs/nasm/tests/ifcritical-err.errwarn b/modules/preprocs/nasm/tests/ifcritical-err.errwarn
index 7cc27b4..7cc7b03 100644
--- a/modules/preprocs/nasm/tests/ifcritical-err.errwarn
+++ b/modules/preprocs/nasm/tests/ifcritical-err.errwarn
@@ -1 +1,2 @@
 -:4: symbol references not supported
+-:4: non-constant value given to `%if'
diff --git a/modules/preprocs/nasm/tests/nasmpp-bigint.asm b/modules/preprocs/nasm/tests/nasmpp-bigint.asm
deleted file mode 100644
index 4314661..0000000
--- a/modules/preprocs/nasm/tests/nasmpp-bigint.asm
+++ /dev/null
@@ -1,3 +0,0 @@
-%if 0x100000000000000 > 0x1000000000000
-db 0
-%endif
diff --git a/modules/preprocs/nasm/tests/nasmpp-bigint.errwarn b/modules/preprocs/nasm/tests/nasmpp-bigint.errwarn
deleted file mode 100644
index e69de29..0000000
--- a/modules/preprocs/nasm/tests/nasmpp-bigint.errwarn
+++ /dev/null
diff --git a/modules/preprocs/nasm/tests/nasmpp-bigint.hex b/modules/preprocs/nasm/tests/nasmpp-bigint.hex
deleted file mode 100644
index 164742d..0000000
--- a/modules/preprocs/nasm/tests/nasmpp-bigint.hex
+++ /dev/null
@@ -1 +0,0 @@
-00 
diff --git a/modules/preprocs/raw/raw-preproc.c b/modules/preprocs/raw/raw-preproc.c
index 9f71674..7ad5cc4 100644
--- a/modules/preprocs/raw/raw-preproc.c
+++ b/modules/preprocs/raw/raw-preproc.c
@@ -37,7 +37,6 @@
     int is_interactive;
     FILE *in;
     yasm_linemap *cur_lm;
-    yasm_errwarns *errwarns;
 } yasm_preproc_raw;
 
 yasm_preproc_module yasm_raw_LTX_preproc;
@@ -45,15 +44,13 @@
 int isatty(int);
 
 static yasm_preproc *
-raw_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm,
-		   yasm_errwarns *errwarns)
+raw_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm)
 {
     yasm_preproc_raw *preproc_raw = yasm_xmalloc(sizeof(yasm_preproc_raw));
 
     preproc_raw->preproc.module = &yasm_raw_LTX_preproc;
     preproc_raw->in = f;
     preproc_raw->cur_lm = lm;
-    preproc_raw->errwarns = errwarns;
     /*@-unrecog@*/
     preproc_raw->is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
     /*@=unrecog@*/
@@ -80,17 +77,13 @@
 	    buf[n] = (char)c;
 	if (c == '\n')
 	    buf[n++] = (char)c;
-	if (c == EOF && ferror(preproc_raw->in)) {
-	    yasm_error_set(YASM_ERROR_IO, N_("error when reading from file"));
-	    yasm_errwarn_propagate(preproc_raw->errwarns,
-				   yasm_linemap_get_current(preproc_raw->cur_lm));
-	}
+	if (c == EOF && ferror(preproc_raw->in))
+	    yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm),
+			N_("error when reading from file"));
     } else if (((n = fread(buf, 1, max_size, preproc_raw->in)) == 0) &&
-	       ferror(preproc_raw->in)) {
-	yasm_error_set(YASM_ERROR_IO, N_("error when reading from file"));
-	yasm_errwarn_propagate(preproc_raw->errwarns,
-			       yasm_linemap_get_current(preproc_raw->cur_lm));
-    }
+	       ferror(preproc_raw->in))
+	yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm),
+		    N_("error when reading from file"));
 
     return n;
 }
diff --git a/tools/Makefile.inc b/tools/Makefile.inc
index 56a4697..264b8e1 100644
--- a/tools/Makefile.inc
+++ b/tools/Makefile.inc
@@ -2,8 +2,6 @@
 
 EXTRA_DIST += tools/re2c/Makefile.inc
 EXTRA_DIST += tools/gap/Makefile.inc
-EXTRA_DIST += tools/python-yasm/Makefile.inc
 
 include tools/re2c/Makefile.inc
 include tools/gap/Makefile.inc
-include tools/python-yasm/Makefile.inc
diff --git a/tools/python-yasm/Makefile.inc b/tools/python-yasm/Makefile.inc
deleted file mode 100644
index 43bca45..0000000
--- a/tools/python-yasm/Makefile.inc
+++ /dev/null
@@ -1,55 +0,0 @@
-# $Id$
-
-PYBINDING_DEPS  = tools/python-yasm/bytecode.pxi
-PYBINDING_DEPS += tools/python-yasm/coretype.pxi
-PYBINDING_DEPS += tools/python-yasm/errwarn.pxi
-PYBINDING_DEPS += tools/python-yasm/expr.pxi
-PYBINDING_DEPS += tools/python-yasm/floatnum.pxi
-PYBINDING_DEPS += tools/python-yasm/intnum.pxi
-PYBINDING_DEPS += tools/python-yasm/symrec.pxi
-PYBINDING_DEPS += tools/python-yasm/value.pxi
-
-EXTRA_DIST += tools/python-yasm/setup.py
-EXTRA_DIST += tools/python-yasm/yasm.pyx
-EXTRA_DIST += $(PYBINDING_DEPS)
-
-if HAVE_PYTHON
-
-yasm_python.c: $(srcdir)/tools/python-yasm/yasm.pyx $(PYBINDING_DEPS)
-	$(PYTHON) -c "from Pyrex.Compiler.Main import main; main(command_line=1)" \
-		-o $@ `test -f tools/python-yasm/yasm.pyx || echo '$(srcdir)/'`tools/python-yasm/yasm.pyx
-
-CLEANFILES += yasm_python.c
-
-# Now the Python build magic...
-python-setup.txt: Makefile
-	echo "includes=${DEFAULT_INCLUDES} ${INCLUDES} ${DEFS}" > python-setup.txt
-	echo "sources=${libyasm_a_SOURCES}" >> python-setup.txt
-	echo "srcdir=${srcdir}" >> python-setup.txt
-	echo "gcc=${GCC}" >> python-setup.txt
-
-CLEANFILES += python-setup.txt
-
-.python-build: python-setup.txt yasm_python.c ${libyasm_a_SOURCES}
-	$(PYTHON) `test -f tools/python-yasm/setup.py || echo '$(srcdir)/'`tools/python-yasm/setup.py build
-	touch .python-build
-python-build: .python-build
-
-CLEANFILES += .python-build
-
-python-install: .python-build
-	$(PYTHON) `test -f tools/python-yasm/setup.py || echo '$(srcdir)/'`tools/python-yasm/setup.py install "--install-lib=$(pythondir)"
-
-python-uninstall:
-	rm -f `$(PYTHON) -c "import sys;sys.path.insert(0, '${pythondir}'); import yasm; print yasm.__file__"`
-
-else
-
-python-build:
-python-install:
-python-uninstall:
-
-endif
-
-EXTRA_DIST += tools/python-yasm/tests/Makefile.inc
-include tools/python-yasm/tests/Makefile.inc
diff --git a/tools/python-yasm/bytecode.pxi b/tools/python-yasm/bytecode.pxi
deleted file mode 100644
index 1c3e5ab..0000000
--- a/tools/python-yasm/bytecode.pxi
+++ /dev/null
@@ -1,191 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for bytecode.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/bytecode.h":
-    cdef struct yasm_effaddr
-
-    cdef struct yasm_effaddr_callback:
-        void (*destroy) (yasm_effaddr *ea)
-        void (*print_ "print") (yasm_effaddr *ea, FILE *f, int indent_level)
-
-    cdef struct yasm_effaddr:
-        yasm_effaddr_callback *callback
-        yasm_value disp
-        unsigned long segreg
-        unsigned int disp_len
-        unsigned int need_disp
-        unsigned int nosplit
-        unsigned int strong
-
-    cdef struct yasm_immval:
-        yasm_value val
-        unsigned int len
-        unsigned int sign
-
-    cdef struct yasm_dataval
-    cdef struct yasm_datavalhead
-
-    cdef enum yasm_bc_resolve_flags:
-        YASM_BC_RESOLVE_NONE
-        YASM_BC_RESOLVE_ERROR
-        YASM_BC_RESOLVE_MIN_LEN
-        YASM_BC_RESOLVE_UNKNOWN_LEN
-
-    cdef yasm_immval* yasm_imm_create_expr(yasm_expr *e)
-    cdef yasm_expr* yasm_ea_get_disp(yasm_effaddr *ea)
-    cdef void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len)
-    cdef void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit)
-    cdef void yasm_ea_set_strong(yasm_effaddr *ea, unsigned int strong)
-    cdef void yasm_ea_set_segreg(yasm_effaddr *ea, unsigned long segreg)
-    cdef void yasm_ea_destroy(yasm_effaddr *ea)
-    cdef void yasm_ea_print(yasm_effaddr *ea, FILE *f, int indent_level)
-
-    cdef void yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
-    cdef yasm_bytecode* yasm_bc_create_data(yasm_datavalhead *datahead,
-            unsigned int size, int append_zero, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_leb128(yasm_datavalhead *datahead,
-            int sign, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_reserve(yasm_expr *numitems,
-            unsigned int itemsize, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_incbin(char *filename,
-            yasm_expr *start, yasm_expr *maxlen, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_align(yasm_expr *boundary,
-            yasm_expr *fill, yasm_expr *maxskip,
-            unsigned char **code_fill, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_org(unsigned long start,
-            unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_insn(yasm_arch *arch,
-            unsigned long insn_data[4], int num_operands,
-            yasm_insn_operands *operands, unsigned long line)
-    cdef yasm_bytecode* yasm_bc_create_empty_insn(yasm_arch *arch,
-            unsigned long insn_data[4], int num_operands,
-            yasm_insn_operands *operands, unsigned long line)
-    cdef void yasm_bc_insn_add_prefix(yasm_bytecode *bc,
-            unsigned long prefix_data[4])
-    cdef void yasm_bc_insn_add_seg_prefix(yasm_bytecode *bc,
-            unsigned long segreg)
-    cdef yasm_section* yasm_bc_get_section(yasm_bytecode *bc)
-    cdef void yasm_bc__add_symrec(yasm_bytecode *bc, yasm_symrec *sym)
-    cdef void yasm_bc_destroy(yasm_bytecode *bc)
-    cdef void yasm_bc_print(yasm_bytecode *bc, FILE *f, int indent_level)
-    cdef void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-    cdef yasm_intnum *yasm_common_calc_bc_dist(yasm_bytecode *precbc1,
-            yasm_bytecode *precbc2)
-    cdef yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
-            yasm_calc_bc_dist_func calc_bc_dist)
-    cdef unsigned char* yasm_bc_tobytes(yasm_bytecode *bc,
-            unsigned char *buf, unsigned long *bufsize, int *gap, void *d,
-            yasm_output_value_func output_value,
-            yasm_output_reloc_func output_reloc)
-    cdef int yasm_bc_get_multiple(yasm_bytecode *bc, unsigned long *multiple,
-                                  yasm_calc_bc_dist_func calc_bc_dist)
-
-    cdef yasm_dataval* yasm_dv_create_expr(yasm_expr *expn)
-    cdef yasm_dataval* yasm_dv_create_string(char *contents, size_t len)
-
-    cdef void yasm_dvs_initialize(yasm_datavalhead *headp)
-    cdef void yasm_dvs_destroy(yasm_datavalhead *headp)
-    cdef yasm_dataval* yasm_dvs_append(yasm_datavalhead *headp,
-            yasm_dataval *dv)
-    cdef void yasm_dvs_print(yasm_datavalhead *headp, FILE *f,
-            int indent_level)
-
-cdef extern from "libyasm/bc-int.h":
-    cdef struct yasm_bytecode_callback:
-        void (*destroy) (void *contents)
-        void (*c_print "print") (void *contents, FILE *f, int indent_level)
-        void (*finalize) (yasm_bytecode *bc, yasm_bytecode *prev_bc)
-        yasm_bc_resolve_flags (*resolve) (yasm_bytecode *bc, int save,
-                                          yasm_calc_bc_dist_func calc_bc_dist)
-        int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
-	                yasm_output_value_func output_value,
-		        yasm_output_reloc_func output_reloc)
-        int reserve
-
-    cdef struct yasm_bytecode:
-        yasm_bytecode_callback *callback
-        yasm_section *section
-        yasm_expr *multiple
-        unsigned long len
-        unsigned long line
-        unsigned long offset
-        unsigned long opt_flags
-        yasm_symrec **symrecs
-        void *contents
-
-    cdef yasm_bytecode *yasm_bc_create_common(yasm_bytecode_callback *callback,
-            void *contents, unsigned long line)
-
-    cdef void yasm_bc_transform(yasm_bytecode *bc,
-            yasm_bytecode_callback *callback, void *contents)
-
-    cdef void yasm_bc_finalize_common(yasm_bytecode *bc, yasm_bytecode *prev_bc)
-
-    cdef yasm_bytecode *yasm_bc__next(yasm_bytecode *bc)
-
-cdef object __make_immval(yasm_immval *imm):
-    return ImmVal(__pass_voidp(imm, ImmVal))
-
-cdef class ImmVal:
-    cdef yasm_immval *imm
-
-    def __new__(self, value):
-        if isinstance(value, Expression):
-            self.imm = yasm_imm_create_expr(
-                    yasm_expr_copy((<Expression>value).expr))
-        elif PyCObject_Check(value):
-            self.imm = <yasm_immval *>__get_voidp(value, ImmVal)
-        else:
-            raise TypeError
-
-cdef class Bytecode:
-    cdef yasm_bytecode *bc
-
-    property len:
-        def __get__(self): return self.bc.len
-        def __set__(self, value): self.bc.len = value
-    property line:
-        def __get__(self): return self.bc.line
-        def __set__(self, value): self.bc.line = value
-    property offset:
-        def __get__(self): return self.bc.offset
-        def __set__(self, value): self.bc.offset = value
-    property opt_flags:
-        def __get__(self): return self.bc.opt_flags
-        def __set__(self, value): self.bc.opt_flags = value
-    property symbols:
-        # Someday extend this to do something modifiable, e.g. return a
-        # list-like object.
-        def __get__(self):
-            cdef yasm_symrec *sym
-            cdef int i
-            s = []
-            i = 0
-            sym = self.bc.symrecs[i]
-            while sym != NULL:
-                s.append(__make_symbol(sym))
-                i = i+1
-                sym = self.bc.symrecs[i]
-            return s
diff --git a/tools/python-yasm/coretype.pxi b/tools/python-yasm/coretype.pxi
deleted file mode 100644
index c0aabca..0000000
--- a/tools/python-yasm/coretype.pxi
+++ /dev/null
@@ -1,124 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for coretype.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern struct FILE:
-    int fileno
-
-ctypedef unsigned long size_t
-
-cdef extern struct va_list:
-    int arglist
-
-cdef extern from "libyasm/coretype.h":
-    cdef struct yasm_arch
-    cdef struct yasm_preproc
-    cdef struct yasm_parser
-    cdef struct yasm_optimizer
-    cdef struct yasm_objfmt
-    cdef struct yasm_dbgfmt
-    cdef struct yasm_listfmt
-
-    cdef struct yasm_assoc_data_callback:
-        void (*destroy) (void *data)
-        void (*print_ "print") (void *data, FILE *f, int indent_level)
-
-    cdef struct yasm_errwarns
-
-    cdef struct yasm_bytecode
-    cdef struct yasm_object
-    cdef struct yasm_section
-    cdef struct yasm_symtab
-    cdef struct yasm_symrec
-    cdef struct yasm_expr
-    cdef struct yasm_intnum
-    cdef struct yasm_floatnum
-
-    cdef struct yasm_value:
-        yasm_expr *abs
-        yasm_symrec *rel
-        yasm_symrec *wrt
-        unsigned int seg_of
-        unsigned int rshift
-        unsigned int curpos_rel
-        unsigned int ip_rel
-        unsigned int section_rel
-        unsigned int size
-
-    cdef struct yasm_linemap
-    cdef struct yasm_valparam
-    cdef struct yasm_valparamhead
-    cdef struct yasm_insn_operands
-
-    ctypedef enum yasm_expr_op:
-        YASM_EXPR_IDENT
-        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_XNOR
-        YASM_EXPR_NOR
-        YASM_EXPR_SHL
-        YASM_EXPR_SHR
-        YASM_EXPR_LOR
-        YASM_EXPR_LAND
-        YASM_EXPR_LNOT
-        YASM_EXPR_LXOR
-        YASM_EXPR_LXNOR
-        YASM_EXPR_LNOR
-        YASM_EXPR_LT
-        YASM_EXPR_GT
-        YASM_EXPR_EQ
-        YASM_EXPR_LE
-        YASM_EXPR_GE
-        YASM_EXPR_NE
-        YASM_EXPR_NONNUM
-        YASM_EXPR_SEG
-        YASM_EXPR_WRT
-        YASM_EXPR_SEGOFF
-
-    ctypedef enum yasm_sym_vis:
-        YASM_SYM_LOCAL
-        YASM_SYM_GLOBAL
-        YASM_SYM_COMMON
-        YASM_SYM_EXTERN
-        YASM_SYM_DLOCAL
-
-    ctypedef yasm_intnum*(*yasm_calc_bc_dist_func)(yasm_bytecode *precbc1,
-            yasm_bytecode *precbc2)
-    ctypedef int*(*yasm_output_value_func)(yasm_value *value, unsigned char
-            *buf, size_t destsize, unsigned long offset, yasm_bytecode *bc,
-            int warn, void *d)
-    ctypedef int(*yasm_output_reloc_func)(yasm_symrec *sym,
-            yasm_bytecode *bc, unsigned char *buf, size_t destsize,
-            size_t valsize, int warn, void *d)
-
diff --git a/tools/python-yasm/errwarn.pxi b/tools/python-yasm/errwarn.pxi
deleted file mode 100644
index 390391b..0000000
--- a/tools/python-yasm/errwarn.pxi
+++ /dev/null
@@ -1,144 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for errwarn.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/errwarn.h":
-    ctypedef enum yasm_warn_class:
-        YASM_WARN_NONE
-        YASM_WARN_GENERAL
-        YASM_WARN_UNREC_CHAR
-        YASM_WARN_PREPROC
-        YASM_WARN_ORPHAN_LABEL
-        YASM_WARN_UNINIT_CONTENTS
-
-    ctypedef enum yasm_error_class:
-        YASM_ERROR_NONE
-        YASM_ERROR_GENERAL
-        YASM_ERROR_ARITHMETIC
-        YASM_ERROR_OVERFLOW
-        YASM_ERROR_FLOATING_POINT
-        YASM_ERROR_ZERO_DIVISION
-        YASM_ERROR_ASSERTION
-        YASM_ERROR_VALUE
-        YASM_ERROR_NOT_ABSOLUTE
-        YASM_ERROR_TOO_COMPLEX
-        YASM_ERROR_NOT_CONSTANT
-        YASM_ERROR_IO
-        YASM_ERROR_NOT_IMPLEMENTED
-        YASM_ERROR_TYPE
-        YASM_ERROR_SYNTAX
-        YASM_ERROR_PARSE
-
-    void yasm_errwarn_initialize()
-    void yasm_errwarn_cleanup()
-    extern void (*yasm_internal_error_) (char *file, unsigned int line,
-                                         char *message)
-    void yasm_internal_error(char *message)
-    extern void (*yasm_fatal) (char *message, va_list va)
-    void yasm__fatal(char *message, ...)
-
-    void yasm_error_clear()
-    yasm_error_class yasm_error_occurred()
-    int yasm_error_matches(yasm_error_class eclass)
-
-    void yasm_error_set_va(yasm_error_class eclass, char *format, va_list va)
-    void yasm_error_set(yasm_error_class eclass, char *format, ...)
-    void yasm_error_set_xref_va(unsigned long xrefline, char *format,
-                                va_list va)
-    void yasm_error_set_xref(unsigned long xrefline, char *format, ...)
-    void yasm_error_fetch(yasm_error_class *eclass, char **str,
-                          unsigned long *xrefline, char **xrefstr)
-
-    void yasm_warn_clear()
-    void yasm_warn_set_va(yasm_warn_class wclass, char *format, va_list va)
-    void yasm_warn_set(yasm_warn_class wclass, char *format, ...)
-    void yasm_warn_fetch(yasm_warn_class *wclass, char **str)
-
-    void yasm_warn_enable(yasm_warn_class wclass)
-    void yasm_warn_disable(yasm_warn_class wclass)
-
-    void yasm_warn_disable_all()
-
-    yasm_errwarns *yasm_errwarns_create()
-    void yasm_errwarns_destroy(yasm_errwarns *errwarns)
-    void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line)
-    unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns,
-                                          int warning_as_error)
-
-    ctypedef void (*yasm_print_error_func) (char *fn, unsigned long line,
-                                            char *msg, unsigned long xrefline,
-                                            char *xrefmsg)
-    ctypedef void (*yasm_print_warning_func) (char *fn, unsigned long line,
-                                              char *msg)
-    void yasm_errwarns_output_all(yasm_errwarns *errwarns, yasm_linemap *lm,
-                                  int warning_as_error,
-                                  yasm_print_error_func print_error,
-                                  yasm_print_warning_func print_warning)
-
-    char *yasm__conv_unprint(int ch)
-
-    extern char * (*yasm_gettext_hook) (char *msgid)
-
-class YasmError(Exception): pass
-
-__errormap = [
-    # Order matters here. Go from most to least specific within a class
-    (YASM_ERROR_ZERO_DIVISION, ZeroDivisionError),
-    # Enable these once there are tests that need them.
-    #(YASM_ERROR_OVERFLOW, OverflowError),
-    #(YASM_ERROR_FLOATING_POINT, FloatingPointError),
-    #(YASM_ERROR_ARITHMETIC, ArithmeticError),
-    #(YASM_ERROR_ASSERTION, AssertionError),
-    #(YASM_ERROR_VALUE, ValueError), # include notabs, notconst, toocomplex
-    #(YASM_ERROR_IO, IOError),
-    #(YASM_ERROR_NOT_IMPLEMENTED, NotImplementedError),
-    #(YASM_ERROR_TYPE, TypeError),
-    #(YASM_ERROR_SYNTAX, SyntaxError), #include parse
-]
-
-cdef void __error_check() except *:
-    cdef yasm_error_class errclass
-    cdef unsigned long xrefline
-    cdef char *errstr, *xrefstr
-
-    # short path for the common case
-    if not yasm_error_occurred(): return
-
-    # look up our preferred python error, fall back to YasmError
-    for error_class, exception in __errormap:
-        if yasm_error_matches(error_class):
-            break
-    else:
-        exception = YasmError
-
-    # retrieve info (clears error)
-    yasm_error_fetch(&errclass, &errstr, &xrefline, &xrefstr)
-
-    if xrefline and xrefstr:
-        PyErr_Format(exception, "%s: %d: %s", errstr, xrefline, xrefstr)
-    else:
-        PyErr_SetString(exception, errstr)
-
-    if xrefstr: free(xrefstr)
-    free(errstr)
diff --git a/tools/python-yasm/expr.pxi b/tools/python-yasm/expr.pxi
deleted file mode 100644
index 64b132d..0000000
--- a/tools/python-yasm/expr.pxi
+++ /dev/null
@@ -1,205 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for expr.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/expr.h":
-    cdef struct yasm_expr__item
-
-    cdef yasm_expr *yasm_expr_create(yasm_expr_op op, yasm_expr__item *a,
-            yasm_expr__item *b, unsigned long line)
-    cdef yasm_expr__item *yasm_expr_sym(yasm_symrec *sym)
-    cdef yasm_expr__item *yasm_expr_expr(yasm_expr *e)
-    cdef yasm_expr__item *yasm_expr_int(yasm_intnum *intn)
-    cdef yasm_expr__item *yasm_expr_float(yasm_floatnum *flt)
-    cdef yasm_expr__item *yasm_expr_reg(unsigned long reg)
-    cdef yasm_expr *yasm_expr_create_tree(yasm_expr *l, yasm_expr_op op,
-            yasm_expr *r, unsigned long line)
-    cdef yasm_expr *yasm_expr_create_branch(yasm_expr_op op,
-            yasm_expr *r, unsigned long line)
-    cdef yasm_expr *yasm_expr_create_ident(yasm_expr *r, unsigned long line)
-    cdef yasm_expr *yasm_expr_copy(yasm_expr *e)
-    cdef void yasm_expr_destroy(yasm_expr *e)
-    cdef int yasm_expr_is_op(yasm_expr *e, yasm_expr_op op)
-    ctypedef yasm_expr * (*yasm_expr_xform_func) (yasm_expr *e, void *d)
-
-    cdef struct yasm__exprhead
-    cdef yasm_expr *yasm_expr__level_tree(yasm_expr *e, int fold_const,
-            int simplify_ident, int simplify_reg_mul,
-            yasm_calc_bc_dist_func calc_bc_dist,
-            yasm_expr_xform_func expr_xform_extra,
-            void *expr_xform_extra_data, yasm__exprhead *eh, int *error)
-    cdef yasm_expr *yasm_expr_simplify(yasm_expr *e, yasm_calc_bc_dist_func cbd)
-    cdef yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep)
-    cdef yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep)
-    cdef yasm_intnum *yasm_expr_get_intnum(yasm_expr **ep,
-            yasm_calc_bc_dist_func calc_bc_dist)
-    cdef yasm_symrec *yasm_expr_get_symrec(yasm_expr **ep, int simplify)
-    cdef unsigned long *yasm_expr_get_reg(yasm_expr **ep, int simplify)
-    cdef void yasm_expr_print(yasm_expr *e, FILE *f)
-
-cdef extern from "libyasm/expr-int.h":
-    cdef enum yasm_expr__type:
-        YASM_EXPR_NONE
-        YASM_EXPR_REG
-        YASM_EXPR_INT
-        YASM_EXPR_FLOAT
-        YASM_EXPR_SYM
-        YASM_EXPR_SYMEXP
-        YASM_EXPR_EXPR
-
-    cdef union yasm_expr__type_data:
-        yasm_symrec *sym
-        yasm_expr *expn
-        yasm_intnum *intn
-        yasm_floatnum *flt
-        unsigned long reg
-
-    cdef struct yasm_expr__item:
-        yasm_expr__type type
-        yasm_expr__type_data data
-
-    cdef struct yasm_expr:
-        yasm_expr_op op
-        unsigned long line
-        int numterms
-        yasm_expr__item terms[2]
-
-    cdef int yasm_expr__traverse_leaves_in_const(yasm_expr *e,
-            void *d, int (*func) (yasm_expr__item *ei, void *d))
-    cdef int yasm_expr__traverse_leaves_in(yasm_expr *e, void *d,
-            int (*func) (yasm_expr__item *ei, void *d))
-
-    cdef void yasm_expr__order_terms(yasm_expr *e)
-
-    cdef yasm_expr *yasm_expr__copy_except(yasm_expr *e, int excpt)
-
-    cdef int yasm_expr__contains(yasm_expr *e, yasm_expr__type t)
-
-import operator
-__op = {}
-for ops, operation in [
-    ((operator.__add__, operator.add, '+'), YASM_EXPR_ADD),
-    ((operator.__and__, operator.and_, '&'), YASM_EXPR_AND),
-    ((operator.__div__, operator.div, '/'), YASM_EXPR_SIGNDIV),
-    ((operator.__floordiv__, operator.floordiv, '//'), YASM_EXPR_SIGNDIV),
-    ((operator.__ge__, operator.ge, '>='), YASM_EXPR_GE),
-    ((operator.__gt__, operator.gt, '>'), YASM_EXPR_GT),
-    ((operator.__inv__, operator.inv, '~'), YASM_EXPR_NOT),
-    ((operator.__invert__, operator.invert), YASM_EXPR_NOT),
-    ((operator.__le__, operator.le, '<='), YASM_EXPR_LE),
-    ((operator.__lt__, operator.lt, '<'), YASM_EXPR_LT),
-    ((operator.__mod__, operator.mod, '%'), YASM_EXPR_SIGNMOD),
-    ((operator.__mul__, operator.mul, '*'), YASM_EXPR_MUL),
-    ((operator.__neg__, operator.neg), YASM_EXPR_NEG),
-    ((operator.__not__, operator.not_, 'not'), YASM_EXPR_LNOT),
-    ((operator.__or__, operator.or_, '|'), YASM_EXPR_OR),
-    ((operator.__sub__, operator.sub, '-'), YASM_EXPR_SUB),
-    ((operator.__xor__, operator.xor, '^'), YASM_EXPR_XOR),
-    ]:
-    for op in ops:
-        __op[op] = operation
-
-del operator, op, ops, operation
-
-cdef object __make_expression(yasm_expr *expr):
-    return Expression(__pass_voidp(expr, Expression))
-
-cdef class Expression:
-    cdef yasm_expr *expr
-
-    def __new__(self, op, *args, **kwargs):
-        self.expr = NULL
-
-        if isinstance(op, Expression):
-            self.expr = yasm_expr_copy((<Expression>op).expr)
-            return
-        if PyCObject_Check(op):
-            self.expr = <yasm_expr *>__get_voidp(op, Expression)
-            return
-
-        cdef size_t numargs
-        cdef unsigned long line
-
-        op = __op.get(op, op)
-        numargs = len(args)
-        line = kwargs.get('line', 0)
-
-        if numargs == 0 or numargs > 2:
-            raise NotImplementedError
-        elif numargs == 2:
-            self.expr = yasm_expr_create(op, self.__new_item(args[0]),
-                                         self.__new_item(args[1]), line)
-        else:
-            self.expr = yasm_expr_create(op, self.__new_item(args[0]), NULL,
-                                         line)
-
-    cdef yasm_expr__item* __new_item(self, value) except NULL:
-        cdef yasm_expr__item *retval
-        if isinstance(value, Expression):
-            return yasm_expr_expr(yasm_expr_copy((<Expression>value).expr))
-        #elif isinstance(value, Symbol):
-        #    return yasm_expr_sym((<Symbol>value).sym)
-        #elif isinstance(value, Register):
-        #    return yasm_expr_reg((<Register>value).reg)
-        elif isinstance(value, FloatNum):
-            return yasm_expr_float(yasm_floatnum_copy((<FloatNum>value).flt))
-        elif isinstance(value, IntNum):
-            return yasm_expr_int(yasm_intnum_copy((<IntNum>value).intn))
-        else:
-            try:
-                intnum = IntNum(value)
-            except:
-                raise ValueError("Invalid item value type '%s'" % type(value))
-            else:
-                retval = yasm_expr_int((<IntNum>intnum).intn)
-                (<IntNum>intnum).intn = NULL
-                return retval
-
-    def __dealloc__(self):
-        if self.expr != NULL: yasm_expr_destroy(self.expr)
-
-    def simplify(self):
-        self.expr = yasm_expr_simplify(self.expr, NULL) # TODO: cbd
-
-    def extract_segoff(self):
-        cdef yasm_expr *retval
-        retval = yasm_expr_extract_segoff(&self.expr)
-        if retval == NULL:
-            raise ValueError("not a SEG:OFF expression")
-        return __make_expression(retval)
-
-    def extract_wrt(self):
-        cdef yasm_expr *retval
-        retval = yasm_expr_extract_wrt(&self.expr)
-        if retval == NULL:
-            raise ValueError("not a WRT expression")
-        return __make_expression(retval)
-
-    def get_intnum(self):
-        cdef yasm_intnum *retval
-        retval = yasm_expr_get_intnum(&self.expr, NULL) # TODO: cbd
-        if retval == NULL:
-            raise ValueError("not an intnum expression")
-        return __make_intnum(yasm_intnum_copy(retval))
-
diff --git a/tools/python-yasm/floatnum.pxi b/tools/python-yasm/floatnum.pxi
deleted file mode 100644
index 7e76198..0000000
--- a/tools/python-yasm/floatnum.pxi
+++ /dev/null
@@ -1,64 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for floatnum.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/floatnum.h":
-    cdef void yasm_floatnum_initialize()
-    cdef void yasm_floatnum_cleanup()
-    cdef yasm_floatnum* yasm_floatnum_create(char *str)
-    cdef yasm_floatnum* yasm_floatnum_copy(yasm_floatnum *flt)
-    cdef void yasm_floatnum_destroy(yasm_floatnum *flt)
-    cdef void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
-            yasm_floatnum *operand)
-    cdef int yasm_floatnum_get_int(yasm_floatnum *flt, size_t *ret_val)
-    cdef int yasm_floatnum_get_sized(yasm_floatnum *flt, unsigned char *ptr,
-            size_t destsize, size_t valsize, size_t shift, int
-            bigendian, int warn)
-    cdef int yasm_floatnum_check_size(yasm_floatnum *flt, size_t size)
-    cdef void yasm_floatnum_print(yasm_floatnum *flt, FILE *f)
-
-cdef class FloatNum:
-    cdef yasm_floatnum *flt
-    def __new__(self, value):
-        self.flt = NULL
-        if isinstance(value, FloatNum):
-            self.flt = yasm_floatnum_copy((<FloatNum>value).flt)
-            return
-        if PyCObject_Check(value):  # should check Desc
-            self.flt = <yasm_floatnum *>PyCObject_AsVoidPtr(value)
-            return
-
-        if isinstance(value, float): string = str(float)
-        else: string = value
-        self.flt = yasm_floatnum_create(string)
-
-    def __dealloc__(self):
-        if self.flt != NULL: yasm_floatnum_destroy(self.flt)
-
-    def __neg__(self):
-        result = FloatNum(self)
-        yasm_floatnum_calc((<FloatNum>result).flt, YASM_EXPR_NEG, NULL)
-        return result
-    def __pos__(self): return self
-
diff --git a/tools/python-yasm/intnum.pxi b/tools/python-yasm/intnum.pxi
deleted file mode 100644
index 42db35e..0000000
--- a/tools/python-yasm/intnum.pxi
+++ /dev/null
@@ -1,203 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for intnum.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/intnum.h":
-    cdef void yasm_intnum_initialize()
-    cdef void yasm_intnum_cleanup()
-    cdef yasm_intnum *yasm_intnum_create_dec(char *str)
-    cdef yasm_intnum *yasm_intnum_create_bin(char *str)
-    cdef yasm_intnum *yasm_intnum_create_oct(char *str)
-    cdef yasm_intnum *yasm_intnum_create_hex(char *str)
-    cdef yasm_intnum *yasm_intnum_create_charconst_nasm(char *str)
-    cdef yasm_intnum *yasm_intnum_create_uint(unsigned long i)
-    cdef yasm_intnum *yasm_intnum_create_int(long i)
-    cdef yasm_intnum *yasm_intnum_create_leb128(unsigned char *ptr,
-            int sign, unsigned long *size)
-    cdef yasm_intnum *yasm_intnum_create_sized(unsigned char *ptr, int sign,
-            size_t srcsize, int bigendian)
-    cdef yasm_intnum *yasm_intnum_copy(yasm_intnum *intn)
-    cdef void yasm_intnum_destroy(yasm_intnum *intn)
-    cdef void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op,
-            yasm_intnum *operand)
-    cdef void yasm_intnum_zero(yasm_intnum *intn)
-    cdef void yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val)
-    cdef int yasm_intnum_is_zero(yasm_intnum *acc)
-    cdef int yasm_intnum_is_pos1(yasm_intnum *acc)
-    cdef int yasm_intnum_is_neg1(yasm_intnum *acc)
-    cdef int yasm_intnum_sign(yasm_intnum *acc)
-    cdef unsigned long yasm_intnum_get_uint(yasm_intnum *intn)
-    cdef long yasm_intnum_get_int(yasm_intnum *intn)
-    cdef void yasm_intnum_get_sized(yasm_intnum *intn, unsigned char *ptr,
-	    size_t destsize, size_t valsize, int shift, int bigendian, int warn)
-    cdef int yasm_intnum_check_size(yasm_intnum *intn, size_t size,
-            size_t rshift, int rangetype)
-    cdef unsigned long yasm_intnum_get_leb128(yasm_intnum *intn,
-            unsigned char *ptr, int sign)
-    cdef unsigned long yasm_intnum_size_leb128(yasm_intnum *intn,
-            int sign)
-    cdef unsigned long yasm_get_sleb128(long v, unsigned char *ptr)
-    cdef unsigned long yasm_size_sleb128(long v)
-    cdef unsigned long yasm_get_uleb128(unsigned long v, unsigned char *ptr)
-    cdef unsigned long yasm_size_uleb128(unsigned long v)
-    cdef void yasm_intnum_print(yasm_intnum *intn, FILE *f)
-
-cdef class IntNum
-
-cdef object __intnum_op_ex(object x, yasm_expr_op op, object y):
-    value = __intnum_op(x, op, y)
-    __error_check()
-    return value
-
-cdef object __intnum_op(object x, yasm_expr_op op, object y):
-    if isinstance(x, IntNum):
-        result = IntNum(x)
-        if y is None:
-            yasm_intnum_calc((<IntNum>result).intn, op, NULL)
-        else:
-            # Coerce to intnum if not already
-            if isinstance(y, IntNum):
-                rhs = y
-            else:
-                rhs = IntNum(y)
-            yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>rhs).intn)
-        return result
-    elif isinstance(y, IntNum):
-        # Reversed operation - x OP y still, just y is intnum, x isn't.
-        result = IntNum(x)
-        yasm_intnum_calc((<IntNum>result).intn, op, (<IntNum>y).intn)
-        return result
-    else:
-        raise NotImplementedError
-
-cdef object __make_intnum(yasm_intnum *intn):
-    return IntNum(__pass_voidp(intn, IntNum))
-
-cdef class IntNum:
-    cdef yasm_intnum *intn
-
-    def __new__(self, value, base=None):
-        cdef unsigned char buf[16]
-
-        self.intn = NULL
-
-        if isinstance(value, IntNum):
-            self.intn = yasm_intnum_copy((<IntNum>value).intn)
-            return
-        if PyCObject_Check(value):
-            self.intn = <yasm_intnum *>__get_voidp(value, IntNum)
-            return
-
-        val = None
-        if isinstance(value, str):
-            val = long(value, base)
-        elif isinstance(value, (int, long)):
-            val = long(value)
-
-        if val is None:
-            raise ValueError
-
-        _PyLong_AsByteArray(val, buf, 16, 1, 1)
-        self.intn = yasm_intnum_create_sized(buf, 1, 16, 0)
-
-    def __dealloc__(self):
-        if self.intn != NULL: yasm_intnum_destroy(self.intn)
-
-    def __long__(self):
-        cdef unsigned char buf[16]
-        yasm_intnum_get_sized(self.intn, buf, 16, 128, 0, 0, 0)
-        return _PyLong_FromByteArray(buf, 16, 1, 1)
-
-    def __repr__(self):
-        return "IntNum(%d)" % self
-
-    def __int__(self): return int(self.__long__())
-    def __complex__(self): return complex(self.__long__())
-    def __float__(self): return float(self.__long__())
-
-    def __oct__(self): return oct(int(self.__long__()))
-    def __hex__(self): return hex(int(self.__long__()))
-
-    def __add__(x, y): return __intnum_op(x, YASM_EXPR_ADD, y)
-    def __sub__(x, y): return __intnum_op(x, YASM_EXPR_SUB, y)
-    def __mul__(x, y): return __intnum_op(x, YASM_EXPR_MUL, y)
-    def __div__(x, y): return __intnum_op_ex(x, YASM_EXPR_SIGNDIV, y)
-    def __floordiv__(x, y): return __intnum_op_ex(x, YASM_EXPR_SIGNDIV, y)
-    def __mod__(x, y): return __intnum_op_ex(x, YASM_EXPR_SIGNMOD, y)
-    def __neg__(self): return __intnum_op(self, YASM_EXPR_NEG, None)
-    def __pos__(self): return self
-    def __abs__(self):
-        if yasm_intnum_sign(self.intn) >= 0: return self
-        else: return __intnum_op(self, YASM_EXPR_NEG, None)
-    def __nonzero__(self): return not yasm_intnum_is_zero(self.intn)
-    def __invert__(self): return __intnum_op(self, YASM_EXPR_NOT, None)
-    def __lshift__(x, y): return __intnum_op(x, YASM_EXPR_SHL, y)
-    def __rshift__(x, y): return __intnum_op(x, YASM_EXPR_SHR, y)
-    def __and__(x, y): return __intnum_op(x, YASM_EXPR_AND, y)
-    def __or__(x, y): return __intnum_op(x, YASM_EXPR_OR, y)
-    def __xor__(x, y): return __intnum_op(x, YASM_EXPR_XOR, y)
-
-    cdef object __op(self, yasm_expr_op op, object x):
-        if isinstance(x, IntNum):
-            rhs = x
-        else:
-            rhs = IntNum(x)
-        yasm_intnum_calc(self.intn, op, (<IntNum>rhs).intn)
-        return self
-
-    def __iadd__(self, x): return self.__op(YASM_EXPR_ADD, x)
-    def __isub__(self, x): return self.__op(YASM_EXPR_SUB, x)
-    def __imul__(self, x): return self.__op(YASM_EXPR_MUL, x)
-    def __idiv__(self, x): return self.__op(YASM_EXPR_SIGNDIV, x)
-    def __ifloordiv__(self, x): return self.__op(YASM_EXPR_SIGNDIV, x)
-    def __imod__(self, x): return self.__op(YASM_EXPR_MOD, x)
-    def __ilshift__(self, x): return self.__op(YASM_EXPR_SHL, x)
-    def __irshift__(self, x): return self.__op(YASM_EXPR_SHR, x)
-    def __iand__(self, x): return self.__op(YASM_EXPR_AND, x)
-    def __ior__(self, x): return self.__op(YASM_EXPR_OR, x)
-    def __ixor__(self, x): return self.__op(YASM_EXPR_XOR, x)
-
-    def __cmp__(self, x):
-        cdef yasm_intnum *t
-        t = yasm_intnum_copy(self.intn)
-        if isinstance(x, IntNum):
-            rhs = x
-        else:
-            rhs = IntNum(x)
-        yasm_intnum_calc(t, YASM_EXPR_SUB, (<IntNum>rhs).intn)
-        result = yasm_intnum_sign(t)
-        yasm_intnum_destroy(t)
-        return result
-
-    def __richcmp__(x, y, op):
-        cdef yasm_expr_op aop
-        if op == 0: aop = YASM_EXPR_LT
-        elif op == 1: aop = YASM_EXPR_LE
-        elif op == 2: aop = YASM_EXPR_EQ
-        elif op == 3: aop = YASM_EXPR_NE
-        elif op == 4: aop = YASM_EXPR_GT
-        elif op == 5: aop = YASM_EXPR_GE
-        else: raise NotImplementedError
-        v = __intnum_op(x, aop, y)
-        return bool(not yasm_intnum_is_zero((<IntNum>v).intn))
diff --git a/tools/python-yasm/setup.py b/tools/python-yasm/setup.py
deleted file mode 100644
index ffc0e0c..0000000
--- a/tools/python-yasm/setup.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#! /usr/bin/env python
-# Build Python extension with configuration file input
-#
-#  Copyright (C) 2006  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.
-
-from distutils.core import setup
-from distutils.extension import Extension
-from Pyrex.Distutils import build_ext
-from os.path import basename, join, exists
-
-def ReadSetup(filename):
-    """ReadSetup goes through filename and parses out the values stored
-    in the file.  Values need to be stored in a
-    \"key=value format\""""
-    return dict(line.split('=', 1) for line in open(filename))
-
-def ParseCPPFlags(flags):
-    """parse the CPPFlags macro"""
-    incl_dir = [x[2:] for x in flags.split() if x.startswith("-I")]
-    cppflags = [x for x in flags.split() if not x.startswith("-I")]
-    return (incl_dir, cppflags)
-
-def ParseSources(src, srcdir):
-    """parse the Sources macro"""
-    # do the dance of detecting if the source file is in the current
-    # directory, and if it's not, prepend srcdir
-    sources = []
-    for tok in src.split():
-        if tok.endswith(".c"):
-            fn = tok
-        elif tok.endswith(".y"):
-            fn = basename(tok)[:-2] + ".c"
-        else:
-            continue
-        if not exists(fn):
-            fn = join(srcdir, fn)
-        sources.append(fn)
-
-    return sources
-
-def RunSetup(incldir, cppflags, sources):
-    setup(
-          name='yasm',
-          version='0.0',
-          description='Python bindings for Yasm',
-          author='Michael Urman, Peter Johnson',
-          url='http://www.tortall.net/projects/yasm',
-          ext_modules=[
-                       Extension('yasm',
-                                 sources=sources,
-                                 extra_compile_args=cppflags,
-                                 include_dirs=incldir,
-                                 library_dirs=['.'],
-                                 libraries=['yasm'],
-                       ),
-                      ],
-          cmdclass = dict(build_ext=build_ext),
-         )
-
-if __name__ == "__main__":
-    opts = ReadSetup("python-setup.txt")
-    incldir, cppflags = ParseCPPFlags(opts["includes"])
-    sources = ParseSources(opts["sources"], opts["srcdir"].strip())
-    sources.append('yasm_python.c')
-    if opts["gcc"].strip() == "yes":
-        cppflags.append('-w')
-    RunSetup(incldir, cppflags, sources)
-
diff --git a/tools/python-yasm/symrec.pxi b/tools/python-yasm/symrec.pxi
deleted file mode 100644
index 60f7a4d..0000000
--- a/tools/python-yasm/symrec.pxi
+++ /dev/null
@@ -1,324 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for symrec.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/symrec.h":
-    cdef yasm_symtab* yasm_symtab_create()
-    cdef void yasm_symtab_destroy(yasm_symtab *symtab)
-    cdef yasm_symrec* yasm_symtab_use(yasm_symtab *symtab, char *name,
-            unsigned long line)
-    cdef yasm_symrec* yasm_symtab_get(yasm_symtab *symtab, char *name)
-    cdef yasm_symrec* yasm_symtab_define_equ(yasm_symtab *symtab,
-            char *name, yasm_expr *e, unsigned long line)
-    cdef yasm_symrec* yasm_symtab_define_label(yasm_symtab *symtab,
-            char *name, yasm_bytecode *precbc, int in_table, unsigned long line)
-    cdef yasm_symrec* yasm_symtab_define_curpos(yasm_symtab *symtab, char *name,
-            yasm_bytecode *precbc, unsigned long line)
-    cdef yasm_symrec* yasm_symtab_define_special(yasm_symtab *symtab,
-            char *name, yasm_sym_vis vis)
-    cdef yasm_symrec* yasm_symtab_declare(yasm_symtab *symtab,
-            char *name, yasm_sym_vis vis, unsigned long line)
-    cdef void yasm_symrec_declare(yasm_symrec *symrec, yasm_sym_vis vis,
-            unsigned long line)
-
-    ctypedef int (*yasm_symtab_traverse_callback)(yasm_symrec *sym, void *d)
-    cdef int yasm_symtab_traverse(yasm_symtab *symtab, void *d,
-            yasm_symtab_traverse_callback func)
-
-    ctypedef struct yasm_symtab_iter
-    cdef yasm_symtab_iter *yasm_symtab_first(yasm_symtab *symtab)
-    cdef yasm_symtab_iter *yasm_symtab_next(yasm_symtab_iter *prev)
-    cdef yasm_symrec *yasm_symtab_iter_value(yasm_symtab_iter *cur)
-
-    cdef void yasm_symtab_parser_finalize(yasm_symtab *symtab,
-            int undef_extern, yasm_objfmt *objfmt)
-    cdef void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
-    cdef char* yasm_symrec_get_name(yasm_symrec *sym)
-    cdef yasm_sym_vis yasm_symrec_get_visibility(yasm_symrec *sym)
-    cdef yasm_expr* yasm_symrec_get_equ(yasm_symrec *sym)
-
-    ctypedef yasm_bytecode *yasm_symrec_get_label_bytecodep
-
-    cdef int yasm_symrec_get_label(yasm_symrec *sym,
-            yasm_symrec_get_label_bytecodep *precbc)
-    cdef int yasm_symrec_is_special(yasm_symrec *sym)
-    cdef int yasm_symrec_is_curpos(yasm_symrec *sym)
-    cdef void* yasm_symrec_get_data(yasm_symrec *sym,
-            yasm_assoc_data_callback *callback)
-    cdef void yasm_symrec_add_data(yasm_symrec *sym,
-            yasm_assoc_data_callback *callback, void *data)
-    cdef void yasm_symrec_print(yasm_symrec *sym, FILE *f, int indent_level)
-
-cdef class Symbol:
-    cdef yasm_symrec *sym
-
-    def __new__(self, symrec):
-        self.sym = NULL
-        if PyCObject_Check(symrec):
-            self.sym = <yasm_symrec *>__get_voidp(symrec, Symbol)
-        else:
-            raise NotImplementedError
-
-    # no deref or destroy necessary
-
-    property name:
-        def __get__(self): return yasm_symrec_get_name(self.sym)
-
-    property visibility:
-        def __get__(self):
-            cdef yasm_sym_vis vis
-            s = set()
-            vis = yasm_symrec_get_visibility(self.sym)
-            if vis & YASM_SYM_GLOBAL: s.add('global')
-            if vis & YASM_SYM_COMMON: s.add('common')
-            if vis & YASM_SYM_EXTERN: s.add('extern')
-            if vis & YASM_SYM_DLOCAL: s.add('dlocal')
-            return s
-
-    property equ:
-        def __get__(self):
-            cdef yasm_expr *e
-            e = yasm_symrec_get_equ(self.sym)
-            if not e:
-                raise AttributeError("not an EQU")
-            return __make_expression(yasm_expr_copy(e))
-
-    property label:
-        def __get__(self):
-            cdef yasm_symrec_get_label_bytecodep bc
-            if yasm_symrec_get_label(self.sym, &bc):
-                return None #Bytecode(bc)
-            else:
-                raise AttributeError("not a label or not defined")
-
-    property is_special:
-        def __get__(self): return bool(yasm_symrec_is_special(self.sym))
-
-    property is_curpos:
-        def __get__(self): return bool(yasm_symrec_is_curpos(self.sym))
-
-    def get_data(self): pass # TODO
-        #return <object>(yasm_symrec_get_data(self.sym, PyYasmAssocData))
-
-    def set_data(self, data): pass # TODO
-        #yasm_symrec_set_data(self.sym, PyYasmAssocData, data)
-
-#
-# Use associated data mechanism to keep Symbol reference paired with symrec.
-#
-
-cdef class __assoc_data_callback:
-    cdef yasm_assoc_data_callback *cb
-    def __new__(self, destroy, print_):
-        self.cb = <yasm_assoc_data_callback *>malloc(sizeof(yasm_assoc_data_callback))
-        self.cb.destroy = <void (*) (void *)>PyCObject_AsVoidPtr(destroy)
-        self.cb.print_ = <void (*) (void *, FILE *, int)>PyCObject_AsVoidPtr(print_)
-    def __dealloc__(self):
-        free(self.cb)
-
-cdef void __python_symrec_cb_destroy(void *data):
-    Py_DECREF(<object>data)
-cdef void __python_symrec_cb_print(void *data, FILE *f, int indent_level):
-    pass
-__python_symrec_cb = __assoc_data_callback(
-        PyCObject_FromVoidPtr(&__python_symrec_cb_destroy, NULL),
-        PyCObject_FromVoidPtr(&__python_symrec_cb_print, NULL))
-
-cdef object __make_symbol(yasm_symrec *symrec):
-    cdef void *data
-    __error_check()
-    data = yasm_symrec_get_data(symrec,
-                                (<__assoc_data_callback>__python_symrec_cb).cb)
-    if data != NULL:
-        return <object>data
-    symbol = Symbol(__pass_voidp(symrec, Symbol))
-    yasm_symrec_add_data(symrec,
-                         (<__assoc_data_callback>__python_symrec_cb).cb,
-                         <void *>symbol)
-    Py_INCREF(symbol)       # We're keeping a reference on the C side!
-    return symbol
-
-cdef class Bytecode
-cdef class SymbolTable
-
-cdef class SymbolTableKeyIterator:
-    cdef yasm_symtab_iter *iter
-
-    def __new__(self, symtab):
-        if not isinstance(symtab, SymbolTable):
-            raise TypeError
-        self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
-
-    def __iter__(self):
-        return self
-
-    def __next__(self):
-        if self.iter == NULL:
-            raise StopIteration
-        rv = yasm_symrec_get_name(yasm_symtab_iter_value(self.iter))
-        self.iter = yasm_symtab_next(self.iter)
-        return rv
-
-cdef class SymbolTableValueIterator:
-    cdef yasm_symtab_iter *iter
-
-    def __new__(self, symtab):
-        if not isinstance(symtab, SymbolTable):
-            raise TypeError
-        self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
-
-    def __iter__(self):
-        return self
-
-    def __next__(self):
-        if self.iter == NULL:
-            raise StopIteration
-        rv = __make_symbol(yasm_symtab_iter_value(self.iter))
-        self.iter = yasm_symtab_next(self.iter)
-        return rv
-
-cdef class SymbolTableItemIterator:
-    cdef yasm_symtab_iter *iter
-
-    def __new__(self, symtab):
-        if not isinstance(symtab, SymbolTable):
-            raise TypeError
-        self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
-
-    def __iter__(self):
-        return self
-
-    def __next__(self):
-        cdef yasm_symrec *sym
-        if self.iter == NULL:
-            raise StopIteration
-        sym = yasm_symtab_iter_value(self.iter)
-        rv = (yasm_symrec_get_name(sym), __make_symbol(sym))
-        self.iter = yasm_symtab_next(self.iter)
-        return rv
-
-cdef yasm_sym_vis __parse_vis(vis) except -1:
-    if not vis or vis == 'local': return YASM_SYM_LOCAL
-    if vis == 'global': return YASM_SYM_GLOBAL
-    if vis == 'common': return YASM_SYM_COMMON
-    if vis == 'extern': return YASM_SYM_EXTERN
-    if vis == 'dlocal': return YASM_SYM_DLOCAL
-    msg = "bad visibility value %r" % vis
-    PyErr_SetString(ValueError, msg)
-    return -1
-
-cdef class SymbolTable:
-    cdef yasm_symtab *symtab
-
-    def __new__(self):
-        self.symtab = yasm_symtab_create()
-
-    def __dealloc__(self):
-        if self.symtab != NULL: yasm_symtab_destroy(self.symtab)
-
-    def use(self, name, line):
-        return __make_symbol(yasm_symtab_use(self.symtab, name, line))
-
-    def define_equ(self, name, expr, line):
-        if not isinstance(expr, Expression):
-            raise TypeError
-        return __make_symbol(yasm_symtab_define_equ(self.symtab, name,
-                yasm_expr_copy((<Expression>expr).expr), line))
-
-    def define_label(self, name, precbc, in_table, line):
-        if not isinstance(precbc, Bytecode):
-            raise TypeError
-        return __make_symbol(yasm_symtab_define_label(self.symtab, name,
-                (<Bytecode>precbc).bc, in_table, line))
-
-    def define_special(self, name, vis):
-        return __make_symbol(yasm_symtab_define_special(self.symtab, name,
-                                                        __parse_vis(vis)))
-
-    def declare(self, name, vis, line):
-        return __make_symbol(yasm_symtab_declare(self.symtab, name,
-                                                 __parse_vis(vis), line))
-
-    #
-    # Methods to make SymbolTable behave like a dictionary of Symbols.
-    #
-
-    def __getitem__(self, key):
-        cdef yasm_symrec *symrec
-        symrec = yasm_symtab_get(self.symtab, key)
-        if symrec == NULL:
-            raise KeyError
-        return __make_symbol(symrec)
-
-    def __contains__(self, key):
-        cdef yasm_symrec *symrec
-        symrec = yasm_symtab_get(self.symtab, key)
-        return symrec != NULL
-
-    def keys(self):
-        cdef yasm_symtab_iter *iter
-        l = []
-        iter = yasm_symtab_first(self.symtab)
-        while iter != NULL:
-            l.append(yasm_symrec_get_name(yasm_symtab_iter_value(iter)))
-            iter = yasm_symtab_next(iter)
-        return l
-
-    def values(self):
-        cdef yasm_symtab_iter *iter
-        l = []
-        iter = yasm_symtab_first(self.symtab)
-        while iter != NULL:
-            l.append(__make_symbol(yasm_symtab_iter_value(iter)))
-            iter = yasm_symtab_next(iter)
-        return l
-
-    def items(self):
-        cdef yasm_symtab_iter *iter
-        cdef yasm_symrec *sym
-        l = []
-        iter = yasm_symtab_first(self.symtab)
-        while iter != NULL:
-            sym = yasm_symtab_iter_value(iter)
-            l.append((yasm_symrec_get_name(sym), __make_symbol(sym)))
-            iter = yasm_symtab_next(iter)
-        return l
-
-    def has_key(self, key):
-        cdef yasm_symrec *symrec
-        symrec = yasm_symtab_get(self.symtab, key)
-        return symrec != NULL
-
-    def get(self, key, x):
-        cdef yasm_symrec *symrec
-        symrec = yasm_symtab_get(self.symtab, key)
-        if symrec == NULL:
-            return x
-        return __make_symbol(symrec)
-
-    def iterkeys(self): return SymbolTableKeyIterator(self)
-    def itervalues(self): return SymbolTableValueIterator(self)
-    def iteritems(self): return SymbolTableItemIterator(self)
-    def __iter__(self): return SymbolTableKeyIterator(self)
-
diff --git a/tools/python-yasm/tests/Makefile.inc b/tools/python-yasm/tests/Makefile.inc
deleted file mode 100644
index 19181b9..0000000
--- a/tools/python-yasm/tests/Makefile.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-# $Id$
-
-EXTRA_DIST += tools/python-yasm/tests/python_test.sh
-EXTRA_DIST += tools/python-yasm/tests/__init__.py
-EXTRA_DIST += tools/python-yasm/tests/test_intnum.py
-EXTRA_DIST += tools/python-yasm/tests/test_symrec.py
-
-if HAVE_PYTHON
-
-TESTS_ENVIRONMENT += PYTHON=${PYTHON}
-TESTS += tools/python-yasm/tests/python_test.sh
-
-endif
diff --git a/tools/python-yasm/tests/__init__.py b/tools/python-yasm/tests/__init__.py
deleted file mode 100644
index 6d608f2..0000000
--- a/tools/python-yasm/tests/__init__.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Test wrapper from Quod Libet
-# http://www.sacredchao.net/quodlibet/
-# $Id$
-import unittest, sys
-suites = []
-add = registerCase = suites.append
-from unittest import TestCase
-
-class Mock(object):
-    # A generic mocking object.
-    def __init__(self, **kwargs): self.__dict__.update(kwargs)
-
-import test_intnum
-import test_symrec
-import test_bytecode
-import test_expr
-
-class Result(unittest.TestResult):
-
-    separator1 = '=' * 70
-    separator2 = '-' * 70
-
-    def addSuccess(self, test):
-        unittest.TestResult.addSuccess(self, test)
-        sys.stdout.write('.')
-
-    def addError(self, test, err):
-        unittest.TestResult.addError(self, test, err)
-        sys.stdout.write('E')
-
-    def addFailure(self, test, err):
-        unittest.TestResult.addFailure(self, test, err)
-        sys.stdout.write('F')
-
-    def printErrors(self):
-        succ = self.testsRun - (len(self.errors) + len(self.failures))
-        v = "%3d" % succ
-        count = 50 - self.testsRun
-        sys.stdout.write((" " * count) + v + "\n")
-        self.printErrorList('ERROR', self.errors)
-        self.printErrorList('FAIL', self.failures)
-
-    def printErrorList(self, flavour, errors):
-        for test, err in errors:
-            sys.stdout.write(self.separator1 + "\n")
-            sys.stdout.write("%s: %s\n" % (flavour, str(test)))
-            sys.stdout.write(self.separator2 + "\n")
-            sys.stdout.write("%s\n" % err)
-
-class Runner:
-    def run(self, test):
-        suite = unittest.makeSuite(test)
-        pref = '%s (%d): ' % (test.__name__, len(suite._tests))
-        print pref + " " * (25 - len(pref)),
-        result = Result()
-        suite(result)
-        result.printErrors()
-        return bool(result.failures + result.errors)
-
-def unit(run = []):
-    runner = Runner()
-    failures = False
-    for test in suites:
-        if not run or test.__name__ in run:
-            failures |= runner.run(test)
-    return failures
-
-if __name__ == "__main__":
-    raise SystemExit(unit(sys.argv[1:]))
-
diff --git a/tools/python-yasm/tests/python_test.sh b/tools/python-yasm/tests/python_test.sh
deleted file mode 100755
index 1f3896d..0000000
--- a/tools/python-yasm/tests/python_test.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-# Based on _sanity.sh from Quod Libet
-# http://www.sacredchao.net/quodlibet/
-# $Id$
-
-set -e
-
-test -n "${srcdir}" || srcdir=.
-test -n "${PYTHON}" || PYTHON=python
-
-if test "$1" = "--help" -o "$1" = "-h"; then
-    echo "Usage: $0 --sanity | [TestName] ..."
-    exit 0
-elif [ "$1" = "--sanity" ]; then
-    echo "Running static sanity checks."
-    grep "except None:" ${srcdir}/tools/python-yasm/tests/*.py
-else
-    ${PYTHON} -c "import sys; import glob; sys.path.insert(0, '${srcdir}/tools/python-yasm'); sys.path.insert(0, glob.glob('build/lib.*')[0]); import tests; raise SystemExit(tests.unit('$*'.split()))"
-fi
-
diff --git a/tools/python-yasm/tests/test_bytecode.py b/tools/python-yasm/tests/test_bytecode.py
deleted file mode 100644
index ff7d706..0000000
--- a/tools/python-yasm/tests/test_bytecode.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Id$
-from tests import TestCase, add
-from yasm import Bytecode, ImmVal, Expression
-
-class TImmVal(TestCase):
-    def test_create(self):
-        self.assertRaises(TypeError, ImmVal, "notimmval")
-
-        imm = ImmVal(Expression('+', 2, 3))
-
-add(TImmVal)
diff --git a/tools/python-yasm/tests/test_expr.py b/tools/python-yasm/tests/test_expr.py
deleted file mode 100644
index 1fb930d..0000000
--- a/tools/python-yasm/tests/test_expr.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# $Id$
-from tests import TestCase, add
-from yasm import Expression
-import operator
-
-class TExpression(TestCase):
-    def test_create(self):
-        e1 = Expression(operator.add, 1, 2)
-        e2 = Expression('+', 1, 2)
-        
-        self.assertEquals(e1.get_intnum(), e1.get_intnum())
-
-    def test_extract(self):
-        e1 = Expression('/', 15, 5)
-        self.assertEquals(e1.get_intnum(), 3)
-        self.assertRaises(ValueError, e1.extract_segoff)
-        self.assertRaises(ValueError, e1.extract_wrt)
-
-add(TExpression)
diff --git a/tools/python-yasm/tests/test_intnum.py b/tools/python-yasm/tests/test_intnum.py
deleted file mode 100644
index 1c157f6..0000000
--- a/tools/python-yasm/tests/test_intnum.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# $Id$
-from tests import TestCase, add
-from yasm import IntNum
-
-class TIntNum(TestCase):
-    legal_values = [
-        0, 1, -1, 2, -2, 17, -17,
-        2**31-1, -2**31, 2**31, 2**32-1, -2**32,
-        2**63-1, -2**63-1, 2**63, 2**64, -2**64,
-        2**127-1, -2**127
-    ]
-    overflow_values = [
-        2**127, -2**127-1
-    ]
-
-    def test_to_from(self):
-        for i in self.legal_values:
-            self.assertEquals(i, int(IntNum(i)))
-
-    def test_overflow(self):
-        for i in self.overflow_values:
-            self.assertRaises(OverflowError, IntNum, i)
-
-    def test_exceptions(self):
-        self.assertRaises(ZeroDivisionError, IntNum(1).__div__, 0)
-
-        IntNum(1) / 1 # make sure the above error is cleared
-
-        try: IntNum(1) / 0
-        except ZeroDivisionError, err:
-            self.assertEquals('divide by zero', str(err))
-
-    def test_xor(self):
-        a = IntNum(-234)
-        b = IntNum(432)
-        c = a ^ b
-        self.assertEquals(a, -234)
-        self.assertEquals(b, 432)
-        self.assertEquals(c, -234 ^ 432)
-
-    def test_ixor(self):
-        a = IntNum(-234)
-        b = IntNum(432)
-        a ^= b; b ^= a; a ^= b
-        self.assertEquals(a, 432)
-        self.assertEquals(b, -234)
-
-    def test_cmp(self):
-        a = IntNum(-1)
-        b = IntNum(0)
-        c = IntNum(1)
-        self.assert_(a < b < c)
-        self.assert_(a <= b <= c)
-        self.assert_(c >= b >= a)
-        self.assert_(c > b > a)
-        self.assert_(a != b != c)
-
-    def test_abs(self):
-        a = IntNum(-1)
-        b = IntNum(0)
-        c = IntNum(1)
-
-        self.assertEquals(abs(a), abs(c))
-        self.assertEquals(abs(a) - abs(c), abs(b))
-
-add(TIntNum)
diff --git a/tools/python-yasm/tests/test_symrec.py b/tools/python-yasm/tests/test_symrec.py
deleted file mode 100644
index a228eeb..0000000
--- a/tools/python-yasm/tests/test_symrec.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# $Id$
-from tests import TestCase, add
-from yasm import SymbolTable, Expression, YasmError
-
-class TSymbolTable(TestCase):
-    def setUp(self):
-        self.symtab = SymbolTable()
-
-    def test_keys(self):
-        self.assertEquals(len(self.symtab.keys()), 0)
-        self.symtab.declare("foo", None, 0)
-        keys = self.symtab.keys()
-        self.assertEquals(len(keys), 1)
-        self.assertEquals(keys[0], "foo")
-
-    def test_contains(self):
-        self.assert_("foo" not in self.symtab)
-        self.symtab.declare("foo", None, 0)
-        self.assert_("foo" in self.symtab)
-
-    def test_exception(self):
-        expr = Expression('+', 1, 2)
-        self.symtab.define_equ("foo", expr, 0)
-        self.assertRaises(YasmError, self.symtab.define_equ, "foo", expr, 0)
-        self.symtab.define_equ("bar", expr, 0) # cleared
-        self.assertRaises(YasmError, self.symtab.define_special, "bar",
-                'global')
-
-    def test_iters(self):
-        tab = self.symtab
-        tab.declare("foo", None, 0)
-        tab.declare("bar", None, 0)
-        tab.declare("baz", None, 0)
-
-        # while ordering is not known, it must be consistent
-        self.assertEquals(list(tab.keys()), list(tab.iterkeys()))
-        self.assertEquals(list(tab.values()), list(tab.itervalues()))
-        self.assertEquals(list(tab.items()), list(tab.iteritems()))
-        self.assertEquals(list(tab.iteritems()), zip(tab.keys(), tab.values()))
-
-add(TSymbolTable)
-
-class TSymbolAttr(TestCase):
-    def setUp(self):
-        self.symtab = SymbolTable()
-        self.declsym = self.symtab.declare("foo", None, 0)
-
-    def test_visibility(self):
-        sym = self.symtab.declare("local1", None, 0)
-        self.assertEquals(sym.visibility, set())
-        sym = self.symtab.declare("local2", '', 0)
-        self.assertEquals(sym.visibility, set())
-        sym = self.symtab.declare("local3", 'local', 0)
-        self.assertEquals(sym.visibility, set())
-        sym = self.symtab.declare("global", 'global', 0)
-        self.assertEquals(sym.visibility, set(['global']))
-        sym = self.symtab.declare("common", 'common', 0)
-        self.assertEquals(sym.visibility, set(['common']))
-        sym = self.symtab.declare("extern", 'extern', 0)
-        self.assertEquals(sym.visibility, set(['extern']))
-        sym = self.symtab.declare("dlocal", 'dlocal', 0)
-        self.assertEquals(sym.visibility, set(['dlocal']))
-
-        self.assertRaises(ValueError,
-                          lambda: self.symtab.declare("extern2", 'foo', 0))
-    def test_name(self):
-        self.assertEquals(self.declsym.name, "foo")
-
-    def test_equ(self):
-        self.assertRaises(AttributeError, lambda: self.declsym.equ)
-
-    def test_label(self):
-        self.assertRaises(AttributeError, lambda: self.declsym.label)
-
-    def test_is_special(self):
-        self.assertEquals(self.declsym.is_special, False)
-
-    def test_is_curpos(self):
-        self.assertEquals(self.declsym.is_curpos, False)
-
-add(TSymbolAttr)
diff --git a/tools/python-yasm/value.pxi b/tools/python-yasm/value.pxi
deleted file mode 100644
index 81b1f2d..0000000
--- a/tools/python-yasm/value.pxi
+++ /dev/null
@@ -1,65 +0,0 @@
-# Python bindings for Yasm: Pyrex input file for value.h
-#
-#  Copyright (C) 2006  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.
-
-cdef extern from "libyasm/value.h":
-    cdef void yasm_value_initialize(yasm_value *value, yasm_expr *e,
-                                    unsigned int size)
-    cdef void yasm_value_init_sym(yasm_value *value, yasm_symrec *sym,
-                                  unsigned int size)
-    cdef void yasm_value_delete(yasm_value *value)
-    cdef int yasm_value_finalize(yasm_value *value)
-    cdef int yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
-                                      unsigned int size)
-    cdef int yasm_value_output_basic(yasm_value *value, unsigned char *buf,
-            size_t destsize, yasm_bytecode *bc, int warn, yasm_arch *arch,
-            yasm_calc_bc_dist_func calc_bc_dist)
-    cdef void yasm_value_print(yasm_value *value, FILE *f, int indent_level)
-
-cdef class Value:
-    cdef yasm_value value
-    def __new__(self, value=None, size=None):
-        cdef unsigned int sz
-        if size is None:
-            sz = 0
-        else:
-            sz = size;
-
-        yasm_value_initialize(&self.value, NULL, sz)
-        if value is None:
-            pass
-        elif isinstance(value, Expression):
-            yasm_value_initialize(&self.value,
-                                  yasm_expr_copy((<Expression>value).expr), sz)
-        elif isinstance(value, Symbol):
-            yasm_value_init_sym(&self.value, (<Symbol>value).sym, sz)
-        else:
-            raise ValueError("Invalid value type '%s'" % type(value))
-
-    def __dealloc__(self):
-        yasm_value_delete(&self.value)
-
-    def finalize(self):
-        return yasm_value_finalize(&self.value)
-
diff --git a/tools/python-yasm/yasm.pyx b/tools/python-yasm/yasm.pyx
deleted file mode 100644
index f0114d2..0000000
--- a/tools/python-yasm/yasm.pyx
+++ /dev/null
@@ -1,131 +0,0 @@
-# Python bindings for Yasm: Main Pyrex input file
-#
-#  Copyright (C) 2006  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.
-"""Interface to the Yasm library.
-
-The Yasm library (aka libyasm) provides the core functionality of the Yasm
-assembler.  Classes in this library provide for manipulation of machine
-instructions and object file constructs such as symbol tables and sections.
-
-Expression objects encapsulate complex expressions containing registers,
-symbols, and operations such as SEG.
-
-Bytecode objects encapsulate data or code objects such as data, reserve,
-align, or instructions.
-
-Section objects encapsulate an object file section, including the section
-name, any Bytecode objects contained within that section, and other
-information.
-
-"""
-
-cdef extern from "Python.h":
-    cdef object PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
-    cdef object PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
-                                             void (*destr)(void *, void *))
-    cdef int PyType_Check(object)
-    cdef int PyCObject_Check(object)
-    cdef void *PyCObject_AsVoidPtr(object)
-    cdef void *PyCObject_GetDesc(object)
-
-    cdef object _PyLong_FromByteArray(unsigned char *bytes, unsigned int n,
-                                      int little_endian, int is_signed)
-    cdef int _PyLong_AsByteArray(object v, unsigned char *bytes, unsigned int n,
-                                 int little_endian, int is_signed) except -1
-
-    cdef void Py_INCREF(object o)
-    cdef void Py_DECREF(object o)
-
-    cdef void PyErr_SetString(object type, char *message)
-    cdef object PyErr_Format(object type, char *format, ...)
-
-cdef object __pass_voidp(void *obj, object forclass):
-    return PyCObject_FromVoidPtrAndDesc(obj, <void *>forclass, NULL)
-
-cdef void *__get_voidp(object obj, object forclass) except NULL:
-    cdef void* desc
-
-    if not PyCObject_Check(obj):
-        msg = "obj %r is not a CObject" % obj
-        PyErr_SetString(TypeError, msg)
-        return NULL
-
-    desc = PyCObject_GetDesc(obj)
-
-    if desc != <void *>forclass:
-        if desc == NULL:
-            msg = "CObject type is not set (expecting %s)" % forclass
-        elif PyType_Check(<object>desc):
-            msg = "CObject is for %s not %s" % (<object>desc, forclass)
-        else:
-            msg = "CObject is incorrect (expecting %s)" % forclass
-        PyErr_SetString(TypeError, msg)
-        return NULL
-
-    return PyCObject_AsVoidPtr(obj)
-
-cdef extern from "stdlib.h":
-    cdef void *malloc(int n)
-    cdef void free(void *p)
-
-cdef extern from "libyasm/compat-queue.h":
-    pass
-
-cdef class Register:
-    cdef unsigned long reg
-    def __new__(self, reg):
-        self.reg = reg
-
-include "coretype.pxi"
-
-include "errwarn.pxi"
-include "intnum.pxi"
-include "floatnum.pxi"
-include "expr.pxi"
-include "symrec.pxi"
-include "value.pxi"
-
-include "bytecode.pxi"
-
-
-cdef extern from "libyasm/bitvect.h":
-    cdef void BitVector_Boot()
-    cdef void BitVector_Shutdown()
-
-def __initialize():
-    BitVector_Boot()
-    yasm_intnum_initialize()
-    yasm_floatnum_initialize()
-    yasm_errwarn_initialize()
-
-def __cleanup():
-    yasm_floatnum_cleanup()
-    yasm_intnum_cleanup()
-    yasm_errwarn_cleanup()
-    BitVector_Shutdown()
-
-__initialize()
-import atexit
-atexit.register(__cleanup)
-