[Nasm-commits] [nasm:macho64] Push files missed during last commit.

nasm-bot for Keith Kanios keith at kanios.net
Thu Jun 4 19:56:20 PDT 2020


Commit-ID:  fabb245a364fbc071f4ac3ae7aaf90a190892e44
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=fabb245a364fbc071f4ac3ae7aaf90a190892e44
Author:     Keith Kanios <keith at kanios.net>
AuthorDate: Tue, 7 Jul 2009 23:55:03 -0500
Committer:  Keith Kanios <keith at kanios.net>
CommitDate: Tue, 7 Jul 2009 23:55:03 -0500

Push files missed during last commit.



---
 listing.h => headers/c              |   11 -
 headers/doc                         |   33 +
 output/outbin.mac => headers/mac    |    7 -
 pptok.dat => headers/perl           |   56 --
 misc/genfma.pl                      |   63 ++
 misc/omfdump.c                      |  223 +++++
 nasm.nsi                            |  112 +++
 eval.h => output/dwarf.h            |   47 +-
 output/elf32.h                      |  167 ++++
 output/elf64.h                      |  189 +++++
 output/elfcommon.h                  |  250 ++++++
 float.h => output/nulldbg.c         |   70 +-
 output/{outbin.mac => outaout.mac}  |    5 +-
 output/{outbin.mac => outas86.mac}  |    5 +-
 tables.h => output/outelf.c         |   49 +-
 output/outelf.h                     |   96 +++
 rdoff/rdx.c => output/outform.c     |   89 +-
 output/outform.h                    |  344 ++++++++
 quote.h => output/outlib.c          |   28 +-
 float.h => output/outlib.h          |   34 +-
 output/{outbin.mac => outmacho.mac} |    5 +-
 output/outmacho32.c                 | 1382 +++++++++++++++++++++++++++++++
 output/outmacho64.c                 | 1528 +++++++++++++++++++++++++++++++++++
 rbtree.c                            |  119 +++
 rdoff/symtab.h => rbtree.h          |   32 +-
 rdoff/{rdf2com.1 => rdf2ihx.1}      |    0
 rdoff/{rdf2com.1 => rdf2ith.1}      |    0
 rdoff/{rdf2com.1 => rdf2srec.1}     |    0
 test/align13.asm                    |   16 +
 test/align13s.asm                   |   16 +
 test/andbyte.asm                    |   15 +
 test/avx005.asm                     |  529 ++++++++++++
 test/br2148476.asm                  |  221 +++++
 test/br2222615.asm                  |   19 +
 test/br890790.asm                   |    7 +
 test/br890790_i.asm                 |    1 +
 test/crc32.asm                      |   37 +
 test/elf64so.asm                    |  118 +++
 test/{elftest.c => elftest64.c}     |   27 +-
 test/fwdopt.asm                     |  133 +++
 test/fwdoptpp.asm                   |  150 ++++
 test/gotoff64.asm                   |   25 +
 test/ifelse.asm                     |   46 ++
 test/immwarn.asm                    |   91 +++
 test/imul.asm                       |   90 +++
 test/optimization.asm               |  104 +++
 test/pinsr16.asm                    |   52 ++
 test/pinsr32.asm                    |   52 ++
 test/pinsr64.asm                    |   68 ++
 test/popcnt.asm                     |   32 +
 test/ppindirect.asm                 |   42 +
 test/pushseg.asm                    |   17 +
 test/riprel2.asm                    |   11 +
 test/smartalign16.asm               |   36 +
 test/smartalign32.asm               |   36 +
 test/smartalign64.asm               |   36 +
 test/struc.asm                      |   33 +
 test/weirdpaste.asm                 |   29 +
 float.h => ver.c                    |   32 +-
 59 files changed, 6803 insertions(+), 262 deletions(-)

diff --git a/listing.h b/headers/c
similarity index 90%
copy from listing.h
copy to headers/c
index da2e849f..31157c44 100644
--- a/listing.h
+++ b/headers/c
@@ -31,14 +31,3 @@
  *
  * ----------------------------------------------------------------------- */
 
-/* 
- * listing.h   header file for listing.c
- */
-
-#ifndef NASM_LISTING_H
-#define NASM_LISTING_H
-
-extern ListGen nasmlist;
-extern int user_nolist;         /* fbk - 9/1/00 */
-
-#endif
diff --git a/headers/doc b/headers/doc
new file mode 100644
index 00000000..38ab1332
--- /dev/null
+++ b/headers/doc
@@ -0,0 +1,33 @@
+\# --------------------------------------------------------------------------
+\#   
+\#   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+\#   See the file AUTHORS included with the NASM distribution for
+\#   the specific copyright holders.
+\#
+\#   Redistribution and use in source and binary forms, with or without
+\#   modification, are permitted provided that the following
+\#   conditions are met:
+\#
+\#   * Redistributions of source code must retain the above copyright
+\#     notice, this list of conditions and the following disclaimer.
+\#   * 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 COPYRIGHT HOLDERS AND
+\#     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+\#     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+\#     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+\#     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+\#     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+\#     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+\#     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+\#     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+\#     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+\#     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+\#     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+\#     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\#
+\# --------------------------------------------------------------------------
+
diff --git a/output/outbin.mac b/headers/mac
similarity index 93%
copy from output/outbin.mac
copy to headers/mac
index be7fefae..b68288f6 100644
--- a/output/outbin.mac
+++ b/headers/mac
@@ -31,10 +31,3 @@
 ;;
 ;; --------------------------------------------------------------------------
 
-OUT: bin
-%define __SECT__ [section .text]
-%imacro org 1+.nolist
-[org %1]
-%endmacro
-%macro __NASM_CDecl__ 1
-%endmacro
diff --git a/pptok.dat b/headers/perl
similarity index 77%
copy from pptok.dat
copy to headers/perl
index 2dac63e9..23170882 100644
--- a/pptok.dat
+++ b/headers/perl
@@ -31,59 +31,3 @@
 ##
 ## --------------------------------------------------------------------------
 
-#
-# A * at the end indicates a condition; the list of conditions are
-# on lines starting with *; the negatives are auto-generated
-#
-*
-*ctx
-*def
-*empty
-*id
-*idn
-*idni
-*macro
-*num
-*str
-*token
-%arg
-%assign
-%clear
-%define
-%defstr
-%depend
-%elif*
-%else
-%endif
-%endm
-%endmacro
-%endrep
-%error
-%exitrep
-%fatal
-%iassign
-%idefine
-%idefstr
-%if*
-%imacro
-%include
-%ixdefine
-%line
-%local
-%macro
-%pathsearch
-%pop
-%push
-%rep
-%repl
-%rotate
-%stacksize
-%strcat
-%strlen
-%substr
-%undef
-%unimacro
-%unmacro
-%use
-%warning
-%xdefine
diff --git a/misc/genfma.pl b/misc/genfma.pl
new file mode 100755
index 00000000..2b6a65c5
--- /dev/null
+++ b/misc/genfma.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+%packed_insns = (
+    'vfmadd'    => 0x98,
+    'vfmaddsub' => 0x96,
+    'vfmsubadd' => 0x97,
+    'vfmsub'    => 0x9a,
+    'vfnmadd'   => 0x9c,
+    'vfnmsub'   => 0x9e
+    );
+
+%scalar_insns = (
+    'vfmadd'    => 0x99,
+    'vfmsub'    => 0x9b,
+    'vfnmadd'   => 0x9d,
+    'vfnmsub'   => 0x9f
+    );
+
+foreach $pi ( sort(keys(%packed_insns)) ) {
+    $op = $packed_insns{$pi};
+    foreach $order ('132', '213', '231') {
+	$xorder = substr($order,1,1).substr($order,0,1).substr($order,2,1);
+	foreach $o ($order, $xorder) {
+	    for ($w = 0; $w < 2; $w++) {
+		$suf = $w  ? 'pd' : 'ps';
+		for ($l = 128; $l <= 256; $l <<= 1) {
+		    $sx  = ($l == 256) ? 'SY' : 'SO';
+		    $mm  = ($l == 256) ? 'ymm' : 'xmm';
+		    printf "%-15s %-31s %-8s%-39s %s\n",
+		    	"\U${pi}${o}${suf}",
+			"${mm}reg,${mm}reg,${mm}rm",
+		    	"[rvm:",
+		        sprintf("vex.dds.%d.66.0f38.w%d %02x /r]",
+			    $l, $w, $op),
+		    "FMA,FUTURE,${sx}";
+		}
+	    }
+	}
+	$op += 0x10;
+    }
+}
+
+foreach $si ( sort(keys(%scalar_insns)) ) {
+    $op = $scalar_insns{$si};
+    foreach $order ('132', '213', '231') {
+	$xorder = substr($order,1,1).substr($order,0,1).substr($order,2,1);
+	foreach $o ($order, $xorder) {
+	    for ($w = 0; $w < 2; $w++) {
+		$suf = $w ? 'sd' : 'ss';
+		$sx  = $w ? 'SQ' : 'SD';
+		$l  = 128;
+		$mm  = 'xmm';
+		printf "%-15s %-31s %-8s%-39s %s\n",
+		    "\U${si}${o}${suf}",
+		    "${mm}reg,${mm}reg,${mm}rm",
+		    '[rvm:',
+		    sprintf("vex.dds.%d.66.0f38.w%d %02x /r]",
+			$l, $w, $op),
+		"FMA,FUTURE,${sx}";
+	    }
+	}
+	$op += 0x10;
+    }
+}
diff --git a/misc/omfdump.c b/misc/omfdump.c
new file mode 100644
index 00000000..322971e9
--- /dev/null
+++ b/misc/omfdump.c
@@ -0,0 +1,223 @@
+/*
+ * omfdump.c
+ *
+ * Very simple program to dump the contents of an OMF (OBJ) file
+ *
+ * This assumes a littleendian, unaligned-load-capable host and a
+ * C compiler which handles basic C99.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+const char *progname;
+
+static const char *record_types[256] =
+{
+    [0x80] = "THEADR",
+    [0x82] = "LHEADR",
+    [0x88] = "COMENT",
+    [0x8a] = "MODEND16",
+    [0x8b] = "MODEND32",
+    [0x8c] = "EXTDEF",
+    [0x90] = "PUBDEF16",
+    [0x91] = "PUBDEF32",
+    [0x94] = "LINNUM16",
+    [0x95] = "LINNUM32",
+    [0x96] = "LNAMES",
+    [0x98] = "SEGDEF16",
+    [0x99] = "SEGDEF32",
+    [0x9a] = "GRPDEF",
+    [0x9c] = "FIXUPP16",
+    [0x9d] = "FIXUPP32",
+    [0xa0] = "LEDATA16",
+    [0xa1] = "LEDATA32",
+    [0xa2] = "LIDATA16",
+    [0xa3] = "LIDATA32",
+    [0xb0] = "COMDEF",
+    [0xb2] = "BAKPAT16",
+    [0xb3] = "BAKPAT32",
+    [0xb4] = "LEXTDEF",
+    [0xb6] = "LPUBDEF16",
+    [0xb7] = "LPUBDEF32",
+    [0xb8] = "LCOMDEF",
+    [0xbc] = "CEXTDEF",
+    [0xc2] = "COMDAT16",
+    [0xc3] = "COMDAT32",
+    [0xc4] = "LINSYM16",
+    [0xc5] = "LINSYM32",
+    [0xc6] = "ALIAS",
+    [0xc8] = "NBKPAT16",
+    [0xc9] = "NBKPAT32",
+    [0xca] = "LLNAMES",
+    [0xcc] = "VERNUM",
+    [0xce] = "VENDEXT",
+    [0xf0] = "LIBHDR",
+    [0xf1] = "LIBEND",
+};
+
+typedef void (*dump_func)(uint8_t, const uint8_t *, size_t);
+
+static void hexdump_data(unsigned int offset, const uint8_t *data, size_t n)
+{
+    unsigned int i, j;
+
+    for (i = 0; i < n; i += 16) {
+	printf("  %04x: ", i+offset);
+	for (j = 0; j < 16; j++) {
+	    if (i+j < n)
+		printf("%02x%c", data[i+j], (j == 7) ? '-' : ' ');
+	    else
+		printf("   ");
+	}
+	printf(" :  ");
+	for (j = 0; j < 16; j++) {
+	    if (i+j < n)
+		putchar(isprint(data[i+j]) ? data[i+j] : '.');
+	}
+	putchar('\n');
+    }
+}
+
+static void dump_unknown(uint8_t type, const uint8_t *data, size_t n)
+{
+    (void)type;
+    hexdump_data(0, data, n);
+}
+
+static void dump_coment(uint8_t type, const uint8_t *data, size_t n)
+{
+    uint8_t class;
+    static const char *coment_class[256] = {
+	[0x00] = "Translator",
+	[0x01] = "Copyright",
+	[0x81] = "Library specifier",
+	[0x9c] = "MS-DOS version",
+	[0x9d] = "Memory model",
+	[0x9e] = "DOSSEG",
+	[0x9f] = "Library search",
+	[0xa0] = "OMF extensions",
+	[0xa1] = "New OMF extension",
+	[0xa2] = "Link pass separator",
+	[0xa3] = "LIBMOD",
+	[0xa4] = "EXESTR",
+	[0xa6] = "INCERR",
+	[0xa7] = "NOPAD",
+	[0xa8] = "WKEXT",
+	[0xa9] = "LZEXT",
+	[0xda] = "Comment",
+	[0xdb] = "Compiler",
+	[0xdc] = "Date",
+	[0xdd] = "Timestamp",
+	[0xdf] = "User",
+	[0xe9] = "Dependency file",
+	[0xff] = "Command line"
+    };
+
+    if (n < 2) {
+	dump_unknown(type, data, n);
+	return;
+    }
+
+    type  = data[0];
+    class = data[1];
+
+    printf("  [NP=%d NL=%d UD=%02X] %02X %s\n",
+	   (type >> 7) & 1,
+	   (type >> 6) & 1,
+	   type & 0x3f,
+	   class,
+	   coment_class[class] ? coment_class[class] : "???");
+
+    hexdump_data(2, data+2, n-2);
+}
+
+static const dump_func dump_type[256] =
+{
+    [0x88] = dump_coment,
+};
+
+int dump_omf(int fd)
+{
+    struct stat st;
+    size_t len, n;
+    uint8_t type;
+    const uint8_t *p, *data;
+
+    if (fstat(fd, &st))
+	return -1;
+
+    len = st.st_size;
+
+    data = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (data == MAP_FAILED)
+	return -1;
+
+    p = data;
+    while (len >= 3) {
+	uint8_t csum;
+	int i;
+
+	type = p[0];
+	n = *(uint16_t *)(p+1);
+
+	printf("%02x %-10s %4zd bytes",
+	       type,
+	       record_types[type] ? record_types[type] : "???",
+	       n);
+
+	if (len < n+3) {
+	    printf("\n  (truncated, only %zd bytes left)\n", len-3);
+	    break;		/* Truncated */
+	}
+
+	p += 3;	      /* Header doesn't count in the length */
+	n--;	      /* Remove checksum byte */
+
+	csum = 0;
+	for (i = -3; i < (int)n; i++)
+	    csum -= p[i];
+
+	printf(", checksum %02X", p[i]);
+	if (csum == p[i])
+	    printf(" (valid)\n");
+	else
+	    printf(" (actual = %02X)\n", csum);
+
+	if (dump_type[type])
+	    dump_type[type](type, p, n);
+	else
+	    dump_unknown(type, p, n);
+
+	p   += n+1;
+	len -= (n+4);
+    }
+
+    munmap((void *)data, st.st_size);
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    int fd;
+    int i;
+
+    progname = argv[0];
+
+    for (i = 1; i < argc; i++) {
+	fd = open(argv[i], O_RDONLY);
+	if (fd < 0 || dump_omf(fd)) {
+	    perror(argv[i]);
+	    return 1;
+	}
+	close(fd);
+    }
+
+    return 0;
+}
diff --git a/nasm.nsi b/nasm.nsi
new file mode 100644
index 00000000..ba6b4a25
--- /dev/null
+++ b/nasm.nsi
@@ -0,0 +1,112 @@
+#!Nsis Installer Command Script
+
+# Copyright (c) 2009, Shao Miller (shao.miller at yrdsb.edu.on.ca)
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+!include "version.nsh"
+!define PRODUCT_NAME "Netwide Assembler"
+!define PRODUCT_SHORT_NAME "nasm"
+!define PACKAGE_NAME "${PRODUCT_NAME} ${VERSION}"
+!define PACKAGE_SHORT_NAME "${PRODUCT_SHORT_NAME}-${VERSION}"
+
+Name "${PACKAGE_NAME}"
+OutFile "${PACKAGE_SHORT_NAME}-installer.exe"
+InstallDir "$PROGRAMFILES\NASM"
+InstallDirRegKey HKLM "SOFTWARE\${PACKAGE_SHORT_NAME}" "InstallDir"
+SetCompressor lzma
+
+XPStyle on
+
+DirText "Please select the installation folder."
+Page directory
+
+ComponentText "Select which optional components you want to install."
+Page components
+
+ShowInstDetails hide
+ShowUninstDetails hide
+Page instfiles
+
+Section "${PACKAGE_NAME}"
+  SectionIn RO
+
+  SetOutPath "$INSTDIR\."
+  File "LICENSE"
+  File "nasm.exe"
+  File "ndisasm.exe"
+  File "doc/nasmdoc.pdf"
+  File "rdoff/ldrdf.exe"
+  File "rdoff/rdf2bin.exe"
+  File "rdoff/rdf2com.exe"
+  File "rdoff/rdf2ith.exe"
+  File "rdoff/rdf2ihx.exe"
+  File "rdoff/rdf2srec.exe"
+  File "rdoff/rdfdump.exe"
+  File "rdoff/rdflib.exe"
+  File "rdoff/rdx.exe"
+  FileOpen $0 "nasmpath.bat" w
+  IfErrors skip
+  FileWrite $0 "@set path=$INSTDIR;%path%$\r$\n"
+  FileWrite $0 "@%comspec%"
+  FileClose $0
+  skip:
+SectionEnd
+
+Section "Start Menu Shortcuts"
+  CreateDirectory "$SMPROGRAMS\${PACKAGE_NAME}"
+  CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\Uninstall ${PACKAGE_NAME}.lnk" "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe" "" "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe" 0
+  CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\NASM Shell.lnk" "$INSTDIR\nasmpath.bat" "" "$INSTDIR\nasmpath.bat" 0
+  CreateShortCut "$SMPROGRAMS\${PACKAGE_NAME}\NASM Manual.lnk" "$INSTDIR\nasmdoc.pdf" "" "$INSTDIR\nasmdoc.pdf" 0
+SectionEnd
+
+Section "Desktop Icons"
+  CreateShortCut "$DESKTOP\NASM.lnk" "$INSTDIR\nasmpath.bat" "" "$INSTDIR\nasmpath.bat" 0
+SectionEnd
+
+Section "Uninstall"
+  Delete /rebootok "$DESKTOP\NASM.lnk"
+  Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\NASM Shell.lnk"
+  Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\NASM Manual.lnk"
+  Delete /rebootok "$SMPROGRAMS\${PACKAGE_NAME}\Uninstall ${PACKAGE_NAME}.lnk"
+  RMDir "$SMPROGRAMS\${PACKAGE_NAME}"
+
+  Delete /rebootok "$INSTDIR\nasmpath.bat"
+  Delete /rebootok "$INSTDIR\rdx.exe"
+  Delete /rebootok "$INSTDIR\rdflib.exe"
+  Delete /rebootok "$INSTDIR\rdfdump.exe"
+  Delete /rebootok "$INSTDIR\rdf2srec.exe"
+  Delete /rebootok "$INSTDIR\rdf2ihx.exe"
+  Delete /rebootok "$INSTDIR\rdf2ith.exe"
+  Delete /rebootok "$INSTDIR\rdf2com.exe"
+  Delete /rebootok "$INSTDIR\rdf2bin.exe"
+  Delete /rebootok "$INSTDIR\ndisasm.exe"
+  Delete /rebootok "$INSTDIR\nasmdoc.pdf"
+  Delete /rebootok "$INSTDIR\nasm.exe"
+  Delete /rebootok "$INSTDIR\ldrdf.exe"
+  Delete /rebootok "$INSTDIR\LICENSE"
+  RMDir "$INSTDIR"
+SectionEnd
+
+Section -post
+  WriteUninstaller "$INSTDIR\Uninstall ${PACKAGE_NAME}.exe"
+SectionEnd
+
diff --git a/eval.h b/output/dwarf.h
similarity index 67%
copy from eval.h
copy to output/dwarf.h
index 0ea59d17..4994464b 100644
--- a/eval.h
+++ b/output/dwarf.h
@@ -31,28 +31,29 @@
  *
  * ----------------------------------------------------------------------- */
 
-/* 
- * eval.h   header file for eval.c
- */
+#ifndef OUTPUT_DWARF_H
+#define OUTPUT_DWARF_H
 
-#ifndef NASM_EVAL_H
-#define NASM_EVAL_H
+#define    DW_TAG_compile_unit	0x11
+#define    DW_TAG_subprogram    0x2e
+#define    DW_AT_name           0x03
+#define    DW_AT_stmt_list      0x10
+#define    DW_AT_low_pc         0x11
+#define    DW_AT_high_pc        0x12
+#define    DW_AT_language       0x13
+#define    DW_AT_producer       0x25
+#define    DW_AT_frame_base     0x40
+#define    DW_FORM_addr         0x01
+#define    DW_FORM_data2        0x05
+#define    DW_FORM_data4        0x06
+#define    DW_FORM_string       0x08
+#define    DW_LNS_extended_op   0
+#define    DW_LNS_advance_pc    2
+#define    DW_LNS_advance_line  3
+#define    DW_LNS_set_file      4
+#define    DW_LNE_end_sequence  1
+#define    DW_LNE_set_address   2
+#define    DW_LNE_define_file   3
+#define    DW_LANG_Mips_Assembler  0x8001
 
-/*
- * 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 eval_global_info(struct ofmt *output, lfunc lookup_label,
-                      struct location * locp);
-
-/*
- * The evaluator itself.
- */
-expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv,
-               int *fwref, int critical, efunc report_error,
-               struct eval_hints *hints);
-
-void eval_cleanup(void);
-
-#endif
+#endif /* OUTPUT_DWARF_H */
diff --git a/output/elf32.h b/output/elf32.h
new file mode 100644
index 00000000..b40a9ffa
--- /dev/null
+++ b/output/elf32.h
@@ -0,0 +1,167 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef OUTPUT_ELF32_H
+#define OUTPUT_ELF32_H
+
+#include "output/elfcommon.h"
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+typedef uint16_t Elf32_Half;
+typedef int16_t Elf32_SHalf;
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+
+typedef uint32_t Elf32_Off;
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Section;
+
+/* Dynamic header */
+
+typedef struct elf32_dyn {
+    Elf32_Sword d_tag;
+    union {
+	Elf32_Sword d_val;
+	Elf32_Addr d_ptr;
+    } d_un;
+} Elf32_Dyn;
+
+/* Relocations */
+
+#define ELF32_R_SYM(x)	((x) >> 8)
+#define ELF32_R_TYPE(x)	((x) & 0xff)
+
+typedef struct elf32_rel {
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf32_rela {
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+    Elf32_Sword r_addend;
+} Elf32_Rela;
+
+enum reloc32_type {
+    R_386_32		=  1,   /* ordinary absolute relocation */
+    R_386_PC32          =  2,   /* PC-relative relocation */
+    R_386_GOT32         =  3,   /* an offset into GOT */
+    R_386_PLT32         =  4,   /* a PC-relative offset into PLT */
+    R_386_COPY          =  5,   /* ??? */
+    R_386_GLOB_DAT      =  6,   /* ??? */
+    R_386_JUMP_SLOT     =  7,   /* ??? */
+    R_386_RELATIVE      =  8,   /* ??? */
+    R_386_GOTOFF        =  9,   /* an offset from GOT base */
+    R_386_GOTPC         = 10,   /* a PC-relative offset _to_ GOT */
+    R_386_TLS_TPOFF     = 14,   /* Offset in static TLS block */
+    R_386_TLS_IE        = 15,   /* Address of GOT entry for static TLS
+                                   block offset */
+    /* These are GNU extensions, but useful */
+    R_386_16            = 20,   /* A 16-bit absolute relocation */
+    R_386_PC16          = 21,   /* A 16-bit PC-relative relocation */
+    R_386_8             = 22,   /* An 8-bit absolute relocation */
+    R_386_PC8           = 23    /* An 8-bit PC-relative relocation */
+};
+
+/* Symbol */
+
+typedef struct elf32_sym {
+    Elf32_Word st_name;
+    Elf32_Addr st_value;
+    Elf32_Word st_size;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf32_Half st_shndx;
+} Elf32_Sym;
+
+/* Main file header */
+
+typedef struct elf32_hdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;
+    Elf32_Off e_phoff;
+    Elf32_Off e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+/* Program header */
+
+typedef struct elf32_phdr {
+    Elf32_Word p_type;
+    Elf32_Off p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
+} Elf32_Phdr;
+
+/* Section header */
+
+typedef struct elf32_shdr {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+/* Note header */
+typedef struct elf32_note {
+    Elf32_Word n_namesz;	/* Name size */
+    Elf32_Word n_descsz;	/* Content size */
+    Elf32_Word n_type;	/* Content type */
+} Elf32_Nhdr;
+
+/* How to extract and insert information held in the st_info field.  */
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+
+#endif	/* OUTPUT_ELF32_H */
diff --git a/output/elf64.h b/output/elf64.h
new file mode 100644
index 00000000..efbc4f2f
--- /dev/null
+++ b/output/elf64.h
@@ -0,0 +1,189 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef OUTPUT_ELF64_H
+#define OUTPUT_ELF64_H
+
+#include "output/elfcommon.h"
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+typedef uint16_t Elf64_Half;
+typedef int16_t Elf64_SHalf;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef uint64_t Elf64_Off;
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Section;
+
+/* Dynamic header */
+
+typedef struct elf64_dyn {
+    Elf64_Sxword d_tag;
+    union {
+	Elf64_Xword d_val;
+	Elf64_Addr d_ptr;
+    } d_un;
+} Elf64_Dyn;
+
+/* Relocations */
+
+#define ELF64_R_SYM(x)	((x) >> 32)
+#define ELF64_R_TYPE(x)	((x) & 0xffffffff)
+
+typedef struct elf64_rel {
+    Elf64_Addr r_offset;
+    Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct elf64_rela {
+    Elf64_Addr r_offset;
+    Elf64_Xword r_info;
+    Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+enum reloc64_type {
+    R_X86_64_NONE       =  0,	/* No reloc */
+    R_X86_64_64	        =  1,	/* Direct 64 bit  */
+    R_X86_64_PC32	=  2,  	/* PC relative 32 bit signed */
+    R_X86_64_GOT32	=  3,	/* 32 bit GOT entry */
+    R_X86_64_PLT32	=  4,	/* 32 bit PLT address */
+    R_X86_64_COPY	=  5,	/* Copy symbol at runtime */
+    R_X86_64_GLOB_DAT	=  6,	/* Create GOT entry */
+    R_X86_64_JUMP_SLOT	=  7,	/* Create PLT entry */
+    R_X86_64_RELATIVE	=  8,	/* Adjust by program base */
+    R_X86_64_GOTPCREL	=  9,	/* 32 bit signed PC relative offset to GOT */
+    R_X86_64_32		= 10,	/* Direct 32 bit zero extended */
+    R_X86_64_32S	= 11,	/* Direct 32 bit sign extended */
+    R_X86_64_16		= 12,	/* Direct 16 bit zero extended */
+    R_X86_64_PC16	= 13,	/* 16 bit sign extended pc relative */
+    R_X86_64_8		= 14,	/* Direct 8 bit sign extended  */
+    R_X86_64_PC8	= 15,	/* 8 bit sign extended pc relative */
+    R_X86_64_DTPMOD64	= 16,	/* ID of module containing symbol */
+    R_X86_64_DTPOFF64	= 17,	/* Offset in module's TLS block */
+    R_X86_64_TPOFF64	= 18,	/* Offset in initial TLS block */
+    R_X86_64_TLSGD	= 19,	/* 32 bit signed PC relative offset
+				   to two GOT entries for GD symbol */
+    R_X86_64_TLSLD	= 20,	/* 32 bit signed PC relative offset
+				   to two GOT entries for LD symbol */
+    R_X86_64_DTPOFF32	= 21,	/* Offset in TLS block */
+    R_X86_64_GOTTPOFF	= 22,	/* 32 bit signed PC relative offset
+				   to GOT entry for IE symbol */
+    R_X86_64_TPOFF32	= 23,	/* Offset in initial TLS block */
+    R_X86_64_PC64	= 24, 	/* word64 S + A - P */
+    R_X86_64_GOTOFF64	= 25, 	/* word64 S + A - GOT */
+    R_X86_64_GOTPC32	= 26, 	/* word32 GOT + A - P */
+    R_X86_64_GOT64	= 27, 	/* word64 G + A */
+    R_X86_64_GOTPCREL64	= 28, 	/* word64 G + GOT - P + A */
+    R_X86_64_GOTPC64	= 29, 	/* word64 GOT - P + A */
+    R_X86_64_GOTPLT64	= 30, 	/* word64 G + A */
+    R_X86_64_PLTOFF64	= 31, 	/* word64 L - GOT + A */
+    R_X86_64_SIZE32	= 32, 	/* word32 Z + A */
+    R_X86_64_SIZE64	= 33, 	/* word64 Z + A */
+    R_X86_64_GOTPC32_TLSDESC = 34, 	/* word32 */
+    R_X86_64_TLSDESC_CALL    = 35, 	/* none */
+    R_X86_64_TLSDESC    = 36 	/* word64×2 */
+};
+
+/* Symbol */
+
+typedef struct elf64_sym {
+    Elf64_Word st_name;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf64_Half st_shndx;
+    Elf64_Addr st_value;
+    Elf64_Xword st_size;
+} Elf64_Sym;
+
+/* Main file header */
+
+typedef struct elf64_hdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf64_Half e_type;
+    Elf64_Half e_machine;
+    Elf64_Word e_version;
+    Elf64_Addr e_entry;
+    Elf64_Off e_phoff;
+    Elf64_Off e_shoff;
+    Elf64_Word e_flags;
+    Elf64_Half e_ehsize;
+    Elf64_Half e_phentsize;
+    Elf64_Half e_phnum;
+    Elf64_Half e_shentsize;
+    Elf64_Half e_shnum;
+    Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* Program header */
+
+typedef struct elf64_phdr {
+    Elf64_Word p_type;
+    Elf64_Word p_flags;
+    Elf64_Off p_offset;
+    Elf64_Addr p_vaddr;
+    Elf64_Addr p_paddr;
+    Elf64_Xword p_filesz;
+    Elf64_Xword p_memsz;
+    Elf64_Xword p_align;
+} Elf64_Phdr;
+
+/* Section header */
+
+typedef struct elf64_shdr {
+    Elf64_Word sh_name;
+    Elf64_Word sh_type;
+    Elf64_Xword sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off sh_offset;
+    Elf64_Xword sh_size;
+    Elf64_Word sh_link;
+    Elf64_Word sh_info;
+    Elf64_Xword sh_addralign;
+    Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+/* Note header */
+typedef struct elf64_note {
+    Elf64_Word n_namesz;	/* Name size */
+    Elf64_Word n_descsz;	/* Content size */
+    Elf64_Word n_type;	/* Content type */
+} Elf64_Nhdr;
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+
+#endif /* OUTPUT_ELF64_H */
diff --git a/output/elfcommon.h b/output/elfcommon.h
new file mode 100644
index 00000000..608da9c8
--- /dev/null
+++ b/output/elfcommon.h
@@ -0,0 +1,250 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef OUTPUT_ELFCOMMON_H
+#define OUTPUT_ELFCOMMON_H
+
+#include "compiler.h"
+#include <inttypes.h>
+
+/* Segment types */
+#define PT_NULL    	0
+#define PT_LOAD    	1
+#define PT_DYNAMIC 	2
+#define PT_INTERP  	3
+#define PT_NOTE    	4
+#define PT_SHLIB   	5
+#define PT_PHDR    	6
+#define PT_LOOS    	0x60000000
+#define PT_HIOS    	0x6fffffff
+#define PT_LOPROC  	0x70000000
+#define PT_HIPROC  	0x7fffffff
+#define PT_GNU_EH_FRAME	0x6474e550	/* Extension, eh? */
+
+/* ELF file types */
+#define ET_NONE   	0
+#define ET_REL    	1
+#define ET_EXEC   	2
+#define ET_DYN    	3
+#define ET_CORE   	4
+#define ET_LOPROC 	0xff00
+#define ET_HIPROC 	0xffff
+
+/* ELF machine types */
+#define EM_NONE  	0
+#define EM_M32   	1
+#define EM_SPARC 	2
+#define EM_386   	3
+#define EM_68K   	4
+#define EM_88K   	5
+#define EM_486   	6	/* Not used in Linux at least */
+#define EM_860   	7
+#define EM_MIPS         8	/* R3k, bigendian(?) */
+#define EM_MIPS_RS4_BE 	10	/* R4k BE */
+#define EM_PARISC      	15
+#define EM_SPARC32PLUS 	18
+#define EM_PPC         	20
+#define EM_PPC64       	21
+#define EM_S390         22
+#define EM_SH          	42
+#define EM_SPARCV9	43	/* v9 = SPARC64 */
+#define EM_H8_300H      47
+#define EM_H8S          48
+#define EM_IA_64        50
+#define EM_X86_64       62
+#define EM_CRIS         76
+#define EM_V850         87
+#define EM_ALPHA        0x9026	/* Interrim Alpha that stuck around */
+#define EM_CYGNUS_V850  0x9080	/* Old v850 ID used by Cygnus */
+#define EM_S390_OLD     0xA390	/* Obsolete interrim value for S/390 */
+
+/* Dynamic type values */
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+
+/* Auxilliary table entries */
+#define AT_NULL		0	/* end of vector */
+#define AT_IGNORE	1	/* entry should be ignored */
+#define AT_EXECFD	2	/* file descriptor of program */
+#define AT_PHDR		3	/* program headers for program */
+#define AT_PHENT	4	/* size of program header entry */
+#define AT_PHNUM	5	/* number of program headers */
+#define AT_PAGESZ	6	/* system page size */
+#define AT_BASE		7	/* base address of interpreter */
+#define AT_FLAGS	8	/* flags */
+#define AT_ENTRY	9	/* entry point of program */
+#define AT_NOTELF	10	/* program is not ELF */
+#define AT_UID		11	/* real uid */
+#define AT_EUID		12	/* effective uid */
+#define AT_GID		13	/* real gid */
+#define AT_EGID		14	/* effective gid */
+#define AT_PLATFORM	15	/* string identifying CPU for optimizations */
+#define AT_HWCAP  	16	/* arch dependent hints at CPU capabilities */
+#define AT_CLKTCK 	17	/* frequency at which times() increments */
+/* 18..22 = ? */
+#define AT_SECURE 	23	/* secure mode boolean */
+
+/* Program header permission flags */
+#define PF_X            0x1
+#define PF_W            0x2
+#define PF_R            0x4
+
+/* Section header types */
+#define SHT_NULL        0
+#define SHT_PROGBITS    1
+#define SHT_SYMTAB      2
+#define SHT_STRTAB      3
+#define SHT_RELA        4
+#define SHT_HASH        5
+#define SHT_DYNAMIC     6
+#define SHT_NOTE        7
+#define SHT_NOBITS      8
+#define SHT_REL         9
+#define SHT_SHLIB       10
+#define SHT_DYNSYM      11
+#define SHT_NUM         12
+#define SHT_LOPROC      0x70000000
+#define SHT_HIPROC      0x7fffffff
+#define SHT_LOUSER      0x80000000
+#define SHT_HIUSER      0xffffffff
+
+/* Section header flags */
+#define SHF_WRITE            (1 << 0)   /* Writable */
+#define SHF_ALLOC            (1 << 1)   /* Occupies memory during execution */
+#define SHF_EXECINSTR        (1 << 2)   /* Executable */
+#define SHF_MERGE            (1 << 4)   /* Might be merged */
+#define SHF_STRINGS          (1 << 5)   /* Contains nul-terminated strings */
+#define SHF_INFO_LINK        (1 << 6)   /* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER       (1 << 7)   /* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)   /* Non-standard OS specific handling
+                                           required */
+#define SHF_GROUP            (1 << 9)   /* Section is member of a group.  */
+#define SHF_TLS              (1 << 10)  /* Section hold thread-local data.  */
+
+/* Special section numbers */
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+
+/* Lenght of magic at the start of a file */
+#define EI_NIDENT	16
+
+/* Magic number constants... */
+#define EI_MAG0         0	/* e_ident[] indexes */
+#define EI_MAG1         1
+#define EI_MAG2         2
+#define EI_MAG3         3
+#define EI_CLASS        4
+#define EI_DATA         5
+#define EI_VERSION      6
+#define EI_OSABI        7
+#define EI_PAD          8
+
+#define ELFMAG0         0x7f	/* EI_MAG */
+#define ELFMAG1         'E'
+#define ELFMAG2         'L'
+#define ELFMAG3         'F'
+#define ELFMAG          "\177ELF"
+#define SELFMAG         4
+
+#define ELFCLASSNONE    0	/* EI_CLASS */
+#define ELFCLASS32      1
+#define ELFCLASS64      2
+#define ELFCLASSNUM     3
+
+#define ELFDATANONE     0	/* e_ident[EI_DATA] */
+#define ELFDATA2LSB     1
+#define ELFDATA2MSB     2
+
+#define EV_NONE         0	/* e_version, EI_VERSION */
+#define EV_CURRENT      1
+#define EV_NUM          2
+
+#define ELFOSABI_NONE   0
+#define ELFOSABI_LINUX  3
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Symbol types */
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+
+/* Symbol visibilities */
+#define STV_DEFAULT     0               /* Default symbol visibility rules */
+#define STV_INTERNAL    1               /* Processor specific hidden class */
+#define STV_HIDDEN      2               /* Sym unavailable in other modules */
+#define STV_PROTECTED   3               /* Not preemptible, not exported */
+
+#endif /* OUTPUT_ELFCOMMON_H */
diff --git a/float.h b/output/nulldbg.c
similarity index 62%
copy from float.h
copy to output/nulldbg.c
index 6f94cc68..54a45802 100644
--- a/float.h
+++ b/output/nulldbg.c
@@ -31,25 +31,59 @@
  *
  * ----------------------------------------------------------------------- */
 
-/* 
- * float.h   header file for the floating-point constant module of
- *	     the Netwide Assembler
- */
-
-#ifndef NASM_FLOAT_H
-#define NASM_FLOAT_H
-
 #include "nasm.h"
+#include "nasmlib.h"
 
-enum float_round {
-    FLOAT_RC_NEAR,
-    FLOAT_RC_ZERO,
-    FLOAT_RC_DOWN,
-    FLOAT_RC_UP,
-};
+void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
+{
+	(void)of;
+	(void)id;
+	(void)fp;
+	(void)error;
+}
+void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
+{
+	(void)filename;
+	(void)linenumber;
+	(void)segto;
+}
+void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
+                         int is_global, char *special)
+{
+	(void)name;
+	(void)segment;
+	(void)offset;
+	(void)is_global;
+	(void)special;
+}
+void null_debug_routine(const char *directive, const char *params)
+{
+	(void)directive;
+	(void)params;
+}
+void null_debug_typevalue(int32_t type)
+{
+	(void)type;
+}
+void null_debug_output(int type, void *param)
+{
+	(void)type;
+	(void)param;
+}
+void null_debug_cleanup(void)
+{
+}
 
-int float_const(const char *string, int sign, uint8_t *result, int bytes,
-                efunc error);
-int float_option(const char *option);
+struct dfmt null_debug_form = {
+    "Null debug format",
+    "null",
+    null_debug_init,
+    null_debug_linenum,
+    null_debug_deflabel,
+    null_debug_routine,
+    null_debug_typevalue,
+    null_debug_output,
+    null_debug_cleanup
+};
 
-#endif
+struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };
diff --git a/output/outbin.mac b/output/outaout.mac
similarity index 97%
copy from output/outbin.mac
copy to output/outaout.mac
index be7fefae..cd23852d 100644
--- a/output/outbin.mac
+++ b/output/outaout.mac
@@ -31,10 +31,7 @@
 ;;
 ;; --------------------------------------------------------------------------
 
-OUT: bin
+OUT: aout aoutb
 %define __SECT__ [section .text]
-%imacro org 1+.nolist
-[org %1]
-%endmacro
 %macro __NASM_CDecl__ 1
 %endmacro
diff --git a/output/outbin.mac b/output/outas86.mac
similarity index 97%
copy from output/outbin.mac
copy to output/outas86.mac
index be7fefae..f0bd2e41 100644
--- a/output/outbin.mac
+++ b/output/outas86.mac
@@ -31,10 +31,7 @@
 ;;
 ;; --------------------------------------------------------------------------
 
-OUT: bin
+OUT: as86
 %define __SECT__ [section .text]
-%imacro org 1+.nolist
-[org %1]
-%endmacro
 %macro __NASM_CDecl__ 1
 %endmacro
diff --git a/tables.h b/output/outelf.c
similarity index 61%
copy from tables.h
copy to output/outelf.c
index 284f0465..a8654403 100644
--- a/tables.h
+++ b/output/outelf.c
@@ -32,37 +32,36 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * tables.h
- *
- * Declarations for auto-generated tables
+ * Common code for outelf32 and outelf64
  */
 
-#ifndef TABLES_H
-#define TABLES_H
-
 #include "compiler.h"
-#include <inttypes.h>
-#include "insnsi.h"		/* For enum opcode */
 
-/* --- From standard.mac via macros.pl: --- */
-
-/* macros.c */
-extern const unsigned char nasm_stdmac[];
-extern const unsigned char * const nasm_stdmac_after_tasm;
-const unsigned char *nasm_stdmac_find_package(const char *);
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
 
-/* --- From insns.dat via insns.pl: --- */
+#include "nasm.h"
+#include "output/outform.h"
 
-/* insnsn.c */
-extern const char * const nasm_insn_names[];
+#include "output/elfcommon.h"
+#include "output/dwarf.h"
+#include "output/outelf.h"
 
-/* --- From regs.dat via regs.pl: --- */
+#if defined(OF_ELF32) || defined(OF_ELF64)
 
-/* regs.c */
-extern const char * const nasm_reg_names[];
-/* regflags.c */
-extern const int32_t nasm_reg_flags[];
-/* regvals.c */
-extern const int nasm_regvals[];
+const struct elf_known_section elf_known_sections[] = {
+    { ".text",    SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR,     16 },
+    { ".rodata",  SHT_PROGBITS, SHF_ALLOC,                    4 },
+    { ".lrodata", SHT_PROGBITS, SHF_ALLOC,                    4 },
+    { ".data",    SHT_PROGBITS, SHF_ALLOC|SHF_WRITE,          4 },
+    { ".ldata",   SHT_PROGBITS, SHF_ALLOC|SHF_WRITE,          4 },
+    { ".bss",     SHT_NOBITS,   SHF_ALLOC|SHF_WRITE,          4 },
+    { ".lbss",    SHT_NOBITS,   SHF_ALLOC|SHF_WRITE,          4 },
+    { ".tdata",   SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS,  4 },
+    { ".tbss",    SHT_NOBITS,   SHF_ALLOC|SHF_WRITE|SHF_TLS,  4 },
+    { ".comment", SHT_PROGBITS, 0,                            1 },
+    { NULL,       SHT_PROGBITS, SHF_ALLOC,                    1 } /* default */
+};
 
-#endif /* TABLES_H */
+#endif /* defined(OF_ELF32) || defined(OF_ELF64) */
diff --git a/output/outelf.h b/output/outelf.h
new file mode 100644
index 00000000..a5bbd563
--- /dev/null
+++ b/output/outelf.h
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Internal definitions common to outelf32 and outelf64
+ */
+#ifndef OUTPUT_OUTELF_H
+#define OUTPUT_OUTELF_H
+
+#define SYM_GLOBAL 0x10
+
+#define GLOBAL_TEMP_BASE  0x40000000 /* bigger than any sane symbol index */
+
+#define SEG_ALIGN 16            /* alignment of sections in file */
+#define SEG_ALIGN_1 (SEG_ALIGN-1)
+
+/* this stuff is needed for the stabs debugging format */
+#define N_SO 0x64               /* ID for main source file */
+#define N_SOL 0x84              /* ID for sub-source file */
+#define N_BINCL 0x82
+#define N_EINCL 0xA2
+#define N_SLINE 0x44
+#define TY_STABSSYMLIN 0x40     /* ouch */
+
+/* this stuff is needed for the dwarf debugging format */
+#define TY_DEBUGSYMLIN 0x40     /* internal call to debug_out */
+
+/* Known sections with nonstandard defaults */
+struct elf_known_section {
+    const char *name;		/* Name of section */
+    int type;			/* Section type (SHT_) */
+    uint32_t flags;		/* Section flags (SHF_) */
+    uint32_t align;		/* Section alignment */
+};
+extern const struct elf_known_section elf_known_sections[];
+
+/*
+ * Special ELF sections (after the real sections but before debugging ones)
+ */
+#define sec_shstrtab		(nsects + 1)
+#define sec_symtab		(nsects + 2)
+#define sec_strtab		(nsects + 3)
+#define sec_numspecial  	3
+
+/*
+ * Debugging ELF sections (last in the file)
+ */
+
+/* stabs */
+#define sec_stab		(nsections-3)
+#define sec_stabstr		(nsections-2)
+#define sec_rel_stab		(nsections-1)
+
+/* dwarf */
+#define sec_debug_aranges	(nsections-10)
+#define sec_rela_debug_aranges	(nsections-9)
+#define sec_debug_pubnames	(nsections-8)
+#define sec_debug_info		(nsections-7)
+#define sec_rela_debug_info	(nsections-6)
+#define sec_debug_abbrev	(nsections-5)
+#define sec_debug_line		(nsections-4)
+#define sec_rela_debug_line	(nsections-3)
+#define sec_debug_frame		(nsections-2)
+#define sec_debug_loc		(nsections-1)
+
+#endif /* OUTPUT_OUTELF_H */
diff --git a/rdoff/rdx.c b/output/outform.c
similarity index 52%
copy from rdoff/rdx.c
copy to output/outform.c
index 240ab592..f8cdca87 100644
--- a/rdoff/rdx.c
+++ b/output/outform.c
@@ -32,57 +32,70 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * rdx.c	RDOFF Object File loader program
+ * outform.c	manages a list of output formats, and associates
+ *		them with their relevant drivers. Also has a
+ *		routine to find the correct driver given a name
+ *		for it
  */
 
-/* note: most of the actual work of this program is done by the modules
-   "rdfload.c", which loads and relocates the object file, and by "rdoff.c",
-   which contains general purpose routines to manipulate RDOFF object
-   files. You can use these files in your own program to load RDOFF objects
-   and execute the code in them in a similar way to what is shown here. */
-
 #include "compiler.h"
 
 #include <stdio.h>
-#include <stdlib.h>
-
-#include "rdfload.h"
-#include "symtab.h"
+#include <string.h>
+#include <inttypes.h>
 
-typedef int (*main_fn) (int, char **);  /* Main function prototype */
+#define BUILD_DRIVERS_ARRAY
+#include "output/outform.h"
 
-int main(int argc, char **argv)
-{
-    rdfmodule *m;
-    main_fn code;
-    symtabEnt *s;
+static int ndrivers = 0;
 
-    if (argc < 2) {
-        puts("usage: rdx <rdoff-executable> [params]\n");
-        exit(255);
-    }
+struct ofmt *ofmt_find(char *name)
+{                               /* find driver */
+    int i;
 
-    m = rdfload(argv[1]);
+    for (i = 0; i < ndrivers; i++)
+        if (!strcmp(name, drivers[i]->shortname))
+            return drivers[i];
 
-    if (!m) {
-        rdfperror("rdx", argv[1]);
-        exit(255);
+    return NULL;
+}
+struct dfmt *dfmt_find(struct ofmt *ofmt, char *name)
+{                               /* find driver */
+    struct dfmt **dfmt = ofmt->debug_formats;
+    while (*dfmt) {
+        if (!strcmp(name, (*dfmt)->shortname))
+            return (*dfmt);
+        dfmt++;
     }
+    return NULL;
+}
 
-    rdf_relocate(m);            /* in this instance, the default relocation
-                                   values will work fine, but they may need changing
-                                   in other cases... */
-
-    s = symtabFind(m->symtab, "_main");
-    if (!s) {
-        fprintf(stderr, "rdx: could not find symbol '_main' in '%s'\n",
-                argv[1]);
-        exit(255);
+void ofmt_list(struct ofmt *deffmt, FILE * fp)
+{
+    int i;
+    for (i = 0; i < ndrivers; i++)
+        fprintf(fp, "  %c %-10s%s\n",
+                drivers[i] == deffmt ? '*' : ' ',
+                drivers[i]->shortname, drivers[i]->fullname);
+}
+void dfmt_list(struct ofmt *ofmt, FILE * fp)
+{
+    struct dfmt **drivers = ofmt->debug_formats;
+    while (*drivers) {
+        fprintf(fp, "  %c %-10s%s\n",
+                drivers[0] == ofmt->current_dfmt ? '*' : ' ',
+                drivers[0]->shortname, drivers[0]->fullname);
+        drivers++;
     }
+}
+struct ofmt *ofmt_register(efunc error)
+{
+    for (ndrivers = 0; drivers[ndrivers] != NULL; ndrivers++) ;
 
-    code = (main_fn)(size_t) s->offset;
-
-    argv++, argc--;             /* remove 'rdx' from command line */
+    if (ndrivers == 0) {
+        error(ERR_PANIC | ERR_NOFILE,
+              "No output drivers given at compile time");
+    }
 
-    return code(argc, argv);    /* execute */
+    return (&OF_DEFAULT);
 }
diff --git a/output/outform.h b/output/outform.h
new file mode 100644
index 00000000..3dfbc9c7
--- /dev/null
+++ b/output/outform.h
@@ -0,0 +1,344 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outform.h    header file for binding output format drivers to the
+ *              remainder of the code in the Netwide Assembler
+ */
+
+/*
+ * This header file allows configuration of which output formats
+ * get compiled into the NASM binary. You can configure by defining
+ * various preprocessor symbols beginning with "OF_", either on the
+ * compiler command line or at the top of this file.
+ *
+ * OF_ONLY                -- only include specified object formats
+ * OF_name                -- ensure that output format 'name' is included
+ * OF_NO_name             -- remove output format 'name'
+ * OF_DOS                 -- ensure that 'obj', 'bin' & 'win32' are included.
+ * OF_UNIX                -- ensure that 'aout', 'aoutb', 'coff', 'elf32' 'elf64' are in.
+ * OF_OTHERS              -- ensure that 'bin', 'as86' & 'rdf' are in.
+ * OF_ALL                 -- ensure that all formats are included.
+ *                           note that this doesn't include 'dbg', which is
+ *                           only really useful if you're doing development
+ *                           work on NASM. Define OF_DBG if you want this.
+ *
+ * OF_DEFAULT=of_name     -- ensure that 'name' is the default format.
+ *
+ * eg: -DOF_UNIX -DOF_ELF32 -DOF_DEFAULT=of_elf32 would be a suitable config
+ * for an average linux system.
+ *
+ * Default config = -DOF_ALL -DOF_DEFAULT=of_bin
+ *
+ * You probably only want to set these options while compiling 'nasm.c'. */
+
+#ifndef NASM_OUTFORM_H
+#define NASM_OUTFORM_H
+
+#include "nasm.h"
+
+/* -------------- USER MODIFIABLE PART ---------------- */
+
+/*
+ * Insert #defines here in accordance with the configuration
+ * instructions above.
+ *
+ * E.g.
+ *
+ * #define OF_ONLY
+ * #define OF_OBJ
+ * #define OF_BIN
+ *
+ * for a 16-bit DOS assembler with no extraneous formats.
+ */
+
+/* ------------ END USER MODIFIABLE PART -------------- */
+
+/* ====configurable info begins here==== */
+/* formats configurable:
+ * bin,obj,elf32,elf64,aout,aoutb,coff,win32,as86,rdf2,macho */
+
+/* process options... */
+
+#ifndef OF_ONLY
+#ifndef OF_ALL
+#define OF_ALL                  /* default is to have all formats */
+#endif
+#endif
+
+#ifdef OF_ALL                   /* set all formats on... */
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_OBJ
+#define OF_OBJ
+#endif
+#ifndef OF_ELF32
+#define OF_ELF32
+#endif
+#ifndef OF_ELF64
+#define OF_ELF64
+#endif
+#ifndef OF_COFF
+#define OF_COFF
+#endif
+#ifndef OF_AOUT
+#define OF_AOUT
+#endif
+#ifndef OF_AOUTB
+#define OF_AOUTB
+#endif
+#ifndef OF_WIN32
+#define OF_WIN32
+#endif
+#ifndef OF_WIN64
+#define OF_WIN64
+#endif
+#ifndef OF_AS86
+#define OF_AS86
+#endif
+#ifndef OF_RDF2
+#define OF_RDF2
+#endif
+#ifndef OF_IEEE
+#define OF_IEEE
+#endif
+#ifndef OF_MACHO32
+#define OF_MACHO32
+#endif
+#ifndef OF_MACHO64
+#define OF_MACHO64
+#endif
+#ifndef OF_DBG
+#define OF_DBG
+#endif
+#endif                          /* OF_ALL */
+
+/* turn on groups of formats specified.... */
+#ifdef OF_DOS
+#ifndef OF_OBJ
+#define OF_OBJ
+#endif
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_COFF
+#define OF_COFF			/* COFF is used by DJGPP */
+#endif
+#ifndef OF_WIN32
+#define OF_WIN32
+#endif
+#ifndef OF_WIN64
+#define OF_WIN64
+#endif
+#endif
+
+#ifdef OF_UNIX
+#ifndef OF_AOUT
+#define OF_AOUT
+#endif
+#ifndef OF_AOUTB
+#define OF_AOUTB
+#endif
+#ifndef OF_COFF
+#define OF_COFF
+#endif
+#ifndef OF_ELF32
+#define OF_ELF32
+#endif
+#ifndef OF_ELF64
+#define OF_ELF64
+#endif
+#endif
+
+#ifdef OF_OTHERS
+#ifndef OF_BIN
+#define OF_BIN
+#endif
+#ifndef OF_AS86
+#define OF_AS86
+#endif
+#ifndef OF_RDF2
+#define OF_RDF2
+#endif
+#ifndef OF_IEEE
+#define OF_IEEE
+#endif
+#ifndef OF_MACHO32
+#define OF_MACHO32
+#endif
+#ifndef OF_MACHO64
+#define OF_MACHO64
+#endif
+#endif
+
+/* finally... override any format specifically specified to be off */
+#ifdef OF_NO_BIN
+#undef OF_BIN
+#endif
+#ifdef OF_NO_OBJ
+#undef OF_OBJ
+#endif
+#ifdef OF_NO_ELF32
+#undef OF_ELF32
+#endif
+#ifdef OF_NO_ELF64
+#undef OF_ELF64
+#endif
+#ifdef OF_NO_AOUT
+#undef OF_AOUT
+#endif
+#ifdef OF_NO_AOUTB
+#undef OF_AOUTB
+#endif
+#ifdef OF_NO_COFF
+#undef OF_COFF
+#endif
+#ifdef OF_NO_WIN32
+#undef OF_WIN32
+#endif
+#ifdef OF_NO_WIN64
+#undef OF_WIN64
+#endif
+#ifdef OF_NO_AS86
+#undef OF_AS86
+#endif
+#ifdef OF_NO_RDF2
+#undef OF_RDF
+#endif
+#ifdef OF_NO_IEEE
+#undef OF_IEEE
+#endif
+#ifdef OF_NO_MACHO32
+#undef OF_MACHO32
+#endif
+#ifdef OF_NO_MACHO64
+#undef OF_MACHO64
+#endif
+#ifdef OF_NO_DBG
+#undef OF_DBG
+#endif
+
+#ifndef OF_DEFAULT
+#define OF_DEFAULT of_bin
+#endif
+
+#ifdef BUILD_DRIVERS_ARRAY      /* only if included from outform.c */
+
+/* pull in the externs for the different formats, then make the *drivers
+ * array based on the above defines */
+
+extern struct ofmt of_bin;
+extern struct ofmt of_ith;
+extern struct ofmt of_srec;
+extern struct ofmt of_aout;
+extern struct ofmt of_aoutb;
+extern struct ofmt of_coff;
+extern struct ofmt of_elf32;
+extern struct ofmt of_elf;
+extern struct ofmt of_elf64;
+extern struct ofmt of_as86;
+extern struct ofmt of_obj;
+extern struct ofmt of_win32;
+extern struct ofmt of_win64;
+extern struct ofmt of_rdf2;
+extern struct ofmt of_ieee;
+extern struct ofmt of_macho32;
+extern struct ofmt of_macho;
+extern struct ofmt of_macho64;
+extern struct ofmt of_dbg;
+
+struct ofmt *drivers[] = {
+#ifdef OF_BIN
+    &of_bin,
+    &of_ith,
+    &of_srec,
+#endif
+#ifdef OF_AOUT
+    &of_aout,
+#endif
+#ifdef OF_AOUTB
+    &of_aoutb,
+#endif
+#ifdef OF_COFF
+    &of_coff,
+#endif
+#ifdef OF_ELF32
+    &of_elf32,
+    &of_elf,
+#endif
+#ifdef OF_ELF64
+    &of_elf64,
+#endif
+#ifdef OF_AS86
+    &of_as86,
+#endif
+#ifdef OF_OBJ
+    &of_obj,
+#endif
+#ifdef OF_WIN32
+    &of_win32,
+#endif
+#ifdef OF_WIN64
+    &of_win64,
+#endif
+#ifdef OF_RDF2
+    &of_rdf2,
+#endif
+#ifdef OF_IEEE
+    &of_ieee,
+#endif
+#ifdef OF_MACHO32
+    &of_macho32,
+	&of_macho,
+#endif
+#ifdef OF_MACHO64
+    &of_macho64,
+#endif
+#ifdef OF_DBG
+    &of_dbg,
+#endif
+
+    NULL
+};
+
+#endif                          /* BUILD_DRIVERS_ARRAY */
+
+struct ofmt *ofmt_find(char *);
+struct dfmt *dfmt_find(struct ofmt *, char *);
+void ofmt_list(struct ofmt *, FILE *);
+void dfmt_list(struct ofmt *ofmt, FILE * fp);
+struct ofmt *ofmt_register(efunc error);
+extern struct dfmt null_debug_form;
+
+#endif                          /* NASM_OUTFORM_H */
diff --git a/quote.h b/output/outlib.c
similarity index 84%
copy from quote.h
copy to output/outlib.c
index 13089cb7..56ac6cd5 100644
--- a/quote.h
+++ b/output/outlib.c
@@ -31,14 +31,26 @@
  *
  * ----------------------------------------------------------------------- */
 
-#ifndef NASM_QUOTE_H
-#define NASM_QUOTE_H
+/*
+ * libout.c
+ *
+ * Common routines for the output backends.
+ */
 
 #include "compiler.h"
+#include "nasm.h"
+#include "output/outlib.h"
 
-char *nasm_quote(char *str, size_t len);
-size_t nasm_unquote(char *str, char **endptr);
-char *nasm_skip_string(char *str);
-
-#endif /* NASM_QUOTE_H */
-
+uint64_t realsize(enum out_type type, uint64_t size)
+{
+    switch (type) {
+    case OUT_REL2ADR:
+	return 2;
+    case OUT_REL4ADR:
+	return 4;
+    case OUT_REL8ADR:
+	return 8;
+    default:
+	return size;
+    }
+}
diff --git a/float.h b/output/outlib.h
similarity index 71%
copy from float.h
copy to output/outlib.h
index 6f94cc68..964da5c8 100644
--- a/float.h
+++ b/output/outlib.h
@@ -31,25 +31,25 @@
  *
  * ----------------------------------------------------------------------- */
 
-/* 
- * float.h   header file for the floating-point constant module of
- *	     the Netwide Assembler
- */
-
-#ifndef NASM_FLOAT_H
-#define NASM_FLOAT_H
+#ifndef NASM_OUTLIB_H
+#define NASM_OUTLIB_H
 
 #include "nasm.h"
 
-enum float_round {
-    FLOAT_RC_NEAR,
-    FLOAT_RC_ZERO,
-    FLOAT_RC_DOWN,
-    FLOAT_RC_UP,
-};
+uint64_t realsize(enum out_type type, uint64_t size);
+
+/* Do-nothing versions of all the debug routines */
+struct ofmt;
+void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error);
+void null_debug_linenum(const char *filename, int32_t linenumber,
+			int32_t segto);
+void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
+                         int is_global, char *special);
+void null_debug_routine(const char *directive, const char *params);
+void null_debug_typevalue(int32_t type);
+void null_debug_output(int type, void *param);
+void null_debug_cleanup(void);
+extern struct dfmt *null_debug_arr[2];
 
-int float_const(const char *string, int sign, uint8_t *result, int bytes,
-                efunc error);
-int float_option(const char *option);
+#endif /* NASM_OUTLIB_H */
 
-#endif
diff --git a/output/outbin.mac b/output/outmacho.mac
similarity index 97%
copy from output/outbin.mac
copy to output/outmacho.mac
index be7fefae..f1cdf180 100644
--- a/output/outbin.mac
+++ b/output/outmacho.mac
@@ -31,10 +31,7 @@
 ;;
 ;; --------------------------------------------------------------------------
 
-OUT: bin
+OUT: macho macho32 macho64
 %define __SECT__ [section .text]
-%imacro org 1+.nolist
-[org %1]
-%endmacro
 %macro __NASM_CDecl__ 1
 %endmacro
diff --git a/output/outmacho32.c b/output/outmacho32.c
new file mode 100644
index 00000000..c9e43659
--- /dev/null
+++ b/output/outmacho32.c
@@ -0,0 +1,1382 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outmacho.c	output routines for the Netwide Assembler to produce
+ *		NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
+ */
+
+/* Most of this file is, like Mach-O itself, based on a.out. For more
+ * guidelines see outaout.c.  */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
+#include "output/outform.h"
+#include "output/outlib.h"
+
+#if defined(OF_MACHO32)
+
+/* Mach-O in-file header structure sizes */
+#define MACHO_HEADER_SIZE	(28)
+#define MACHO_SEGCMD_SIZE	(56)
+#define MACHO_SECTCMD_SIZE	(68)
+#define MACHO_SYMCMD_SIZE	(24)
+#define MACHO_NLIST_SIZE	(12)
+#define MACHO_RELINFO_SIZE	(8)
+
+/* Mach-O file header values */
+#define	MH_MAGIC		(0xfeedface)
+#define CPU_TYPE_I386		(7)     /* x86 platform */
+#define	CPU_SUBTYPE_I386_ALL	(3)     /* all-x86 compatible */
+#define	MH_OBJECT		(0x1)   /* object file */
+
+#define	LC_SEGMENT		(0x1)   /* segment load command */
+#define LC_SYMTAB		(0x2)   /* symbol table load command */
+
+#define	VM_PROT_NONE	(0x00)
+#define VM_PROT_READ	(0x01)
+#define VM_PROT_WRITE	(0x02)
+#define VM_PROT_EXECUTE	(0x04)
+
+#define VM_PROT_DEFAULT	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
+#define VM_PROT_ALL	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
+
+struct section {
+    /* nasm internal data */
+    struct section *next;
+    struct SAA *data;
+    int32_t index;
+    struct reloc *relocs;
+    int align;
+
+    /* data that goes into the file */
+    char sectname[16];          /* what this section is called */
+    char segname[16];           /* segment this section will be in */
+    uint32_t addr;         /* in-memory address (subject to alignment) */
+    uint32_t size;         /* in-memory and -file size  */
+    uint32_t nreloc;       /* relocation entry count */
+    uint32_t flags;        /* type and attributes (masked) */
+};
+
+#define SECTION_TYPE	0x000000ff      /* section type mask */
+
+#define	S_REGULAR	(0x0)   /* standard section */
+#define	S_ZEROFILL	(0x1)   /* zerofill, in-memory only */
+
+#define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* system setable attributes */
+#define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* section contains some
+                                                   machine instructions */
+#define S_ATTR_EXT_RELOC         0x00000200     /* section has external
+                                                   relocation entries */
+#define S_ATTR_LOC_RELOC         0x00000100     /* section has local
+                                                   relocation entries */
+
+
+static struct sectmap {
+    const char *nasmsect;
+    const char *segname;
+    const char *sectname;
+    const int32_t flags;
+} sectmap[] = {
+    {".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS},
+    {".data", "__DATA", "__data", S_REGULAR},
+    {".rodata", "__DATA", "__const", S_REGULAR},
+    {".bss", "__DATA", "__bss", S_ZEROFILL},
+    {NULL, NULL, NULL, 0}
+};
+
+struct reloc {
+    /* nasm internal data */
+    struct reloc *next;
+
+    /* data that goes into the file */
+    int32_t addr;                  /* op's offset in section */
+    unsigned int snum:24,       /* contains symbol index if
+				** ext otherwise in-file
+				** section number */
+	pcrel:1,                /* relative relocation */
+	length:2,               /* 0=byte, 1=word, 2=int32_t */
+	ext:1,                  /* external symbol referenced */
+	type:4;                 /* reloc type, 0 for us */
+};
+
+#define	R_ABS		0       /* absolute relocation */
+#define R_SCATTERED	0x80000000      /* reloc entry is scattered if
+					** highest bit == 1 */
+
+struct symbol {
+    /* nasm internal data */
+    struct symbol *next;	/* next symbol in the list */
+    char *name;			/* name of this symbol */
+    int32_t initial_snum;		/* symbol number used above in
+				   reloc */
+    int32_t snum;			/* true snum for reloc */
+
+    /* data that goes into the file */
+    int32_t strx;                  /* string table index */
+    uint8_t type;         /* symbol type */
+    uint8_t sect;         /* NO_SECT or section number */
+    int16_t desc;                 /* for stab debugging, 0 for us */
+    uint32_t value;        /* offset of symbol in section */
+};
+
+/* symbol type bits */
+#define	N_EXT	0x01            /* global or external symbol */
+
+#define	N_UNDF	0x0             /* undefined symbol | n_sect == */
+#define	N_ABS	0x2             /* absolute symbol  |  NO_SECT */
+#define	N_SECT	0xe             /* defined symbol, n_sect holds
+				** section number */
+
+#define	N_TYPE	0x0e            /* type bit mask */
+
+#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
+
+/* special section number values */
+#define	NO_SECT		0       /* no section, invalid */
+#define MAX_SECT	255     /* maximum number of sections */
+
+static struct section *sects, **sectstail;
+static struct symbol *syms, **symstail;
+static uint32_t nsyms;
+
+/* These variables are set by macho_layout_symbols() to organize
+   the symbol table and string table in order the dynamic linker
+   expects.  They are then used in macho_write() to put out the
+   symbols and strings in that order.
+
+   The order of the symbol table is:
+     local symbols
+     defined external symbols (sorted by name)
+     undefined external symbols (sorted by name)
+
+   The order of the string table is:
+     strings for external symbols
+     strings for local symbols
+ */
+static uint32_t ilocalsym = 0;
+static uint32_t iextdefsym = 0;
+static uint32_t iundefsym = 0;
+static uint32_t nlocalsym;
+static uint32_t nextdefsym;
+static uint32_t nundefsym;
+static struct symbol **extdefsyms = NULL;
+static struct symbol **undefsyms = NULL;
+
+static struct RAA *extsyms;
+static struct SAA *strs;
+static uint32_t strslen;
+
+static FILE *machofp;
+static efunc error;
+static evalfunc evaluate;
+
+extern struct ofmt of_macho;
+
+/* Global file information. This should be cleaned up into either
+   a structure or as function arguments.  */
+uint32_t head_ncmds = 0;
+uint32_t head_sizeofcmds = 0;
+uint32_t seg_filesize = 0;
+uint32_t seg_vmsize = 0;
+uint32_t seg_nsects = 0;
+uint32_t rel_padcnt = 0;
+
+
+#define xstrncpy(xdst, xsrc)						\
+    memset(xdst, '\0', sizeof(xdst));	/* zero out whole buffer */	\
+    strncpy(xdst, xsrc, sizeof(xdst));	/* copy over string */		\
+    xdst[sizeof(xdst) - 1] = '\0';      /* proper null-termination */
+
+#define align(x, y)							\
+    (((x) + (y) - 1) & ~((y) - 1))      /* align x to multiple of y */
+
+#define alignint32_t(x)							\
+    align(x, sizeof(int32_t))      /* align x to int32_t boundary */
+
+static void debug_reloc (struct reloc *);
+static void debug_section_relocs (struct section *) _unused;
+
+static int exact_log2 (uint32_t align)
+{
+    if (align == 0) {
+	return 0;
+    } else if (align & (align-1)) {
+	return -1;		/* Not a power of 2 */
+    } else {
+#ifdef HAVE_GNUC_4
+	return __builtin_ctzl (align);
+#else
+	uint32_t result = 0;
+
+	/* We know exactly one bit is set at this point. */
+	if (align & 0xffff0000)
+	    result |= 16;
+	if (align & 0xff00ff00)
+	    result |= 8;
+	if (align & 0xf0f0f0f0)
+	    result |= 4;
+	if (align & 0xcccccccc)
+	    result |= 2;
+	if (align & 0xaaaaaaaa)
+	    result |= 1;
+
+	return result;
+#endif
+    }
+}
+
+static struct section *get_section_by_name(const char *segname,
+                                           const char *sectname)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+            break;
+
+    return s;
+}
+
+static struct section *get_section_by_index(const int32_t index)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (index == s->index)
+            break;
+
+    return s;
+}
+
+static int32_t get_section_index_by_name(const char *segname,
+                                      const char *sectname)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+            return s->index;
+
+    return -1;
+}
+
+static char *get_section_name_by_index(const int32_t index)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (index == s->index)
+            return s->sectname;
+
+    return NULL;
+}
+
+static uint8_t get_section_fileindex_by_index(const int32_t index)
+{
+    struct section *s;
+    uint8_t i = 1;
+
+    for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
+        if (index == s->index)
+            return i;
+
+    if (i == MAX_SECT)
+        error(ERR_WARNING,
+              "too many sections (>255) - clipped by fileindex");
+
+    return NO_SECT;
+}
+
+static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
+                       evalfunc eval)
+{
+    char zero = 0;
+
+    machofp = fp;
+    error = errfunc;
+    evaluate = eval;
+
+    (void)ldef;                 /* placate optimisers */
+
+    sects = NULL;
+    sectstail = §s;
+
+    syms = NULL;
+    symstail = &syms;
+    nsyms = 0;
+    nlocalsym = 0;
+    nextdefsym = 0;
+    nundefsym = 0;
+
+    extsyms = raa_init();
+    strs = saa_init(1L);
+
+    /* string table starts with a zero byte - don't ask why */
+    saa_wbytes(strs, &zero, sizeof(char));
+    strslen = 1;
+}
+
+static int macho_setinfo(enum geninfo type, char **val)
+{
+    (void)type;
+    (void)val;
+    return 0;
+}
+
+static void sect_write(struct section *sect,
+                       const uint8_t *data, uint32_t len)
+{
+    saa_wbytes(sect->data, data, len);
+    sect->size += len;
+}
+
+static void add_reloc(struct section *sect, int32_t section,
+                      int pcrel, int bytes)
+{
+    struct reloc *r;
+    int32_t fi;
+
+    /* NeXT as puts relocs in reversed order (address-wise) into the
+     ** files, so we do the same, doesn't seem to make much of a
+     ** difference either way */
+    r = nasm_malloc(sizeof(struct reloc));
+    r->next = sect->relocs;
+    sect->relocs = r;
+
+    /* the current end of the section will be the symbol's address for
+     ** now, might have to be fixed by macho_fixup_relocs() later on. make
+     ** sure we don't make the symbol scattered by setting the highest
+     ** bit by accident */
+    r->addr = sect->size & ~R_SCATTERED;
+    r->ext = 0;
+    r->pcrel = pcrel;
+
+    /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */
+    r->length = bytes >> 1;
+
+    /* vanilla relocation (GENERIC_RELOC_VANILLA) */
+    r->type = 0;
+
+    if (section == NO_SEG) {
+        /* absolute local symbol if no section index given */
+        r->snum = R_ABS;
+    } else {
+        fi = get_section_fileindex_by_index(section);
+
+        if (fi == NO_SECT) {
+            /* external symbol if no section with that index known,
+             ** symbol number was saved in macho_symdef() */
+            r->snum = raa_read(extsyms, section);
+            r->ext = 1;
+        } else {
+            /* local symbol in section fi */
+            r->snum = fi;
+        }
+    }
+
+    ++sect->nreloc;
+}
+
+static void macho_output(int32_t secto, const void *data,
+			 enum out_type type, uint64_t size,
+                         int32_t section, int32_t wrt)
+{
+    struct section *s, *sbss;
+    int32_t addr;
+    uint8_t mydata[4], *p;
+
+    if (wrt != NO_SEG) {
+        wrt = NO_SEG;
+        error(ERR_NONFATAL, "WRT not supported by Mach-O output format");
+        /* continue to do _something_ */
+    }
+
+    if (secto == NO_SEG) {
+        if (type != OUT_RESERVE)
+            error(ERR_NONFATAL, "attempt to assemble code in "
+                  "[ABSOLUTE] space");
+
+        return;
+    }
+
+    s = get_section_by_index(secto);
+
+    if (s == NULL) {
+        error(ERR_WARNING, "attempt to assemble code in"
+              " section %d: defaulting to `.text'", secto);
+        s = get_section_by_name("__TEXT", "__text");
+
+        /* should never happen */
+        if (s == NULL)
+            error(ERR_PANIC, "text section not found");
+    }
+
+    sbss = get_section_by_name("__DATA", "__bss");
+
+    if (s == sbss && type != OUT_RESERVE) {
+        error(ERR_WARNING, "attempt to initialize memory in the"
+              " BSS section: ignored");
+        s->size += realsize(type, size);
+        return;
+    }
+
+    switch (type) {
+    case OUT_RESERVE:
+        if (s != sbss) {
+            error(ERR_WARNING, "uninitialized space declared in"
+                  " %s section: zeroing",
+                  get_section_name_by_index(secto));
+
+            sect_write(s, NULL, size);
+        } else
+            s->size += size;
+
+        break;
+
+    case OUT_RAWDATA:
+        if (section != NO_SEG)
+            error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
+
+        sect_write(s, data, size);
+        break;
+
+    case OUT_ADDRESS:
+        addr = *(int64_t *)data;
+
+        if (section != NO_SEG) {
+            if (section % 2) {
+                error(ERR_NONFATAL, "Mach-O format does not support"
+                      " section base references");
+            } else
+                add_reloc(s, section, 0, size);
+        }
+
+        p = mydata;
+	WRITEADDR(p, addr, size);
+        sect_write(s, mydata, size);
+        break;
+
+    case OUT_REL2ADR:
+        if (section == secto)
+            error(ERR_PANIC, "intra-section OUT_REL2ADR");
+
+        if (section != NO_SEG && section % 2) {
+            error(ERR_NONFATAL, "Mach-O format does not support"
+                  " section base references");
+        } else
+            add_reloc(s, section, 1, 2);
+
+        p = mydata;
+        WRITESHORT(p, *(int32_t *)data - (size + s->size));
+        sect_write(s, mydata, 2L);
+        break;
+
+    case OUT_REL4ADR:
+        if (section == secto)
+            error(ERR_PANIC, "intra-section OUT_REL4ADR");
+
+        if (section != NO_SEG && section % 2) {
+            error(ERR_NONFATAL, "Mach-O format does not support"
+                  " section base references");
+        } else
+            add_reloc(s, section, 1, 4);
+
+        p = mydata;
+        WRITELONG(p, *(int32_t *)data - (size + s->size));
+        sect_write(s, mydata, 4L);
+        break;
+
+    default:
+        error(ERR_PANIC, "unknown output type?");
+        break;
+    }
+}
+
+static int32_t macho_section(char *name, int pass, int *bits)
+{
+    int32_t index, originalIndex;
+    char *sectionAttributes;
+    struct sectmap *sm;
+    struct section *s;
+
+    (void)pass;
+
+    /* Default to 32 bits. */
+    if (!name) {
+        *bits = 32;
+        name = ".text";
+        sectionAttributes = NULL;
+    } else {
+        sectionAttributes = name;
+        name = nasm_strsep(&sectionAttributes, " \t");
+    }
+
+    for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
+        /* make lookup into section name translation table */
+        if (!strcmp(name, sm->nasmsect)) {
+            char *currentAttribute;
+
+            /* try to find section with that name */
+            originalIndex = index = get_section_index_by_name(sm->segname,
+                                                              sm->sectname);
+
+            /* create it if it doesn't exist yet */
+            if (index == -1) {
+                s = *sectstail = nasm_malloc(sizeof(struct section));
+                s->next = NULL;
+                sectstail = &s->next;
+
+                s->data = saa_init(1L);
+                s->index = seg_alloc();
+                s->relocs = NULL;
+                s->align = -1;
+
+                xstrncpy(s->segname, sm->segname);
+                xstrncpy(s->sectname, sm->sectname);
+                s->size = 0;
+                s->nreloc = 0;
+                s->flags = sm->flags;
+
+                index = s->index;
+            } else {
+                s = get_section_by_index(index);
+            }
+
+            while ((NULL != sectionAttributes)
+                   && (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
+                if (0 != *currentAttribute) {
+                    if (!nasm_strnicmp("align=", currentAttribute, 6)) {
+                        char *end;
+                        int newAlignment, value;
+
+                        value = strtoul(currentAttribute + 6, (char**)&end, 0);
+                        newAlignment = exact_log2(value);
+
+                        if (0 != *end) {
+                            error(ERR_PANIC,
+                                  "unknown or missing alignment value \"%s\" "
+                                      "specified for section \"%s\"",
+                                  currentAttribute + 6,
+                                  name);
+                            return NO_SEG;
+                        } else if (0 > newAlignment) {
+                            error(ERR_PANIC,
+                                  "alignment of %d (for section \"%s\") is not "
+                                      "a power of two",
+                                  value,
+                                  name);
+                            return NO_SEG;
+                        }
+
+                        if ((-1 != originalIndex)
+                            && (s->align != newAlignment)
+                           && (s->align != -1)) {
+                            error(ERR_PANIC,
+                                  "section \"%s\" has already been specified "
+                                      "with alignment %d, conflicts with new "
+                                      "alignment of %d",
+                            name,
+                            (1 << s->align),
+                            value);
+                            return NO_SEG;
+                        }
+
+                        s->align = newAlignment;
+                    } else if (!nasm_stricmp("data", currentAttribute)) {
+                        /* Do nothing; 'data' is implicit */
+                    } else {
+                        error(ERR_PANIC,
+                              "unknown section attribute %s for section %s",
+                              currentAttribute,
+                              name);
+                        return NO_SEG;
+                    }
+                }
+            }
+
+            return index;
+        }
+    }
+
+    error(ERR_PANIC, "invalid section name %s", name);
+    return NO_SEG;
+}
+
+static void macho_symdef(char *name, int32_t section, int64_t offset,
+                         int is_global, char *special)
+{
+    struct symbol *sym;
+
+    if (special) {
+        error(ERR_NONFATAL, "The Mach-O output format does "
+              "not support any special symbol types");
+        return;
+    }
+
+    if (is_global == 3) {
+        error(ERR_NONFATAL, "The Mach-O format does not "
+              "(yet) support forward reference fixups.");
+        return;
+    }
+
+    sym = *symstail = nasm_malloc(sizeof(struct symbol));
+    sym->next = NULL;
+    symstail = &sym->next;
+
+    sym->name = name;
+    sym->strx = strslen;
+    sym->type = 0;
+    sym->desc = 0;
+    sym->value = offset;
+    sym->initial_snum = -1;
+
+    /* external and common symbols get N_EXT */
+    if (is_global != 0)
+        sym->type |= N_EXT;
+
+    if (section == NO_SEG) {
+        /* symbols in no section get absolute */
+        sym->type |= N_ABS;
+        sym->sect = NO_SECT;
+    } else {
+        sym->type |= N_SECT;
+
+        /* get the in-file index of the section the symbol was defined in */
+        sym->sect = get_section_fileindex_by_index(section);
+
+        if (sym->sect == NO_SECT) {
+            /* remember symbol number of references to external
+             ** symbols, this works because every external symbol gets
+             ** its own section number allocated internally by nasm and
+             ** can so be used as a key */
+	    extsyms = raa_write(extsyms, section, nsyms);
+	    sym->initial_snum = nsyms;
+
+            switch (is_global) {
+            case 1:
+            case 2:
+                /* there isn't actually a difference between global
+                 ** and common symbols, both even have their size in
+                 ** sym->value */
+                sym->type = N_EXT;
+                break;
+
+            default:
+                /* give an error on unfound section if it's not an
+                 ** external or common symbol (assemble_file() does a
+                 ** seg_alloc() on every call for them) */
+                error(ERR_PANIC, "in-file index for section %d not found",
+                      section);
+            }
+        }
+    }
+
+    ++nsyms;
+}
+
+static int32_t macho_segbase(int32_t section)
+{
+    return section;
+}
+
+static int macho_directive(char *directive, char *value, int pass)
+{
+    (void)directive;
+    (void)value;
+    (void)pass;
+    return 0;
+}
+
+static void macho_filename(char *inname, char *outname, efunc error)
+{
+    standard_extension(inname, outname, ".o", error);
+}
+
+extern macros_t macho_stdmac[];
+
+/* Comparison function for qsort symbol layout.  */
+static int layout_compare (const struct symbol **s1,
+			   const struct symbol **s2)
+{
+    return (strcmp ((*s1)->name, (*s2)->name));
+}
+
+/* The native assembler does a few things in a similar function
+
+	* Remove temporary labels
+	* Sort symbols according to local, external, undefined (by name)
+	* Order the string table
+
+   We do not remove temporary labels right now.
+
+   numsyms is the total number of symbols we have. strtabsize is the
+   number entries in the string table.  */
+
+static void macho_layout_symbols (uint32_t *numsyms,
+				  uint32_t *strtabsize)
+{
+    struct symbol *sym, **symp;
+    uint32_t i,j;
+
+    *numsyms = 0;
+    *strtabsize = sizeof (char);
+
+    symp = &syms;
+
+    while ((sym = *symp)) {
+	/* Undefined symbols are now external.  */
+	if (sym->type == N_UNDF)
+	    sym->type |= N_EXT;
+
+	if ((sym->type & N_EXT) == 0) {
+	    sym->snum = *numsyms;
+	    *numsyms = *numsyms + 1;
+	    nlocalsym++;
+	}
+	else {
+	    if ((sym->type & N_TYPE) != N_UNDF)
+		nextdefsym++;
+	    else
+		nundefsym++;
+
+	    /* If we handle debug info we'll want
+	       to check for it here instead of just
+	       adding the symbol to the string table.  */
+	    sym->strx = *strtabsize;
+	    saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
+	    *strtabsize += strlen(sym->name) + 1;
+	}
+	symp = &(sym->next);
+    }
+
+    /* Next, sort the symbols.  Most of this code is a direct translation from
+       the Apple cctools symbol layout. We need to keep compatibility with that.  */
+    /* Set the indexes for symbol groups into the symbol table */
+    ilocalsym = 0;
+    iextdefsym = nlocalsym;
+    iundefsym = nlocalsym + nextdefsym;
+
+    /* allocate arrays for sorting externals by name */
+    extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
+    undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
+
+    i = 0;
+    j = 0;
+
+    symp = &syms;
+
+    while ((sym = *symp)) {
+
+	if((sym->type & N_EXT) == 0) {
+	    sym->strx = *strtabsize;
+	    saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
+	    *strtabsize += strlen(sym->name) + 1;
+	}
+	else {
+	    if((sym->type & N_TYPE) != N_UNDF)
+		extdefsyms[i++] = sym;
+	    else
+		undefsyms[j++] = sym;
+	}
+	symp = &(sym->next);
+    }
+
+    qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
+	  (int (*)(const void *, const void *))layout_compare);
+    qsort(undefsyms, nundefsym, sizeof(struct symbol *),
+	  (int (*)(const void *, const void *))layout_compare);
+
+    for(i = 0; i < nextdefsym; i++) {
+	extdefsyms[i]->snum = *numsyms;
+	*numsyms += 1;
+    }
+    for(j = 0; j < nundefsym; j++) {
+	undefsyms[j]->snum = *numsyms;
+	*numsyms += 1;
+    }
+}
+
+/* Calculate some values we'll need for writing later.  */
+
+static void macho_calculate_sizes (void)
+{
+    struct section *s;
+
+    /* count sections and calculate in-memory and in-file offsets */
+    for (s = sects; s != NULL; s = s->next) {
+        uint32_t pad = 0;
+
+        /* zerofill sections aren't actually written to the file */
+        if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
+            seg_filesize += s->size;
+
+        /* recalculate segment address based on alignment and vm size */
+        s->addr = seg_vmsize;
+        /* we need section alignment to calculate final section address */
+        if (s->align == -1)
+            s->align = DEFAULT_SECTION_ALIGNMENT;
+        if(s->align) {
+            uint32_t newaddr = align(s->addr, 1 << s->align);
+            pad = newaddr - s->addr;
+            s->addr = newaddr;
+        }
+
+        seg_vmsize += s->size + pad;
+        ++seg_nsects;
+    }
+
+    /* calculate size of all headers, load commands and sections to
+    ** get a pointer to the start of all the raw data */
+    if (seg_nsects > 0) {
+        ++head_ncmds;
+        head_sizeofcmds +=
+            MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE;
+    }
+
+    if (nsyms > 0) {
+	++head_ncmds;
+	head_sizeofcmds += MACHO_SYMCMD_SIZE;
+    }
+}
+
+/* Write out the header information for the file.  */
+
+static void macho_write_header (void)
+{
+    fwriteint32_t(MH_MAGIC, machofp);	/* magic */
+    fwriteint32_t(CPU_TYPE_I386, machofp);	/* CPU type */
+    fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp);	/* CPU subtype */
+    fwriteint32_t(MH_OBJECT, machofp);	/* Mach-O file type */
+    fwriteint32_t(head_ncmds, machofp);	/* number of load commands */
+    fwriteint32_t(head_sizeofcmds, machofp);	/* size of load commands */
+    fwriteint32_t(0, machofp);	/* no flags */
+}
+
+/* Write out the segment load command at offset.  */
+
+static uint32_t macho_write_segment (uint32_t offset)
+{
+    uint32_t rel_base = alignint32_t (offset + seg_filesize);
+    uint32_t s_reloff = 0;
+    struct section *s;
+
+    fwriteint32_t(LC_SEGMENT, machofp);        /* cmd == LC_SEGMENT */
+
+    /* size of load command including section load commands */
+    fwriteint32_t(MACHO_SEGCMD_SIZE + seg_nsects *
+	       MACHO_SECTCMD_SIZE, machofp);
+
+    /* in an MH_OBJECT file all sections are in one unnamed (name
+    ** all zeros) segment */
+    fwritezero(16, machofp);
+    fwriteint32_t(0, machofp); /* in-memory offset */
+    fwriteint32_t(seg_vmsize, machofp);        /* in-memory size */
+    fwriteint32_t(offset, machofp);    /* in-file offset to data */
+    fwriteint32_t(seg_filesize, machofp);      /* in-file size */
+    fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* maximum vm protection */
+    fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* initial vm protection */
+    fwriteint32_t(seg_nsects, machofp);        /* number of sections */
+    fwriteint32_t(0, machofp); /* no flags */
+
+    /* emit section headers */
+    for (s = sects; s != NULL; s = s->next) {
+	fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
+	fwrite(s->segname, sizeof(s->segname), 1, machofp);
+	fwriteint32_t(s->addr, machofp);
+	fwriteint32_t(s->size, machofp);
+
+	/* dummy data for zerofill sections or proper values */
+	if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
+	    fwriteint32_t(offset, machofp);
+	    /* Write out section alignment, as a power of two.
+	       e.g. 32-bit word alignment would be 2 (2^^2 = 4).  */
+	    if (s->align == -1)
+		s->align = DEFAULT_SECTION_ALIGNMENT;
+	    fwriteint32_t(s->align, machofp);
+	    /* To be compatible with cctools as we emit
+	       a zero reloff if we have no relocations.  */
+	    fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp);
+	    fwriteint32_t(s->nreloc, machofp);
+
+	    offset += s->size;
+	    s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
+	} else {
+	    fwriteint32_t(0, machofp);
+	    fwriteint32_t(0, machofp);
+	    fwriteint32_t(0, machofp);
+	    fwriteint32_t(0, machofp);
+	}
+
+	fwriteint32_t(s->flags, machofp);      /* flags */
+	fwriteint32_t(0, machofp);     /* reserved */
+	fwriteint32_t(0, machofp);     /* reserved */
+    }
+
+    rel_padcnt = rel_base - offset;
+    offset = rel_base + s_reloff;
+
+    return offset;
+}
+
+/* For a given chain of relocs r, write out the entire relocation
+   chain to the object file.  */
+
+static void macho_write_relocs (struct reloc *r)
+{
+    while (r) {
+	uint32_t word2;
+
+	fwriteint32_t(r->addr, machofp); /* reloc offset */
+
+	word2 = r->snum;
+	word2 |= r->pcrel << 24;
+	word2 |= r->length << 25;
+	word2 |= r->ext << 27;
+	word2 |= r->type << 28;
+	fwriteint32_t(word2, machofp); /* reloc data */
+
+	r = r->next;
+    }
+}
+
+/* Write out the section data.  */
+static void macho_write_section (void)
+{
+    struct section *s, *s2;
+    struct reloc *r;
+    uint8_t fi, *p, *q, blk[4];
+    int32_t l;
+
+    for (s = sects; s != NULL; s = s->next) {
+	if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
+	    continue;
+
+	/* no padding needs to be done to the sections */
+
+	/* Like a.out Mach-O references things in the data or bss
+	 * sections by addresses which are actually relative to the
+	 * start of the _text_ section, in the _file_. See outaout.c
+	 * for more information. */
+	saa_rewind(s->data);
+	for (r = s->relocs; r != NULL; r = r->next) {
+	    saa_fread(s->data, r->addr, blk, (int32_t)r->length << 1);
+	    p = q = blk;
+	    l = *p++;
+
+	    /* get offset based on relocation type */
+	    if (r->length > 0) {
+		l += ((int32_t)*p++) << 8;
+
+		if (r->length == 2) {
+		    l += ((int32_t)*p++) << 16;
+		    l += ((int32_t)*p++) << 24;
+		}
+	    }
+
+	    /* If the relocation is internal add to the current section
+	       offset. Otherwise the only value we need is the symbol
+	       offset which we already have. The linker takes care
+	       of the rest of the address.  */
+	    if (!r->ext) {
+            /* generate final address by section address and offset */
+		    for (s2 = sects, fi = 1;
+		        s2 != NULL; s2 = s2->next, fi++) {
+		        if (fi == r->snum) {
+		            l += s2->addr;
+		            break;
+		        }
+		    }
+	    }
+
+	    /* write new offset back */
+	    if (r->length == 2)
+		WRITELONG(q, l);
+	    else if (r->length == 1)
+		WRITESHORT(q, l);
+	    else
+		*q++ = l & 0xFF;
+
+	    saa_fwrite(s->data, r->addr, blk, (int32_t)r->length << 1);
+	}
+
+	/* dump the section data to file */
+	saa_fpwrite(s->data, machofp);
+    }
+
+    /* pad last section up to reloc entries on int32_t boundary */
+    fwritezero(rel_padcnt, machofp);
+
+    /* emit relocation entries */
+    for (s = sects; s != NULL; s = s->next)
+	macho_write_relocs (s->relocs);
+}
+
+/* Write out the symbol table. We should already have sorted this
+   before now.  */
+static void macho_write_symtab (void)
+{
+    struct symbol *sym;
+    struct section *s;
+    int32_t fi;
+    uint32_t i;
+
+    /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
+
+    for (sym = syms; sym != NULL; sym = sym->next) {
+	if ((sym->type & N_EXT) == 0) {
+	    fwriteint32_t(sym->strx, machofp);		/* string table entry number */
+	    fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	    fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	    fwriteint16_t(sym->desc, machofp);	/* description */
+
+	    /* Fix up the symbol value now that we know the final section
+	       sizes.  */
+	    if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+		for (s = sects, fi = 1;
+		     s != NULL && fi < sym->sect; s = s->next, ++fi)
+		    sym->value += s->size;
+	    }
+
+	    fwriteint32_t(sym->value, machofp);	/* value (i.e. offset) */
+	}
+    }
+
+    for (i = 0; i < nextdefsym; i++) {
+	sym = extdefsyms[i];
+	fwriteint32_t(sym->strx, machofp);
+	fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	fwriteint16_t(sym->desc, machofp);	/* description */
+
+	/* Fix up the symbol value now that we know the final section
+	   sizes.  */
+	if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+	    for (s = sects, fi = 1;
+		 s != NULL && fi < sym->sect; s = s->next, ++fi)
+		sym->value += s->size;
+	}
+
+	fwriteint32_t(sym->value, machofp);	/* value (i.e. offset) */
+    }
+
+     for (i = 0; i < nundefsym; i++) {
+	 sym = undefsyms[i];
+	 fwriteint32_t(sym->strx, machofp);
+	 fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	 fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	 fwriteint16_t(sym->desc, machofp);	/* description */
+
+	 /* Fix up the symbol value now that we know the final section
+	    sizes.  */
+	 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+	     for (s = sects, fi = 1;
+		  s != NULL && fi < sym->sect; s = s->next, ++fi)
+		 sym->value += s->size;
+	 }
+
+	 fwriteint32_t(sym->value, machofp);	/* value (i.e. offset) */
+     }
+}
+
+/* Fixup the snum in the relocation entries, we should be
+   doing this only for externally undefined symbols. */
+static void macho_fixup_relocs (struct reloc *r)
+{
+    struct symbol *sym;
+    uint32_t i;
+
+    while (r != NULL) {
+	if (r->ext) {
+	    for (i = 0; i < nundefsym; i++) {
+		sym = undefsyms[i];
+		if (sym->initial_snum == r->snum) {
+		    r->snum = sym->snum;
+                   break;
+		}
+	    }
+	}
+	r = r->next;
+    }
+}
+
+/* Write out the object file.  */
+
+static void macho_write (void)
+{
+    uint32_t offset = 0;
+
+    /* mach-o object file structure:
+    **
+    ** mach header
+    **  uint32_t magic
+    **  int   cpu type
+    **  int   cpu subtype
+    **  uint32_t mach file type
+    **  uint32_t number of load commands
+    **  uint32_t size of all load commands
+    **   (includes section struct size of segment command)
+    **  uint32_t flags
+    **
+    ** segment command
+    **  uint32_t command type == LC_SEGMENT
+    **  uint32_t size of load command
+    **   (including section load commands)
+    **  char[16] segment name
+    **  uint32_t in-memory offset
+    **  uint32_t in-memory size
+    **  uint32_t in-file offset to data area
+    **  uint32_t in-file size
+    **   (in-memory size excluding zerofill sections)
+    **  int   maximum vm protection
+    **  int   initial vm protection
+    **  uint32_t number of sections
+    **  uint32_t flags
+    **
+    ** section commands
+    **   char[16] section name
+    **   char[16] segment name
+    **   uint32_t in-memory offset
+    **   uint32_t in-memory size
+    **   uint32_t in-file offset
+    **   uint32_t alignment
+    **    (irrelevant in MH_OBJECT)
+    **   uint32_t in-file offset of relocation entires
+    **   uint32_t number of relocations
+    **   uint32_t flags
+    **   uint32_t reserved
+    **   uint32_t reserved
+    **
+    ** symbol table command
+    **  uint32_t command type == LC_SYMTAB
+    **  uint32_t size of load command
+    **  uint32_t symbol table offset
+    **  uint32_t number of symbol table entries
+    **  uint32_t string table offset
+    **  uint32_t string table size
+    **
+    ** raw section data
+    **
+    ** padding to int32_t boundary
+    **
+    ** relocation data (struct reloc)
+    ** int32_t offset
+    **  uint data (symbolnum, pcrel, length, extern, type)
+    **
+    ** symbol table data (struct nlist)
+    **  int32_t  string table entry number
+    **  uint8_t type
+    **   (extern, absolute, defined in section)
+    **  uint8_t section
+    **   (0 for global symbols, section number of definition (>= 1, <=
+    **   254) for local symbols, size of variable for common symbols
+    **   [type == extern])
+    **  int16_t description
+    **   (for stab debugging format)
+    **  uint32_t value (i.e. file offset) of symbol or stab offset
+    **
+    ** string table data
+    **  list of null-terminated strings
+    */
+
+    /* Emit the Mach-O header.  */
+    macho_write_header();
+
+    offset = MACHO_HEADER_SIZE + head_sizeofcmds;
+
+    /* emit the segment load command */
+    if (seg_nsects > 0)
+	offset = macho_write_segment (offset);
+    else
+        error(ERR_WARNING, "no sections?");
+
+    if (nsyms > 0) {
+        /* write out symbol command */
+        fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
+        fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
+        fwriteint32_t(offset, machofp);    /* symbol table offset */
+        fwriteint32_t(nsyms, machofp);     /* number of symbol
+                                         ** table entries */
+
+        offset += nsyms * MACHO_NLIST_SIZE;
+        fwriteint32_t(offset, machofp);    /* string table offset */
+        fwriteint32_t(strslen, machofp);   /* string table size */
+    }
+
+    /* emit section data */
+    if (seg_nsects > 0)
+	macho_write_section ();
+
+    /* emit symbol table if we have symbols */
+    if (nsyms > 0)
+	macho_write_symtab ();
+
+    /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */
+
+    /* emit string table */
+    saa_fpwrite(strs, machofp);
+}
+/* We do quite a bit here, starting with finalizing all of the data
+   for the object file, writing, and then freeing all of the data from
+   the file.  */
+
+static void macho_cleanup(int debuginfo)
+{
+    struct section *s;
+    struct reloc *r;
+    struct symbol *sym;
+
+    (void)debuginfo;
+
+    /* Sort all symbols.  */
+    macho_layout_symbols (&nsyms, &strslen);
+
+    /* Fixup relocation entries */
+    for (s = sects; s != NULL; s = s->next) {
+	macho_fixup_relocs (s->relocs);
+    }
+
+    /* First calculate and finalize needed values.  */
+    macho_calculate_sizes();
+    macho_write();
+
+    /* done - yay! */
+    fclose(machofp);
+
+    /* free up everything */
+    while (sects->next) {
+        s = sects;
+        sects = sects->next;
+
+        saa_free(s->data);
+        while (s->relocs != NULL) {
+            r = s->relocs;
+            s->relocs = s->relocs->next;
+            nasm_free(r);
+        }
+
+        nasm_free(s);
+    }
+
+    saa_free(strs);
+    raa_free(extsyms);
+
+    if (syms) {
+    while (syms->next) {
+       sym = syms;
+       syms = syms->next;
+
+       nasm_free (sym);
+    }
+}
+}
+
+/* Debugging routines.  */
+static void debug_reloc (struct reloc *r)
+{
+    fprintf (stdout, "reloc:\n");
+    fprintf (stdout, "\taddr: %"PRId32"\n", r->addr);
+    fprintf (stdout, "\tsnum: %d\n", r->snum);
+    fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
+    fprintf (stdout, "\tlength: %d\n", r->length);
+    fprintf (stdout, "\text: %d\n", r->ext);
+    fprintf (stdout, "\ttype: %d\n", r->type);
+}
+
+static void debug_section_relocs (struct section *s)
+{
+    struct reloc *r = s->relocs;
+
+    fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
+
+    while (r != NULL) {
+	debug_reloc (r);
+	r = r->next;
+    }
+}
+
+struct ofmt of_macho32 = {
+    "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
+    "macho32",
+    0,
+    null_debug_arr,
+    &null_debug_form,
+    macho_stdmac,
+    macho_init,
+    macho_setinfo,
+    macho_output,
+    macho_symdef,
+    macho_section,
+    macho_segbase,
+    macho_directive,
+    macho_filename,
+    macho_cleanup
+};
+
+struct ofmt of_macho = {
+    "MACHO (short name for MACHO32)",
+    "macho",
+    0,
+    null_debug_arr,
+    &null_debug_form,
+    macho_stdmac,
+    macho_init,
+    macho_setinfo,
+    macho_output,
+    macho_symdef,
+    macho_section,
+    macho_segbase,
+    macho_directive,
+    macho_filename,
+    macho_cleanup
+};
+
+#endif
+
+/*
+ * Local Variables:
+ * mode:c
+ * c-basic-offset:4
+ * End:
+ *
+ * end of file */
diff --git a/output/outmacho64.c b/output/outmacho64.c
new file mode 100644
index 00000000..0a8b77b9
--- /dev/null
+++ b/output/outmacho64.c
@@ -0,0 +1,1528 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * outmacho64.c	output routines for the Netwide Assembler to produce
+ *		NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
+ */
+
+/* Most of this file is, like Mach-O itself, based on a.out. For more
+ * guidelines see outaout.c.  */
+
+#include "compiler.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
+#include "output/outform.h"
+#include "output/outlib.h"
+
+#if defined(OF_MACHO64)
+
+/* Mach-O in-file header structure sizes */
+#define MACHO_HEADER64_SIZE		(32)
+#define MACHO_SEGCMD64_SIZE		(72)
+#define MACHO_SECTCMD64_SIZE	(80)
+#define MACHO_SYMCMD_SIZE		(24)
+#define MACHO_NLIST64_SIZE		(16)
+#define MACHO_RELINFO64_SIZE	(8)
+
+/* Mach-O file header values */
+#define	MH_MAGIC_64		(0xfeedfacf)
+#define CPU_TYPE_X86_64 (0x01000007) /* x86-64 platform */
+#define	CPU_SUBTYPE_I386_ALL	(3)     /* all-x86 compatible */
+#define	MH_OBJECT		(0x1)   /* object file */
+
+#define	LC_SEGMENT_64	(0x19)  /* segment load command */
+#define LC_SYMTAB		(0x2)   /* symbol table load command */
+
+#define	VM_PROT_NONE	(0x00)
+#define VM_PROT_READ	(0x01)
+#define VM_PROT_WRITE	(0x02)
+#define VM_PROT_EXECUTE	(0x04)
+
+#define VM_PROT_DEFAULT	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
+#define VM_PROT_ALL	(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
+
+struct section {
+    /* nasm internal data */
+    struct section *next;
+    struct SAA *data;
+    int32_t index;
+    struct reloc *relocs;
+    int align;
+
+    /* data that goes into the file */
+    char sectname[16];          /* what this section is called */
+    char segname[16];           /* segment this section will be in */
+    uint64_t addr;         /* in-memory address (subject to alignment) */
+    uint64_t size;         /* in-memory and -file size  */
+    uint32_t nreloc;       /* relocation entry count */
+    uint32_t flags;        /* type and attributes (masked) */
+	uint32_t extreloc;     /* external relocations */
+};
+
+#define SECTION_TYPE	0x000000ff      /* section type mask */
+
+#define	S_REGULAR	(0x0)   /* standard section */
+#define	S_ZEROFILL	(0x1)   /* zerofill, in-memory only */
+
+#define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* system setable attributes */
+#define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* section contains some
+                                                   machine instructions */
+#define S_ATTR_EXT_RELOC         0x00000200     /* section has external
+                                                   relocation entries */
+#define S_ATTR_LOC_RELOC         0x00000100     /* section has local
+                                                   relocation entries */
+#define S_ATTR_PURE_INSTRUCTIONS 0x80000000		/* section uses pure
+												   machine instructions */
+
+static struct sectmap {
+    const char *nasmsect;
+    const char *segname;
+    const char *sectname;
+    const int32_t flags;
+} sectmap[] = {
+    {".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
+    {".data", "__DATA", "__data", S_REGULAR},
+    {".rodata", "__DATA", "__const", S_REGULAR},
+    {".bss", "__DATA", "__bss", S_ZEROFILL},
+    {NULL, NULL, NULL, 0}
+};
+
+struct reloc {
+    /* nasm internal data */
+    struct reloc *next;
+
+    /* data that goes into the file */
+    int32_t addr;                  /* op's offset in section */
+    uint32_t snum:24,       /* contains symbol index if
+				** ext otherwise in-file
+				** section number */
+	pcrel:1,                /* relative relocation */
+	length:2,               /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
+	ext:1,                  /* external symbol referenced */
+	type:4;                 /* reloc type */
+};
+
+#define	R_ABS		0       /* absolute relocation */
+#define R_SCATTERED	0x80000000      /* reloc entry is scattered if
+					** highest bit == 1 */
+
+struct symbol {
+    /* nasm internal data */
+    struct symbol *next;	/* next symbol in the list */
+    char *name;			/* name of this symbol */
+    int32_t initial_snum;		/* symbol number used above in
+				   reloc */
+    int32_t snum;			/* true snum for reloc */
+
+    /* data that goes into the file */
+    uint32_t strx;                  /* string table index */
+    uint8_t type;         /* symbol type */
+    uint8_t sect;         /* NO_SECT or section number */
+    uint16_t desc;                 /* for stab debugging, 0 for us */
+    uint64_t value;        /* offset of symbol in section */
+};
+
+/* symbol type bits */
+#define	N_EXT	0x01            /* global or external symbol */
+
+#define	N_UNDF	0x0             /* undefined symbol | n_sect == */
+#define	N_ABS	0x2             /* absolute symbol  |  NO_SECT */
+#define	N_SECT	0xe             /* defined symbol, n_sect holds
+				** section number */
+
+#define	N_TYPE	0x0e            /* type bit mask */
+
+#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
+
+/* special section number values */
+#define	NO_SECT		0       /* no section, invalid */
+#define MAX_SECT	255     /* maximum number of sections */
+
+static struct section *sects, **sectstail;
+static struct symbol *syms, **symstail;
+static uint32_t nsyms;
+
+/* These variables are set by macho_layout_symbols() to organize
+   the symbol table and string table in order the dynamic linker
+   expects.  They are then used in macho_write() to put out the
+   symbols and strings in that order.
+
+   The order of the symbol table is:
+     local symbols
+     defined external symbols (sorted by name)
+     undefined external symbols (sorted by name)
+
+   The order of the string table is:
+     strings for external symbols
+     strings for local symbols
+ */
+static uint32_t ilocalsym = 0;
+static uint32_t iextdefsym = 0;
+static uint32_t iundefsym = 0;
+static uint32_t nlocalsym;
+static uint32_t nextdefsym;
+static uint32_t nundefsym;
+static struct symbol **extdefsyms = NULL;
+static struct symbol **undefsyms = NULL;
+
+static struct RAA *extsyms;
+static struct SAA *strs;
+static uint32_t strslen;
+
+static FILE *machofp;
+static efunc error;
+static evalfunc evaluate;
+
+extern struct ofmt of_macho64;
+
+/* Global file information. This should be cleaned up into either
+   a structure or as function arguments.  */
+uint32_t head_ncmds64 = 0;
+uint32_t head_sizeofcmds64 = 0;
+uint64_t seg_filesize64 = 0;
+uint64_t seg_vmsize64 = 0;
+uint32_t seg_nsects64 = 0;
+uint64_t rel_padcnt64 = 0;
+
+
+#define xstrncpy(xdst, xsrc)						\
+    memset(xdst, '\0', sizeof(xdst));	/* zero out whole buffer */	\
+    strncpy(xdst, xsrc, sizeof(xdst));	/* copy over string */		\
+    xdst[sizeof(xdst) - 1] = '\0';      /* proper null-termination */
+
+#define align(x, y)							\
+    (((x) + (y) - 1) & ~((y) - 1))      /* align x to multiple of y */
+
+#define alignint32_t(x)							\
+    align(x, sizeof(int32_t))      /* align x to int32_t boundary */
+
+#define alignint64_t(x)							\
+    align(x, sizeof(int64_t))      /* align x to int64_t boundary */
+
+static void debug_reloc (struct reloc *);
+static void debug_section_relocs (struct section *) _unused;
+
+static int exact_log2 (uint32_t align)
+{
+    if (align == 0) {
+	return 0;
+    } else if (align & (align-1)) {
+	return -1;		/* Not a power of 2 */
+    } else {
+#ifdef HAVE_GNUC_4
+	return __builtin_ctzl (align);
+#else
+	uint32_t result = 0;
+
+	/* We know exactly one bit is set at this point. */
+	if (align & 0xffff0000)
+	    result |= 16;
+	if (align & 0xff00ff00)
+	    result |= 8;
+	if (align & 0xf0f0f0f0)
+	    result |= 4;
+	if (align & 0xcccccccc)
+	    result |= 2;
+	if (align & 0xaaaaaaaa)
+	    result |= 1;
+
+	return result;
+#endif
+    }
+}
+
+static struct section *get_section_by_name(const char *segname,
+                                           const char *sectname)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+            break;
+
+    return s;
+}
+
+static struct section *get_section_by_index(const int32_t index)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (index == s->index)
+            break;
+
+    return s;
+}
+
+static int32_t get_section_index_by_name(const char *segname,
+                                      const char *sectname)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname))
+            return s->index;
+
+    return -1;
+}
+
+static char *get_section_name_by_index(const int32_t index)
+{
+    struct section *s;
+
+    for (s = sects; s != NULL; s = s->next)
+        if (index == s->index)
+            return s->sectname;
+
+    return NULL;
+}
+
+static uint8_t get_section_fileindex_by_index(const int32_t index)
+{
+    struct section *s;
+    uint8_t i = 1;
+
+    for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i)
+        if (index == s->index)
+            return i;
+
+    if (i == MAX_SECT)
+        error(ERR_WARNING,
+              "too many sections (>255) - clipped by fileindex");
+
+    return NO_SECT;
+}
+
+static struct symbol *get_closest_section_symbol_by_offset(uint8_t fileindex, int64_t offset)
+{
+	struct symbol *sym;
+
+	for (sym = syms; sym != NULL; sym = sym->next) {
+		if ((sym->sect != NO_SECT) &&
+			(sym->sect == fileindex) &&
+			((int64_t)sym->value >= offset))
+				return sym;
+	}
+
+	return NULL;
+}
+
+
+/*
+ * Special section numbers which are used to define Mach-O special
+ * symbols, which can be used with WRT to provide PIC relocation
+ * types.
+ */
+static int32_t macho_gotpcrel_sect;
+
+static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef,
+                       evalfunc eval)
+{
+    char zero = 0;
+
+	maxbits = 64;
+    machofp = fp;
+    error = errfunc;
+    evaluate = eval;
+
+    (void)ldef;                 /* placate optimizers */
+
+    sects = NULL;
+    sectstail = §s;
+
+    syms = NULL;
+    symstail = &syms;
+    nsyms = 0;
+    nlocalsym = 0;
+    nextdefsym = 0;
+    nundefsym = 0;
+
+    extsyms = raa_init();
+    strs = saa_init(1L);
+
+    /* string table starts with a zero byte - don't ask why */
+    saa_wbytes(strs, &zero, sizeof(char));
+    strslen = 1;
+	
+	/* add special symbol for ..gotpcrel */
+	macho_gotpcrel_sect = seg_alloc();
+	macho_gotpcrel_sect ++;
+//	ldef("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false, &of_macho64, error);
+}
+
+static int macho_setinfo(enum geninfo type, char **val)
+{
+    (void)type;
+    (void)val;
+    return 0;
+}
+
+static void sect_write(struct section *sect,
+                       const uint8_t *data, uint32_t len)
+{
+    saa_wbytes(sect->data, data, len);
+    sect->size += len;
+}
+
+static int32_t add_reloc(struct section *sect, int32_t section,
+                      int pcrel, int bytes, int64_t reloff)
+{
+    struct reloc *r;
+	struct symbol *sym;
+    int32_t fi;
+	int32_t adjustment = 0;
+
+    /* NeXT as puts relocs in reversed order (address-wise) into the
+     ** files, so we do the same, doesn't seem to make much of a
+     ** difference either way */
+    r = nasm_malloc(sizeof(struct reloc));
+    r->next = sect->relocs;
+    sect->relocs = r;
+
+    /* the current end of the section will be the symbol's address for
+     ** now, might have to be fixed by macho_fixup_relocs() later on. make
+     ** sure we don't make the symbol scattered by setting the highest
+     ** bit by accident */
+    r->addr = sect->size & ~R_SCATTERED;
+    r->ext = 1;
+    r->pcrel = (pcrel ? 1 : 0);
+
+    /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
+	switch(bytes){
+		case 1:
+			r->length = 0;
+			break;
+		case 2:
+			r->length = 1;
+			break;
+		case 4:
+			r->length = 2;
+			break;
+		case 8:
+			r->length = 3;
+			break;
+		default:
+			break;
+	}
+
+    /* set default relocation values */
+    r->type = 0;					// X86_64_RELOC_UNSIGNED
+	r->snum = R_ABS;				// Absolute Symbol (indicates no relocation)
+
+	/* absolute relocation */
+	if (pcrel == 0) {
+	
+		/* intra-section */
+		if (section == NO_SEG) {
+			// r->snum = R_ABS;		// Set above
+			
+		/* inter-section */
+		} else {
+			fi = get_section_fileindex_by_index(section);
+			
+			/* external */
+			if (fi == NO_SECT) {
+				r->snum = raa_read(extsyms, section);
+				
+			/* local */
+			} else {
+				sym = get_closest_section_symbol_by_offset(fi, reloff);
+				r->snum = sym->initial_snum;
+				adjustment = sym->value;
+			}
+		}
+
+	/* relative relocation */
+	} else if (pcrel == 1) {
+
+		/* intra-section */
+		if (section == NO_SEG) {
+			r->type = 1;			// X86_64_RELOC_SIGNED
+
+		/* inter-section */
+		} else {
+			r->type = 2;			// X86_64_RELOC_BRANCH
+			fi = get_section_fileindex_by_index(section);
+
+			/* external */
+			if (fi == NO_SECT) {
+				sect->extreloc = 1;
+				r->snum = raa_read(extsyms, section);
+		
+			/* local */
+			} else {
+				sym = get_closest_section_symbol_by_offset(fi, reloff);
+				r->snum = sym->initial_snum;
+				adjustment = sym->value;
+			}
+		}
+		
+	/* subtractor */
+	} else if (pcrel == 2) {
+		r->pcrel = 0;
+		r->type = 5;				// X86_64_RELOC_SUBTRACTOR
+//		r->snum = macho_gotpcrel_sect;
+
+	/* gotpcrel */
+	} else if (pcrel == 3) {
+		r->type = 4;				// X86_64_RELOC_GOT
+	} else if (pcrel == 4) {
+		r->type = 3;				// X86_64_RELOC_GOT_LOAD
+	}
+
+	++sect->nreloc;
+
+	return adjustment;
+}
+
+static void macho_output(int32_t secto, const void *data,
+			 enum out_type type, uint64_t size,
+                         int32_t section, int32_t wrt)
+{
+    struct section *s, *sbss;
+    int64_t addr;
+    uint8_t mydata[16], *p;
+
+    if (secto == NO_SEG) {
+        if (type != OUT_RESERVE)
+            error(ERR_NONFATAL, "attempt to assemble code in "
+                  "[ABSOLUTE] space");
+
+        return;
+    }
+
+    s = get_section_by_index(secto);
+
+    if (s == NULL) {
+        error(ERR_WARNING, "attempt to assemble code in"
+              " section %d: defaulting to `.text'", secto);
+        s = get_section_by_name("__TEXT", "__text");
+
+        /* should never happen */
+        if (s == NULL)
+            error(ERR_PANIC, "text section not found");
+    }
+
+    sbss = get_section_by_name("__DATA", "__bss");
+
+    if (s == sbss && type != OUT_RESERVE) {
+        error(ERR_WARNING, "attempt to initialize memory in the"
+              " BSS section: ignored");
+        s->size += realsize(type, size);
+        return;
+    }
+
+    switch (type) {
+    case OUT_RESERVE:
+        if (s != sbss) {
+            error(ERR_WARNING, "uninitialized space declared in"
+                  " %s section: zeroing",
+                  get_section_name_by_index(secto));
+
+            sect_write(s, NULL, size);
+        } else
+            s->size += size;
+
+        break;
+
+    case OUT_RAWDATA:
+        if (section != NO_SEG)
+            error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
+
+        sect_write(s, data, size);
+        break;
+
+    case OUT_ADDRESS:
+        addr = *(int64_t *)data;
+        if (section != NO_SEG) {
+            if (section % 2) {
+                error(ERR_NONFATAL, "Mach-O format does not support"
+                      " section base references");
+            } else {
+				if (wrt == NO_SEG) {
+					if (size < 8) {
+						error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
+							" 32-bit absolute addresses");
+					/*
+					 Seemingly, Mach-O's X86_64_RELOC_SUBTRACTOR would require
+					 pre-determined knowledge of where the image base would be,
+					 making it impractical for use in intermediate object files
+					 */
+					} else {
+						addr -= add_reloc(s, section, 0, size, addr);
+					}
+				} else if (wrt == macho_gotpcrel_sect) {
+					addr += s->size;
+					add_reloc(s, section, 3, size, addr);				// X86_64_RELOC_GOT
+				} else {
+					error(ERR_NONFATAL, "Mach-O format does not support"
+						" this use of WRT");
+				}
+			}
+		}
+
+        p = mydata;
+		WRITEADDR(p, addr, size);
+        sect_write(s, mydata, size);
+        break;
+
+    case OUT_REL2ADR:
+        p = mydata;
+        WRITESHORT(p, *(int64_t *)data);
+
+        if (section == secto)
+            error(ERR_PANIC, "intra-section OUT_REL2ADR");
+
+        if (section != NO_SEG && section % 2) {
+            error(ERR_NONFATAL, "Mach-O format does not support"
+                  " section base references");
+        } else {
+			if (wrt == NO_SEG) {
+				*mydata -= add_reloc(s, section, 2, 2, (int64_t)*mydata);
+				*mydata -= add_reloc(s, section, 0, 2, (int64_t)*mydata);
+			} else {
+				error(ERR_NONFATAL, "Unsupported non-32-bit"
+				  " Macho-O relocation [2]");
+			}
+		}
+
+        sect_write(s, mydata, 2L);
+        break;
+
+    case OUT_REL4ADR:
+        p = mydata;
+		WRITELONG(p, *(int64_t *)data);
+
+        if (section == secto)
+            error(ERR_PANIC, "intra-section OUT_REL4ADR");
+
+        if (section != NO_SEG && section % 2) {
+            error(ERR_NONFATAL, "Mach-O format does not support"
+                  " section base references");
+        } else {
+			if (wrt == NO_SEG) {
+				*mydata -= add_reloc(s, section, 1, 4, (int64_t)*mydata);				// X86_64_RELOC_UNSIGNED/SIGNED/BRANCH
+			} else if (wrt == macho_gotpcrel_sect) {
+				error(ERR_NONFATAL, "Mach-O format cannot produce PC-"
+					  "relative GOT references");
+			} else {
+				error(ERR_NONFATAL, "Mach-O format does not support"
+				    " this use of WRT");
+				wrt = NO_SEG;	/* we can at least _try_ to continue */
+			}
+		}
+
+        sect_write(s, mydata, 4L);
+        break;
+
+    default:
+        error(ERR_PANIC, "unknown output type?");
+        break;
+    }
+}
+
+static int32_t macho_section(char *name, int pass, int *bits)
+{
+    int32_t index, originalIndex;
+    char *sectionAttributes;
+    struct sectmap *sm;
+    struct section *s;
+
+    (void)pass;
+
+    /* Default to 64 bits. */
+    if (!name) {
+        *bits = 64;
+        name = ".text";
+        sectionAttributes = NULL;
+    } else {
+        sectionAttributes = name;
+        name = nasm_strsep(&sectionAttributes, " \t");
+    }
+
+    for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
+        /* make lookup into section name translation table */
+        if (!strcmp(name, sm->nasmsect)) {
+            char *currentAttribute;
+
+            /* try to find section with that name */
+            originalIndex = index = get_section_index_by_name(sm->segname,
+                                                              sm->sectname);
+
+            /* create it if it doesn't exist yet */
+            if (index == -1) {
+                s = *sectstail = nasm_malloc(sizeof(struct section));
+                s->next = NULL;
+                sectstail = &s->next;
+
+                s->data = saa_init(1L);
+                s->index = seg_alloc();
+                s->relocs = NULL;
+                s->align = -1;
+
+                xstrncpy(s->segname, sm->segname);
+                xstrncpy(s->sectname, sm->sectname);
+                s->size = 0;
+                s->nreloc = 0;
+                s->flags = sm->flags;
+
+                index = s->index;
+            } else {
+                s = get_section_by_index(index);
+            }
+
+            while ((NULL != sectionAttributes)
+                   && (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
+                if (0 != *currentAttribute) {
+                    if (!nasm_strnicmp("align=", currentAttribute, 6)) {
+                        char *end;
+                        int newAlignment, value;
+
+                        value = strtoul(currentAttribute + 6, (char**)&end, 0);
+                        newAlignment = exact_log2(value);
+
+                        if (0 != *end) {
+                            error(ERR_PANIC,
+                                  "unknown or missing alignment value \"%s\" "
+                                      "specified for section \"%s\"",
+                                  currentAttribute + 6,
+                                  name);
+                            return NO_SEG;
+                        } else if (0 > newAlignment) {
+                            error(ERR_PANIC,
+                                  "alignment of %d (for section \"%s\") is not "
+                                      "a power of two",
+                                  value,
+                                  name);
+                            return NO_SEG;
+                        }
+
+                        if ((-1 != originalIndex)
+                            && (s->align != newAlignment)
+                           && (s->align != -1)) {
+                            error(ERR_PANIC,
+                                  "section \"%s\" has already been specified "
+                                      "with alignment %d, conflicts with new "
+                                      "alignment of %d",
+                            name,
+                            (1 << s->align),
+                            value);
+                            return NO_SEG;
+                        }
+
+                        s->align = newAlignment;
+                    } else if (!nasm_stricmp("data", currentAttribute)) {
+                        /* Do nothing; 'data' is implicit */
+                    } else {
+                        error(ERR_PANIC,
+                              "unknown section attribute %s for section %s",
+                              currentAttribute,
+                              name);
+                        return NO_SEG;
+                    }
+                }
+            }
+
+            return index;
+        }
+    }
+
+    error(ERR_PANIC, "invalid section name %s", name);
+    return NO_SEG;
+}
+
+static void macho_symdef(char *name, int32_t section, int64_t offset,
+                         int is_global, char *special)
+{
+    struct symbol *sym;
+
+    if (special) {
+        error(ERR_NONFATAL, "The Mach-O output format does "
+              "not support any special symbol types");
+        return;
+    }
+
+    if (is_global == 3) {
+        error(ERR_NONFATAL, "The Mach-O format does not "
+              "(yet) support forward reference fixups.");
+        return;
+    }
+
+    sym = *symstail = nasm_malloc(sizeof(struct symbol));
+    sym->next = NULL;
+    symstail = &sym->next;
+
+    sym->name = name;
+    sym->strx = strslen;
+    sym->type = 0;
+    sym->desc = 0;
+    sym->value = offset;
+    sym->initial_snum = -1;
+
+	if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
+        /*
+         * This is a NASM special symbol. We never allow it into
+         * the Macho-O symbol table, even if it's a valid one. If it
+         * _isn't_ a valid one, we should barf immediately.
+         */
+        if (strcmp(name, "..gotpcrel"))
+            error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
+         return;
+    }
+
+    /* external and common symbols get N_EXT */
+    if (is_global != 0) {
+        sym->type |= N_EXT;
+	}
+
+    if (section == NO_SEG) {
+        /* symbols in no section get absolute */
+        sym->type |= N_ABS;
+        sym->sect = NO_SECT;
+    } else {
+        sym->type |= N_SECT;
+
+        /* get the in-file index of the section the symbol was defined in */
+        sym->sect = get_section_fileindex_by_index(section);
+		
+		/* track the initially allocated symbol number for use in future fix-ups */
+		sym->initial_snum = nsyms;
+
+        if (sym->sect == NO_SECT) {
+
+            /* remember symbol number of references to external
+             ** symbols, this works because every external symbol gets
+             ** its own section number allocated internally by nasm and
+             ** can so be used as a key */
+			extsyms = raa_write(extsyms, section, nsyms);
+
+            switch (is_global) {
+            case 1:
+            case 2:
+                /* there isn't actually a difference between global
+                 ** and common symbols, both even have their size in
+                 ** sym->value */
+                sym->type = N_EXT;
+                break;
+
+            default:
+                /* give an error on unfound section if it's not an
+                 ** external or common symbol (assemble_file() does a
+                 ** seg_alloc() on every call for them) */
+                error(ERR_PANIC, "in-file index for section %d not found",
+                      section);
+            }
+        }
+    }
+    ++nsyms;
+}
+
+static int32_t macho_segbase(int32_t section)
+{
+    return section;
+}
+
+static int macho_directive(char *directive, char *value, int pass)
+{
+    (void)directive;
+    (void)value;
+    (void)pass;
+    return 0;
+}
+
+static void macho_filename(char *inname, char *outname, efunc error)
+{
+    standard_extension(inname, outname, ".o", error);
+}
+
+extern macros_t macho_stdmac[];
+
+/* Comparison function for qsort symbol layout.  */
+static int layout_compare (const struct symbol **s1,
+			   const struct symbol **s2)
+{
+    return (strcmp ((*s1)->name, (*s2)->name));
+}
+
+/* The native assembler does a few things in a similar function
+
+	* Remove temporary labels
+	* Sort symbols according to local, external, undefined (by name)
+	* Order the string table
+
+   We do not remove temporary labels right now.
+
+   numsyms is the total number of symbols we have. strtabsize is the
+   number entries in the string table.  */
+
+static void macho_layout_symbols (uint32_t *numsyms,
+				  uint32_t *strtabsize)
+{
+    struct symbol *sym, **symp;
+    uint32_t i,j;
+
+    *numsyms = 0;
+    *strtabsize = sizeof (char);
+
+    symp = &syms;
+
+    while ((sym = *symp)) {
+	/* Undefined symbols are now external.  */
+	if (sym->type == N_UNDF)
+	    sym->type |= N_EXT;
+
+	if ((sym->type & N_EXT) == 0) {
+	    sym->snum = *numsyms;
+	    *numsyms = *numsyms + 1;
+	    nlocalsym++;
+	}
+	else {
+		if ((sym->type & N_TYPE) != N_UNDF) {
+			nextdefsym++;
+	    } else {
+			nundefsym++;
+		}
+
+	    /* If we handle debug info we'll want
+	       to check for it here instead of just
+	       adding the symbol to the string table.  */
+	    sym->strx = *strtabsize;
+	    saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
+	    *strtabsize += strlen(sym->name) + 1;
+	}
+	symp = &(sym->next);
+    }
+
+    /* Next, sort the symbols.  Most of this code is a direct translation from
+       the Apple cctools symbol layout. We need to keep compatibility with that.  */
+    /* Set the indexes for symbol groups into the symbol table */
+    ilocalsym = 0;
+    iextdefsym = nlocalsym;
+    iundefsym = nlocalsym + nextdefsym;
+
+    /* allocate arrays for sorting externals by name */
+    extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
+    undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
+
+    i = 0;
+    j = 0;
+
+    symp = &syms;
+
+    while ((sym = *symp)) {
+
+	if((sym->type & N_EXT) == 0) {
+	    sym->strx = *strtabsize;
+	    saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
+	    *strtabsize += strlen(sym->name) + 1;
+	}
+	else {
+		if((sym->type & N_TYPE) != N_UNDF) {
+			extdefsyms[i++] = sym;
+	    } else {
+			undefsyms[j++] = sym;
+		}
+	}
+	symp = &(sym->next);
+    }
+
+    qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
+	  (int (*)(const void *, const void *))layout_compare);
+    qsort(undefsyms, nundefsym, sizeof(struct symbol *),
+	  (int (*)(const void *, const void *))layout_compare);
+
+    for(i = 0; i < nextdefsym; i++) {
+	extdefsyms[i]->snum = *numsyms;
+	*numsyms += 1;
+    }
+    for(j = 0; j < nundefsym; j++) {
+	undefsyms[j]->snum = *numsyms;
+	*numsyms += 1;
+    }
+}
+
+/* Calculate some values we'll need for writing later.  */
+
+static void macho_calculate_sizes (void)
+{
+    struct section *s;
+
+    /* count sections and calculate in-memory and in-file offsets */
+    for (s = sects; s != NULL; s = s->next) {
+        uint64_t pad = 0;
+
+        /* zerofill sections aren't actually written to the file */
+        if ((s->flags & SECTION_TYPE) != S_ZEROFILL)
+            seg_filesize64 += s->size;
+
+        /* recalculate segment address based on alignment and vm size */
+        s->addr = seg_vmsize64;
+        /* we need section alignment to calculate final section address */
+        if (s->align == -1)
+            s->align = DEFAULT_SECTION_ALIGNMENT;
+        if(s->align) {
+            uint64_t newaddr = align(s->addr, 1 << s->align);
+            pad = newaddr - s->addr;
+            s->addr = newaddr;
+        }
+
+        seg_vmsize64 += s->size + pad;
+        ++seg_nsects64;
+    }
+
+    /* calculate size of all headers, load commands and sections to
+    ** get a pointer to the start of all the raw data */
+    if (seg_nsects64 > 0) {
+        ++head_ncmds64;
+        head_sizeofcmds64 +=
+            MACHO_SEGCMD64_SIZE + seg_nsects64 * MACHO_SECTCMD64_SIZE;
+    }
+
+    if (nsyms > 0) {
+	++head_ncmds64;
+	head_sizeofcmds64 += MACHO_SYMCMD_SIZE;
+    }
+}
+
+/* Write out the header information for the file.  */
+
+static void macho_write_header (void)
+{
+    fwriteint32_t(MH_MAGIC_64, machofp);	/* magic */
+    fwriteint32_t(CPU_TYPE_X86_64, machofp);	/* CPU type */
+    fwriteint32_t(CPU_SUBTYPE_I386_ALL, machofp);	/* CPU subtype */
+    fwriteint32_t(MH_OBJECT, machofp);	/* Mach-O file type */
+    fwriteint32_t(head_ncmds64, machofp);	/* number of load commands */
+    fwriteint32_t(head_sizeofcmds64, machofp);	/* size of load commands */
+    fwriteint32_t(0, machofp);	/* no flags */
+	fwriteint32_t(0, machofp); /* reserved for future use */
+}
+
+/* Write out the segment load command at offset.  */
+
+static uint32_t macho_write_segment (uint64_t offset)
+{
+    uint64_t rel_base = alignint64_t (offset + seg_filesize64);
+    uint32_t s_reloff = 0;
+    struct section *s;
+
+    fwriteint32_t(LC_SEGMENT_64, machofp);        /* cmd == LC_SEGMENT_64 */
+
+    /* size of load command including section load commands */
+    fwriteint32_t(MACHO_SEGCMD64_SIZE + seg_nsects64 *
+	       MACHO_SECTCMD64_SIZE, machofp);
+
+    /* in an MH_OBJECT file all sections are in one unnamed (name
+    ** all zeros) segment */
+    fwritezero(16, machofp);
+    fwriteint64_t(0, machofp); /* in-memory offset */
+    fwriteint64_t(seg_vmsize64, machofp);        /* in-memory size */
+    fwriteint64_t(offset, machofp);    /* in-file offset to data */
+    fwriteint64_t(seg_filesize64, machofp);      /* in-file size */
+    fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* maximum vm protection */
+    fwriteint32_t(VM_PROT_DEFAULT, machofp);   /* initial vm protection */
+    fwriteint32_t(seg_nsects64, machofp);        /* number of sections */
+    fwriteint32_t(0, machofp); /* no flags */
+
+    /* emit section headers */
+    for (s = sects; s != NULL; s = s->next) {
+        fwrite(s->sectname, sizeof(s->sectname), 1, machofp);
+        fwrite(s->segname, sizeof(s->segname), 1, machofp);
+        fwriteint64_t(s->addr, machofp);
+        fwriteint64_t(s->size, machofp);
+
+        /* dummy data for zerofill sections or proper values */
+        if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
+            fwriteint32_t(offset, machofp);
+            /* Write out section alignment, as a power of two.
+            e.g. 32-bit word alignment would be 2 (2^2 = 4).  */
+            if (s->align == -1)
+                s->align = DEFAULT_SECTION_ALIGNMENT;
+            fwriteint32_t(s->align, machofp);
+            /* To be compatible with cctools as we emit
+            a zero reloff if we have no relocations.  */
+            fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, machofp);
+            fwriteint32_t(s->nreloc, machofp);
+
+            offset += s->size;
+            s_reloff += s->nreloc * MACHO_RELINFO64_SIZE;
+        } else {
+            fwriteint32_t(0, machofp);
+            fwriteint32_t(0, machofp);
+            fwriteint32_t(0, machofp);
+            fwriteint32_t(0, machofp);
+        }
+		
+		if (s->nreloc) {
+			s->flags |= S_ATTR_LOC_RELOC;
+			if (s->extreloc)
+				s->flags |= S_ATTR_EXT_RELOC;
+		}
+
+        fwriteint32_t(s->flags, machofp);      /* flags */
+        fwriteint32_t(0, machofp);     /* reserved */
+        fwriteint32_t(0, machofp);     /* reserved */
+		
+		fwriteint32_t(0, machofp);     /* align */
+    }
+
+    rel_padcnt64 = rel_base - offset;
+    offset = rel_base + s_reloff;
+
+    return offset;
+}
+
+/* For a given chain of relocs r, write out the entire relocation
+   chain to the object file.  */
+
+static void macho_write_relocs (struct reloc *r)
+{
+    while (r) {
+	uint32_t word2;
+
+	fwriteint32_t(r->addr, machofp); /* reloc offset */
+
+	word2 = r->snum;
+	word2 |= r->pcrel << 24;
+	word2 |= r->length << 25;
+	word2 |= r->ext << 27;
+	word2 |= r->type << 28;
+	fwriteint32_t(word2, machofp); /* reloc data */
+	r = r->next;
+    }
+}
+
+/* Write out the section data.  */
+static void macho_write_section (void)
+{
+    struct section *s, *s2;
+    struct reloc *r;
+    uint8_t fi, *p, *q, blk[8];
+	int32_t len;
+    int64_t l;
+
+    for (s = sects; s != NULL; s = s->next) {
+	if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
+	    continue;
+
+	/* no padding needs to be done to the sections */
+
+	/* Like a.out Mach-O references things in the data or bss
+	 * sections by addresses which are actually relative to the
+	 * start of the _text_ section, in the _file_. See outaout.c
+	 * for more information. */
+	saa_rewind(s->data);
+	for (r = s->relocs; r != NULL; r = r->next) {
+		len = (int32_t)r->length << 1;
+		if(len > 4) len = 8;
+	    saa_fread(s->data, r->addr, blk, len);
+	    p = q = blk;
+	    l = *p++;
+
+	    /* get offset based on relocation type */
+	    if (r->length > 0) {
+			l += ((int64_t)*p++) << 8;
+
+			if (r->length > 1) {
+				l += ((int64_t)*p++) << 16;
+				l += ((int64_t)*p++) << 24;
+			}
+
+			if (r->length > 2) {
+				l += ((int64_t)*p++) << 32;
+				l += ((int64_t)*p++) << 40;
+				l += ((int64_t)*p++) << 48;
+				l += ((int64_t)*p++) << 56;
+			}
+			
+			
+	    }
+	
+	    /* If the relocation is internal add to the current section
+	       offset. Otherwise the only value we need is the symbol
+	       offset which we already have. The linker takes care
+	       of the rest of the address.  */
+	    if (!r->ext) {
+            /* generate final address by section address and offset */
+		    for (s2 = sects, fi = 1;
+		        s2 != NULL; s2 = s2->next, fi++) {
+		        if (fi == r->snum) {
+		            l += s2->addr;
+		            break;
+		        }
+		    }
+	    }
+
+	    /* write new offset back */
+		if (r->length == 3)
+		WRITEDLONG(q, l);
+		else if (r->length == 2)
+		WRITELONG(q, l);
+	    else if (r->length == 1)
+		WRITESHORT(q, l);
+	    else
+		*q++ = l & 0xFF;
+
+	    saa_fwrite(s->data, r->addr, blk, len);
+	}
+
+	/* dump the section data to file */
+	saa_fpwrite(s->data, machofp);
+    }
+
+    /* pad last section up to reloc entries on int64_t boundary */
+    fwritezero(rel_padcnt64, machofp);
+
+    /* emit relocation entries */
+    for (s = sects; s != NULL; s = s->next)
+	macho_write_relocs (s->relocs);
+}
+
+/* Write out the symbol table. We should already have sorted this
+   before now.  */
+static void macho_write_symtab (void)
+{
+    struct symbol *sym;
+    struct section *s;
+    int64_t fi;
+    uint64_t i;
+
+    /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
+
+    for (sym = syms; sym != NULL; sym = sym->next) {
+	if ((sym->type & N_EXT) == 0) {
+	    fwriteint32_t(sym->strx, machofp);		/* string table entry number */
+	    fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	    fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	    fwriteint16_t(sym->desc, machofp);	/* description */
+
+	    /* Fix up the symbol value now that we know the final section
+	       sizes.  */
+	    if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+		for (s = sects, fi = 1;
+		     s != NULL && fi < sym->sect; s = s->next, ++fi)
+		    sym->value += s->size;
+	    }
+
+	    fwriteint64_t(sym->value, machofp);	/* value (i.e. offset) */
+	}
+    }
+
+    for (i = 0; i < nextdefsym; i++) {
+	sym = extdefsyms[i];
+	fwriteint32_t(sym->strx, machofp);
+	fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	fwriteint16_t(sym->desc, machofp);	/* description */
+
+	/* Fix up the symbol value now that we know the final section
+	   sizes.  */
+	if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+	    for (s = sects, fi = 1;
+		 s != NULL && fi < sym->sect; s = s->next, ++fi)
+		sym->value += s->size;
+	}
+
+	fwriteint64_t(sym->value, machofp);	/* value (i.e. offset) */
+    }
+
+     for (i = 0; i < nundefsym; i++) {
+	 sym = undefsyms[i];
+	 fwriteint32_t(sym->strx, machofp);
+	 fwrite(&sym->type, 1, 1, machofp);	/* symbol type */
+	 fwrite(&sym->sect, 1, 1, machofp);	/* section */
+	 fwriteint16_t(sym->desc, machofp);	/* description */
+
+	 // Fix up the symbol value now that we know the final section sizes.
+	 if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
+	     for (s = sects, fi = 1;
+		  s != NULL && fi < sym->sect; s = s->next, ++fi)
+		 sym->value += s->size;
+	 }
+
+	 fwriteint64_t(sym->value, machofp);	// value (i.e. offset)
+     }
+
+}
+
+/* Fixup the snum in the relocation entries, we should be
+   doing this only for externally referenced symbols. */
+static void macho_fixup_relocs (struct reloc *r)
+{
+    struct symbol *sym;
+
+    while (r != NULL) {
+	if (r->ext) {
+	for (sym = syms; sym != NULL; sym = sym->next) {
+		if (sym->initial_snum == r->snum) {
+			r->snum = sym->snum;
+			break;
+		}
+	}
+	}
+	r = r->next;
+    }
+}
+
+/* Write out the object file.  */
+
+static void macho_write (void)
+{
+    uint64_t offset = 0;
+
+    /* mach-o object file structure:
+    **
+    ** mach header
+    **  uint32_t magic
+    **  int   cpu type
+    **  int   cpu subtype
+    **  uint32_t mach file type
+    **  uint32_t number of load commands
+    **  uint32_t size of all load commands
+    **   (includes section struct size of segment command)
+    **  uint32_t flags
+    **
+    ** segment command
+    **  uint32_t command type == LC_SEGMENT_64
+    **  uint32_t size of load command
+    **   (including section load commands)
+    **  char[16] segment name
+    **  uint64_t in-memory offset
+    **  uint64_t in-memory size
+    **  uint64_t in-file offset to data area
+    **  uint64_t in-file size
+    **   (in-memory size excluding zerofill sections)
+    **  int   maximum vm protection
+    **  int   initial vm protection
+    **  uint32_t number of sections
+    **  uint32_t flags
+    **
+    ** section commands
+    **   char[16] section name
+    **   char[16] segment name
+    **   uint64_t in-memory offset
+    **   uint64_t in-memory size
+    **   uint32_t in-file offset
+    **   uint32_t alignment
+    **    (irrelevant in MH_OBJECT)
+    **   uint32_t in-file offset of relocation entires
+    **   uint32_t number of relocations
+    **   uint32_t flags
+    **   uint32_t reserved
+    **   uint32_t reserved
+    **
+    ** symbol table command
+    **  uint32_t command type == LC_SYMTAB
+    **  uint32_t size of load command
+    **  uint32_t symbol table offset
+    **  uint32_t number of symbol table entries
+    **  uint32_t string table offset
+    **  uint32_t string table size
+    **
+    ** raw section data
+    **
+    ** padding to int64_t boundary
+    **
+    ** relocation data (struct reloc)
+    ** int32_t offset
+    **  uint data (symbolnum, pcrel, length, extern, type)
+    **
+    ** symbol table data (struct nlist)
+    **  int32_t  string table entry number
+    **  uint8_t type
+    **   (extern, absolute, defined in section)
+    **  uint8_t section
+    **   (0 for global symbols, section number of definition (>= 1, <=
+    **   254) for local symbols, size of variable for common symbols
+    **   [type == extern])
+    **  int16_t description
+    **   (for stab debugging format)
+    **  uint64_t value (i.e. file offset) of symbol or stab offset
+    **
+    ** string table data
+    **  list of null-terminated strings
+    */
+
+    /* Emit the Mach-O header.  */
+    macho_write_header();
+
+    offset = MACHO_HEADER64_SIZE + head_sizeofcmds64;
+
+    /* emit the segment load command */
+    if (seg_nsects64 > 0)
+	offset = macho_write_segment (offset);
+    else
+        error(ERR_WARNING, "no sections?");
+
+    if (nsyms > 0) {
+        /* write out symbol command */
+        fwriteint32_t(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */
+        fwriteint32_t(MACHO_SYMCMD_SIZE, machofp); /* size of load command */
+        fwriteint32_t(offset, machofp);    /* symbol table offset */
+        fwriteint32_t(nsyms, machofp);     /* number of symbol
+                                         ** table entries */
+
+        offset += nsyms * MACHO_NLIST64_SIZE;
+        fwriteint32_t(offset, machofp);    /* string table offset */
+        fwriteint32_t(strslen, machofp);   /* string table size */
+    }
+
+    /* emit section data */
+    if (seg_nsects64 > 0)
+	macho_write_section ();
+
+    /* emit symbol table if we have symbols */
+    if (nsyms > 0)
+	macho_write_symtab ();
+
+    /* we don't need to pad here since MACHO_NLIST64_SIZE == 16 */
+
+    /* emit string table */
+    saa_fpwrite(strs, machofp);
+}
+/* We do quite a bit here, starting with finalizing all of the data
+   for the object file, writing, and then freeing all of the data from
+   the file.  */
+
+static void macho_cleanup(int debuginfo)
+{
+    struct section *s;
+    struct reloc *r;
+    struct symbol *sym;
+
+    (void)debuginfo;
+
+    /* Sort all symbols.  */
+    macho_layout_symbols (&nsyms, &strslen);
+
+    /* Fixup relocation entries */
+    for (s = sects; s != NULL; s = s->next) {
+	macho_fixup_relocs (s->relocs);
+    }
+
+    /* First calculate and finalize needed values.  */
+    macho_calculate_sizes();
+    macho_write();
+
+    /* done - yay! */
+    fclose(machofp);
+
+    /* free up everything */
+    while (sects->next) {
+        s = sects;
+        sects = sects->next;
+
+        saa_free(s->data);
+        while (s->relocs != NULL) {
+            r = s->relocs;
+            s->relocs = s->relocs->next;
+            nasm_free(r);
+        }
+
+        nasm_free(s);
+    }
+
+    saa_free(strs);
+    raa_free(extsyms);
+
+    if (syms) {
+    while (syms->next) {
+       sym = syms;
+       syms = syms->next;
+
+       nasm_free (sym);
+    }
+}
+}
+
+/* Debugging routines.  */
+static void debug_reloc (struct reloc *r)
+{
+    fprintf (stdout, "reloc:\n");
+    fprintf (stdout, "\taddr: %"PRId32"\n", r->addr);
+    fprintf (stdout, "\tsnum: %d\n", r->snum);
+    fprintf (stdout, "\tpcrel: %d\n", r->pcrel);
+    fprintf (stdout, "\tlength: %d\n", r->length);
+    fprintf (stdout, "\text: %d\n", r->ext);
+    fprintf (stdout, "\ttype: %d\n", r->type);
+}
+
+static void debug_section_relocs (struct section *s)
+{
+    struct reloc *r = s->relocs;
+
+    fprintf (stdout, "relocs for section %s:\n\n", s->sectname);
+
+    while (r != NULL) {
+	debug_reloc (r);
+	r = r->next;
+    }
+}
+
+struct ofmt of_macho64 = {
+    "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
+    "macho64",
+    0,
+    null_debug_arr,
+    &null_debug_form,
+    macho_stdmac,
+    macho_init,
+    macho_setinfo,
+    macho_output,
+    macho_symdef,
+    macho_section,
+    macho_segbase,
+    macho_directive,
+    macho_filename,
+    macho_cleanup
+};
+
+#endif
+
+/*
+ * Local Variables:
+ * mode:c
+ * c-basic-offset:4
+ * End:
+ *
+ * end of file */
diff --git a/rbtree.c b/rbtree.c
new file mode 100644
index 00000000..5af6067d
--- /dev/null
+++ b/rbtree.c
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ *   See the file AUTHORS included with the NASM distribution for
+ *   the specific copyright holders.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following
+ *   conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * 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 COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * rbtree.c
+ *
+ * Simple implementation of a left-leaning red-black tree with 64-bit
+ * integer keys.  The search operation will return the highest node <=
+ * the key; only search and insert are supported, but additional
+ * standard llrbtree operations can be coded up at will.
+ *
+ * See http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf for
+ * information about left-leaning red-black trees.
+ */
+
+#include "rbtree.h"
+
+struct rbtree *rb_search(struct rbtree *tree, uint64_t key)
+{
+    struct rbtree *best = NULL;
+
+    while (tree) {
+	if (tree->key == key)
+	    return tree;
+	else if (tree->key > key)
+	    tree = tree->left;
+	else {
+	    best = tree;
+	    tree = tree->right;
+	}
+    }
+    return best;
+}
+
+static bool is_red(struct rbtree *h)
+{
+    return h && h->red;
+}
+
+static struct rbtree *rotate_left(struct rbtree *h)
+{
+    struct rbtree *x = h->right;
+    h->right = x->left;
+    x->left = h;
+    x->red = x->left->red;
+    x->left->red = true;
+    return x;
+}
+
+static struct rbtree *rotate_right(struct rbtree *h)
+{
+    struct rbtree *x = h->left;
+    h->left = x->right;
+    x->right = h;
+    x->red = x->right->red;
+    x->right->red = true;
+    return x;
+}
+
+static void color_flip(struct rbtree *h)
+{
+    h->red = !h->red;
+    h->left->red = !h->left->red;
+    h->right->red = !h->right->red;
+}
+
+struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node)
+{
+    if (!tree) {
+	node->red = true;
+	return node;
+    }
+
+    if (is_red(tree->left) && is_red(tree->right))
+	color_flip(tree);
+
+    if (node->key < tree->key)
+	tree->left = rb_insert(tree->left, node);
+    else
+	tree->right = rb_insert(tree->right, node);
+
+    if (is_red(tree->right))
+	tree = rotate_left(tree);
+
+    if (is_red(tree->left) && is_red(tree->left->left))
+	tree = rotate_right(tree);
+
+    return tree;
+}
diff --git a/rdoff/symtab.h b/rbtree.h
similarity index 78%
copy from rdoff/symtab.h
copy to rbtree.h
index 0dc8c7b1..ef34789f 100644
--- a/rdoff/symtab.h
+++ b/rbtree.h
@@ -31,26 +31,22 @@
  *
  * ----------------------------------------------------------------------- */
 
-/*
- * symtab.h	Header file for symbol table manipulation routines
- */
-
-#ifndef RDOFF_SYMTAB_H
-#define RDOFF_SYMTAB_H 1
+#ifndef NASM_RBTREE_H
+#define NASM_RBTREE_H
 
+#include "compiler.h"
 #include <inttypes.h>
 
-typedef struct {
-    char *name;
-    int segment;
-    int32_t offset;
-    int32_t flags;
-} symtabEnt;
+/* This structure should be embedded in a larger data structure;
+   the final output from rb_search() can then be converted back
+   to the larger data structure via container_of(). */
+struct rbtree {
+    uint64_t key;
+    struct rbtree *left, *right;
+    bool red;
+};
 
-void *symtabNew(void);
-void symtabDone(void *symtab);
-void symtabInsert(void *symtab, symtabEnt * ent);
-symtabEnt *symtabFind(void *symtab, const char *name);
-void symtabDump(void *symtab, FILE * of);
+struct rbtree *rb_insert(struct rbtree *, struct rbtree *);
+struct rbtree *rb_search(struct rbtree *, uint64_t);
 
-#endif
+#endif /* NASM_RBTREE_H */
diff --git a/rdoff/rdf2com.1 b/rdoff/rdf2ihx.1
similarity index 100%
copy from rdoff/rdf2com.1
copy to rdoff/rdf2ihx.1
diff --git a/rdoff/rdf2com.1 b/rdoff/rdf2ith.1
similarity index 100%
copy from rdoff/rdf2com.1
copy to rdoff/rdf2ith.1
diff --git a/rdoff/rdf2com.1 b/rdoff/rdf2srec.1
similarity index 100%
copy from rdoff/rdf2com.1
copy to rdoff/rdf2srec.1
diff --git a/test/align13.asm b/test/align13.asm
new file mode 100644
index 00000000..556373fc
--- /dev/null
+++ b/test/align13.asm
@@ -0,0 +1,16 @@
+; Test of non-power-of-2 alignment
+
+	bits 32
+
+	inc eax
+	inc eax
+	align 13
+	inc eax
+	inc eax
+	align 13
+	inc eax
+	inc eax
+	align 13
+	align 13 ;should do nothing
+	inc eax
+	inc eax
diff --git a/test/align13s.asm b/test/align13s.asm
new file mode 100644
index 00000000..dab21a20
--- /dev/null
+++ b/test/align13s.asm
@@ -0,0 +1,16 @@
+; Test of non-power-of-2 alignment
+%use smartalign
+
+	bits 32
+
+	inc eax
+	inc eax
+	align 13
+	inc eax
+	inc eax
+	align 13
+	inc eax
+	inc eax
+	align 13
+	inc eax
+	inc eax
diff --git a/test/andbyte.asm b/test/andbyte.asm
new file mode 100644
index 00000000..3d3b1c1a
--- /dev/null
+++ b/test/andbyte.asm
@@ -0,0 +1,15 @@
+;Testname=test; Arguments=-fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
+;Testname=otest; Arguments=-Ox -fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
+
+	bits 16
+
+	add sp, byte -0x10
+	add sp, -0x10
+	adc sp, byte -0x10
+	adc sp, -0x10
+	and sp, byte -0x10
+	and sp, -0x10
+	sbb sp, byte -0x10
+	sbb sp, -0x10
+	sub sp, byte -0x10
+	sub sp, -0x10
diff --git a/test/avx005.asm b/test/avx005.asm
new file mode 100644
index 00000000..08765140
--- /dev/null
+++ b/test/avx005.asm
@@ -0,0 +1,529 @@
+;Testname=avx005; Arguments=-fbin -oavx005.bin -Ox; Files=stdout stderr avx005.bin
+
+%define regxmm xmm0
+%define regymm ymm0
+%define mem [0]
+%define imm 3
+
+%macro x 1+.nolist
+ %1 ; comment this line if RELAXed variants are not supported
+%endmacro
+
+  VFMADDSUB132PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB132PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB132PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB132PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB312PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB312PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB312PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB312PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADDSUB132PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB132PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB132PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB132PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB312PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB312PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB312PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB312PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD132PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD132PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD132PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD132PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD312PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD312PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD312PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD312PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD132PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD132PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD132PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD132PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD312PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD312PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD312PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD312PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD132PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD132PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD132PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD132PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD312PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD312PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD312PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD312PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD132PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD132PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD132PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD132PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD312PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD312PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD312PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD312PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD132SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMADD132SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD312SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMADD312SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMADD132SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMADD132SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD312SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMADD312SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB132PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB132PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB132PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB132PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB312PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB312PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB312PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB312PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB132PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB132PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB132PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB132PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB312PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB312PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB312PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB312PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB132SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMSUB132SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB312SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMSUB312SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB132SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMSUB132SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB312SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMSUB312SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD132PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD132PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD132PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD132PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD312PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD312PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD312PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD312PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD132PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD132PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD132PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD132PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD312PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD312PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD312PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD312PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD132SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMADD132SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD312SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMADD312SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD132SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMADD132SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD312SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMADD312SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB132PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB132PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB132PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB132PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB312PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB312PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB312PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB312PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB132PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB132PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB132PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB132PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB312PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB312PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB312PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB312PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB132SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMSUB132SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB312SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMSUB312SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB132SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMSUB132SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB312SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMSUB312SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMADDSUB213PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB213PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB213PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB213PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB123PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB123PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB123PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB123PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADDSUB213PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB213PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB213PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB213PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB123PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB123PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB123PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB123PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD213PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD213PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD213PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD213PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD123PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD123PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD123PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD123PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD213PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD213PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD213PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD213PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD123PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD123PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD123PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD123PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD213PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD213PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD213PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD213PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD123PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD123PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD123PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD123PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD213PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD213PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD213PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD213PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD123PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD123PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD123PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD123PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD213SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMADD213SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD123SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMADD123SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMADD213SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMADD213SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD123SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMADD123SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB213PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB213PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB213PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB213PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB123PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB123PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB123PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB123PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB213PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB213PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB213PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB213PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB123PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB123PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB123PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB123PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB213SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMSUB213SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB123SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMSUB123SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB213SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMSUB213SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB123SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMSUB123SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD213PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD213PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD213PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD213PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD123PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD123PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD123PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD123PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD213PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD213PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD213PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD213PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD123PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD123PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD123PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD123PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD213SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMADD213SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD123SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMADD123SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD213SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMADD213SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD123SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMADD123SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB213PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB213PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB213PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB213PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB123PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB123PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB123PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB123PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB213PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB213PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB213PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB213PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB123PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB123PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB123PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB123PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB213SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMSUB213SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB123SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMSUB123SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB213SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMSUB213SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB123SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMSUB123SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMADDSUB231PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB231PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB231PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB231PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB321PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB321PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB321PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB321PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADDSUB231PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADDSUB231PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADDSUB231PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADDSUB231PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADDSUB321PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADDSUB321PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADDSUB321PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADDSUB321PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD231PS regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD231PS regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD231PS regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD231PS regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD321PS regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD321PS regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD321PS regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD321PS regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUBADD231PD regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUBADD231PD regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUBADD231PD regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUBADD231PD regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUBADD321PD regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUBADD321PD regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUBADD321PD regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUBADD321PD regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD231PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD231PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD231PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD231PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD321PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD321PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD321PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD321PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD231PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMADD231PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMADD231PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMADD231PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMADD321PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMADD321PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMADD321PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMADD321PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMADD231SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMADD231SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD321SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMADD321SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMADD231SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMADD231SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMADD321SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMADD321SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB231PS    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB231PS    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB231PS    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB231PS    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB321PS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB321PS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB321PS    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB321PS    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB231PD    regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFMSUB231PD    regxmm,regxmm,regxmm     ; VEX_FMA
+  VFMSUB231PD    regymm,regymm,mem        ; VEX_FMA,SY
+  VFMSUB231PD    regymm,regymm,regymm     ; VEX_FMA
+
+x VFMSUB321PD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFMSUB321PD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFMSUB321PD    regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFMSUB321PD    regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFMSUB231SS    regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFMSUB231SS    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB321SS    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFMSUB321SS    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFMSUB231SD    regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFMSUB231SD    regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFMSUB321SD    regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFMSUB321SD    regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD231PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD231PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD231PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD231PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD321PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD321PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD321PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD321PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD231PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMADD231PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMADD231PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMADD231PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMADD321PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMADD321PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMADD321PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMADD321PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMADD231SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMADD231SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD321SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMADD321SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMADD231SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMADD231SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMADD321SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMADD321SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB231PS   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB231PS   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB231PS   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB231PS   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB321PS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB321PS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB321PS   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB321PS   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB231PD   regxmm,regxmm,mem        ; VEX_FMA,SO
+  VFNMSUB231PD   regxmm,regxmm,regxmm     ; VEX_FMA
+  VFNMSUB231PD   regymm,regymm,mem        ; VEX_FMA,SY
+  VFNMSUB231PD   regymm,regymm,regymm     ; VEX_FMA
+
+x VFNMSUB321PD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SO
+x VFNMSUB321PD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+x VFNMSUB321PD   regymm,regymm,mem        ; VEX_FMA,RELAX,SY
+x VFNMSUB321PD   regymm,regymm,regymm     ; VEX_FMA,RELAX
+
+  VFNMSUB231SS   regxmm,regxmm,mem        ; VEX_FMA,SD
+  VFNMSUB231SS   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB321SS   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SD
+x VFNMSUB321SS   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VFNMSUB231SD   regxmm,regxmm,mem        ; VEX_FMA,SQ
+  VFNMSUB231SD   regxmm,regxmm,regxmm     ; VEX_FMA
+
+x VFNMSUB321SD   regxmm,regxmm,mem        ; VEX_FMA,RELAX,SQ
+x VFNMSUB321SD   regxmm,regxmm,regxmm     ; VEX_FMA,RELAX
+
+  VPCLMULLQLQDQ  regxmm,regxmm,mem        ; PCLMUL,VEX_AVX,SO
+  VPCLMULLQLQDQ  regxmm,regxmm,regxmm     ; PCLMUL,VEX_AVX
+  VPCLMULHQLQDQ  regxmm,regxmm,mem        ; PCLMUL,VEX_AVX,SO
+  VPCLMULHQLQDQ  regxmm,regxmm,regxmm     ; PCLMUL,VEX_AVX
+  VPCLMULLQHQDQ  regxmm,regxmm,mem        ; PCLMUL,VEX_AVX,SO
+  VPCLMULLQHQDQ  regxmm,regxmm,regxmm     ; PCLMUL,VEX_AVX
+  VPCLMULHQHQDQ  regxmm,regxmm,mem        ; PCLMUL,VEX_AVX,SO
+  VPCLMULHQHQDQ  regxmm,regxmm,regxmm     ; PCLMUL,VEX_AVX
+  VPCLMULQDQ     regxmm,regxmm,mem,imm    ; PCLMUL,VEX_AVX,SB3,SO
+  VPCLMULQDQ     regxmm,regxmm,regxmm,imm ; PCLMUL,VEX_AVX,SB3
+
+; EOF
+
+ 	  	 
diff --git a/test/br2148476.asm b/test/br2148476.asm
new file mode 100644
index 00000000..1b263c98
--- /dev/null
+++ b/test/br2148476.asm
@@ -0,0 +1,221 @@
+;Testname=test; Arguments=-fbin -obr2148476.bin; Files=.stdout .stderr br2148476.bin
+
+	bits 64
+
+	cvtdq2pd xmm0, xmm1
+	cvtdq2pd xmm0, [rdi]
+	cvtdq2pd xmm0, qword [rdi]
+
+	cvtdq2ps xmm0, xmm1
+	cvtdq2ps xmm0, [rdi]
+	cvtdq2ps xmm0, oword [rdi]
+
+	cvtpd2dq xmm0, xmm1
+	cvtpd2dq xmm0, [rdi]
+	cvtpd2dq xmm0, oword [rdi]
+
+	cvtpd2pi mm0, xmm1
+	cvtpd2pi mm0, [rdi]
+	cvtpd2pi mm0, oword [rdi]
+
+	cvtpd2ps xmm0, xmm1
+	cvtpd2ps xmm0, [rdi]
+	cvtpd2ps xmm0, oword [rdi]
+
+	cvtpi2pd xmm0, mm1
+	cvtpi2pd xmm0, [rdi]
+	cvtpi2pd xmm0, qword [rdi]
+
+	cvtpi2ps xmm0, mm1
+	cvtpi2ps xmm0, [rdi]
+	cvtpi2ps xmm0, qword [rdi]
+
+	cvtps2dq xmm0, xmm1
+	cvtps2dq xmm0, [rdi]
+	cvtps2dq xmm0, oword [rdi]
+
+	cvtps2pd xmm0, xmm1
+	cvtps2pd xmm0, [rdi]
+	cvtps2pd xmm0, qword [rdi]
+
+	cvtps2pi mm0, xmm1
+	cvtps2pi mm0, [rdi]
+	cvtps2pi mm0, qword [rdi]
+
+	cvtsd2si eax, xmm1
+	cvtsd2si eax, [rdi]
+	cvtsd2si eax, qword [rdi]
+	cvtsd2si rax, xmm1
+	cvtsd2si rax, [rdi]
+	cvtsd2si rax, qword [rdi]
+
+	cvtsd2ss xmm0, xmm1
+	cvtsd2ss xmm0, [rdi]
+	cvtsd2ss xmm0, qword [rdi]
+
+	cvtsi2sd xmm0, eax
+	cvtsi2sd xmm0, [rdi]	; Compatibility
+	cvtsi2sd xmm0, dword [rdi]
+	cvtsi2sd xmm0, rax
+	cvtsi2sd xmm0, qword [rdi]
+
+	cvtsi2ss xmm0, eax
+	cvtsi2ss xmm0, [rdi]	; Compatibility
+	cvtsi2ss xmm0, dword [rdi]
+	cvtsi2ss xmm0, rax
+	cvtsi2ss xmm0, qword [rdi]
+
+	cvtss2sd xmm0, xmm1
+	cvtss2sd xmm0, [rdi]
+	cvtss2sd xmm0, dword [rdi]
+
+	cvtss2si eax, xmm1
+	cvtss2si eax, [rdi]
+	cvtss2si eax, dword [rdi]
+	cvtss2si rax, xmm1
+	cvtss2si rax, [rdi]
+	cvtss2si rax, dword [rdi]
+
+	cvttpd2dq xmm0, xmm1
+	cvttpd2dq xmm0, [rdi]
+	cvttpd2dq xmm0, oword [rdi]
+
+	cvttpd2pi mm0, xmm1
+	cvttpd2pi mm0, [rdi]
+	cvttpd2pi mm0, oword [rdi]
+
+	cvttps2dq xmm0, xmm1
+	cvttps2dq xmm0, [rdi]
+	cvttps2dq xmm0, oword [rdi]
+	
+	cvttps2pi mm0, xmm1
+	cvttps2pi mm0, [rdi]
+	cvttps2pi mm0, qword [rdi]
+
+	cvttsd2si eax, xmm1
+	cvttsd2si eax, [rdi]	; Compatibility
+	cvttsd2si eax, qword [rdi]
+	cvttsd2si rax, xmm1
+	cvttsd2si rax, [rdi]
+	cvttsd2si rax, qword [rdi]
+
+	cvttss2si eax, xmm1
+	cvttss2si eax, [rdi] 	; Compatibility
+	cvttss2si eax, dword [rdi]
+	cvttss2si rax, xmm1
+	cvttss2si rax, [rdi]
+	cvttss2si rax, dword [rdi]
+	
+	vcvtdq2pd xmm0, xmm1
+	vcvtdq2pd xmm0, [rdi]
+	vcvtdq2pd xmm0, qword [rdi]
+	vcvtdq2pd ymm0, xmm1
+	vcvtdq2pd ymm0, [rdi]
+	vcvtdq2pd ymm0, oword [rdi]
+
+	vcvtdq2ps xmm0, xmm1
+	vcvtdq2ps xmm0, [rdi]
+	vcvtdq2ps xmm0, oword [rdi]
+	vcvtdq2ps ymm0, ymm1
+	vcvtdq2ps ymm0, [rdi]
+	vcvtdq2ps ymm0, yword [rdi]
+
+	vcvtpd2dq xmm0, xmm1
+	vcvtpd2dq xmm0, oword [rdi]
+	vcvtpd2dq xmm0, ymm1
+	vcvtpd2dq xmm0, yword [rdi]
+
+	vcvtpd2ps xmm0, xmm1
+	vcvtpd2ps xmm0, oword [rdi]
+	vcvtpd2ps xmm0, ymm1
+	vcvtpd2ps xmm0, yword [rdi]
+
+	vcvtps2dq xmm0, xmm1
+	vcvtps2dq xmm0, [rdi]
+	vcvtps2dq xmm0, oword [rdi]
+	vcvtps2dq ymm0, ymm1
+	vcvtps2dq ymm0, [rdi]
+	vcvtps2dq ymm0, yword [rdi]
+
+	vcvtps2pd xmm0, xmm1
+	vcvtps2pd xmm0, [rdi]
+	vcvtps2pd xmm0, qword [rdi]
+	vcvtps2pd ymm0, xmm1
+	vcvtps2pd ymm0, [rdi]
+	vcvtps2pd ymm0, oword [rdi]
+
+	vcvtsd2si eax, xmm1
+	vcvtsd2si eax, [rdi]
+	vcvtsd2si eax, qword [rdi]
+	vcvtsd2si rax, xmm1
+	vcvtsd2si rax, [rdi]
+	vcvtsd2si rax, qword [rdi]
+
+	vcvtsd2ss xmm0, xmm1
+	vcvtsd2ss xmm0, [rdi]
+	vcvtsd2ss xmm0, qword [rdi]
+	vcvtsd2ss xmm0, xmm1, xmm2
+	vcvtsd2ss xmm0, xmm1, [rdi]
+	vcvtsd2ss xmm0, xmm1, qword [rdi]
+
+	vcvtsi2sd xmm0, eax
+	vcvtsi2sd xmm0, [rdi]	; Compatibility
+	vcvtsi2sd xmm0, dword [rdi]
+	vcvtsi2sd xmm0, rax
+	vcvtsi2sd xmm0, qword [rdi]
+	vcvtsi2sd xmm0, xmm1, eax
+	vcvtsi2sd xmm0, xmm1, [rdi]	; Compatibility
+	vcvtsi2sd xmm0, xmm1, dword [rdi]
+	vcvtsi2sd xmm0, xmm1, rax
+	vcvtsi2sd xmm0, xmm1, qword [rdi]
+
+	vcvtsi2ss xmm0, eax
+	vcvtsi2ss xmm0, [rdi]	; Compatibility
+	vcvtsi2ss xmm0, dword [rdi]
+	vcvtsi2ss xmm0, rax
+	vcvtsi2ss xmm0, qword [rdi]
+	vcvtsi2ss xmm0, xmm1, eax
+	vcvtsi2ss xmm0, xmm1, [rdi]	; Compatibility
+	vcvtsi2ss xmm0, xmm1, dword [rdi]
+	vcvtsi2ss xmm0, xmm1, rax
+	vcvtsi2ss xmm0, xmm1, qword [rdi]
+
+	vcvtss2sd xmm0, xmm1
+	vcvtss2sd xmm0, [rdi]
+	vcvtss2sd xmm0, dword [rdi]
+	vcvtss2sd xmm0, xmm1, xmm2
+	vcvtss2sd xmm0, xmm1, [rdi]
+	vcvtss2sd xmm0, xmm1, dword [rdi]
+
+	vcvtss2si eax, xmm1
+	vcvtss2si eax, [rdi]
+	vcvtss2si eax, dword [rdi]
+	vcvtss2si rax, xmm1
+	vcvtss2si rax, [rdi]
+	vcvtss2si rax, dword [rdi]
+
+	vcvttpd2dq xmm0, xmm1
+	vcvttpd2dq xmm0, oword [rdi]
+	vcvttpd2dq xmm0, ymm1
+	vcvttpd2dq xmm0, yword [rdi]
+
+	vcvttps2dq xmm0, xmm1
+	vcvttps2dq xmm0, [rdi]
+	vcvttps2dq xmm0, oword [rdi]
+	vcvttps2dq ymm0, ymm1
+	vcvttps2dq ymm0, [rdi]
+	vcvttps2dq ymm0, yword [rdi]
+	
+	vcvttsd2si eax, xmm1
+	vcvttsd2si eax, [rdi]	; Compatibility
+	vcvttsd2si eax, qword [rdi]
+	vcvttsd2si rax, xmm1
+	vcvttsd2si rax, [rdi]
+	vcvttsd2si rax, qword [rdi]
+
+	vcvttss2si eax, xmm1
+	vcvttss2si eax, [rdi] 	; Compatibility
+	vcvttss2si eax, dword [rdi]
+	vcvttss2si rax, xmm1
+	vcvttss2si rax, [rdi]
+	vcvttss2si rax, dword [rdi]
diff --git a/test/br2222615.asm b/test/br2222615.asm
new file mode 100644
index 00000000..7acef6c8
--- /dev/null
+++ b/test/br2222615.asm
@@ -0,0 +1,19 @@
+;Testname=noerror; Arguments=-fbin -obr2222615.bin; Files=stdout stderr br2222615.bin
+;Testname=error; Arguments=-DERROR -fbin -obr2222615.bin; Files=stdout stderr br2222615.bin
+
+%macro bluttan 0
+	nop
+%endmacro
+
+%ifnmacro bluttan
+ %error "bluttan is a macro"
+%endif
+
+%ifmacro blej
+ %error "blej is not a macro"
+%endif
+
+%ifdef ERROR
+ %ifnmacro
+ %endif
+%endif
diff --git a/test/br890790.asm b/test/br890790.asm
new file mode 100644
index 00000000..a0023825
--- /dev/null
+++ b/test/br890790.asm
@@ -0,0 +1,7 @@
+;Testname=test; Arguments=-fbin -obr890790.bin; Files=stdout stderr br890790.bin
+%rep 5
+  db 0
+  %include "br890790_i.asm"
+%endrep
+
+db 1
diff --git a/test/br890790_i.asm b/test/br890790_i.asm
new file mode 100644
index 00000000..7ff797f3
--- /dev/null
+++ b/test/br890790_i.asm
@@ -0,0 +1 @@
+db 2
diff --git a/test/crc32.asm b/test/crc32.asm
new file mode 100644
index 00000000..c1ddb296
--- /dev/null
+++ b/test/crc32.asm
@@ -0,0 +1,37 @@
+;Testname=test; Arguments=-fbin -ocrc32.bin; Files=stdout stderr crc32.bin
+
+	bits 16
+
+	crc32 eax,cl
+	crc32 eax,byte [di]
+	crc32 eax,cx
+	crc32 eax,word [di]
+	crc32 eax,ecx
+	crc32 eax,dword [di]
+
+	bits 32
+	align 16
+
+	crc32 eax,cl
+	crc32 eax,byte [edi]
+	crc32 eax,cx
+	crc32 eax,word [edi]
+	crc32 eax,ecx
+	crc32 eax,dword [edi]
+
+	bits 64
+	align 16
+
+	crc32 eax,cl
+	crc32 eax,byte [rdi]
+	crc32 eax,r9b
+	crc32 eax,cx
+	crc32 eax,word [rdi]
+	crc32 eax,ecx
+	crc32 eax,dword [rdi]
+	crc32 rax,cl
+	crc32 rax,byte [rdi]
+	crc32 rax,r9b
+	crc32 rax,rcx
+	crc32 rax,qword [rdi]
+	crc32 rax,r9
diff --git a/test/elf64so.asm b/test/elf64so.asm
new file mode 100644
index 00000000..f1b23464
--- /dev/null
+++ b/test/elf64so.asm
@@ -0,0 +1,118 @@
+; test source file for assembling to ELF64 shared library
+; build with:
+;    nasm -f elf64 elf64so.asm
+;    ld -shared -o elf64so.so elf64so.o
+; test with:
+;    gcc -o elf64so elftest64.c ./elf64so.so
+;    ./elf64so
+
+; This file should test the following:
+; [1] Define and export a global text-section symbol
+; [2] Define and export a global data-section symbol
+; [3] Define and export a global BSS-section symbol
+; [4] Define a non-global text-section symbol
+; [5] Define a non-global data-section symbol
+; [6] Define a non-global BSS-section symbol
+; [7] Define a COMMON symbol
+; [8] Define a NASM local label
+; [9] Reference a NASM local label
+; [10] Import an external symbol
+; [11] Make a PC-relative call to an external symbol
+; [12] Reference a text-section symbol in the text section
+; [13] Reference a data-section symbol in the text section
+; [14] Reference a BSS-section symbol in the text section
+; [15] Reference a text-section symbol in the data section
+; [16] Reference a data-section symbol in the data section
+; [17] Reference a BSS-section symbol in the data section
+
+	  BITS 64
+	  GLOBAL lrotate:function ; [1]
+	  GLOBAL greet_s:function ; [1]
+	  GLOBAL greet_m:function ; [1]
+	  GLOBAL asmstr:data asmstr.end-asmstr ; [2]
+	  GLOBAL textptr:data 8	; [2]
+	  GLOBAL selfptr:data 8	; [2]
+	  GLOBAL useless:data 8	; [3]
+	  GLOBAL integer:data 8	; [3]
+	  EXTERN printf		; [10]
+	  COMMON commvar 8:8	; [7]
+	  EXTERN _GLOBAL_OFFSET_TABLE_
+
+	  SECTION .text
+
+; prototype: long lrotate(long x, int num);
+lrotate:			; [1]
+	  push rbp
+	  mov rbp,rsp
+	  mov rax,rdi
+	  mov rcx,rsi
+.label	  rol rax,1		; [4] [8]
+	  loop .label		; [9] [12]
+	  mov rsp,rbp
+	  pop rbp
+	  ret
+
+;; prototype: void greet_*(void);
+;; 
+;;  Arguments are:	rdi - rsi - rdx - rcx - r8 - r9
+;;  Registers:		rbx, rbp, r12-r15 are saved
+;; greet_s() is Small PIC model, greet_m() is Medium PIC model
+;; (Large model cannot be linked with other code)
+;;
+greet_s:
+	  ;;  This instruction is useless, this is only a test...
+	  cmp qword [rel integer wrt ..got],0
+	  mov rax,[rel commvar wrt ..got] ; &commvar
+	  mov rcx,[rax]			  ; commvar
+	  mov rax,[rel integer wrt ..got] ; &integer
+	  mov rsi,[rax]
+	  lea rdx,[rsi+1]
+	  mov [rel localint],rdx ; localint = integer+1
+	  mov rax,[rel localptr] ; localptr
+	  mov rdx,[rax]		 ; *localptr = localint
+	  lea rdi,[rel printfstr]
+	  xor eax,eax		; No fp arguments
+	  jmp printf wrt ..plt	; [10]
+
+greet_m:
+	  push r15		; Used by convention...
+	  lea r15,[rel _GLOBAL_OFFSET_TABLE_]
+	  mov rax,[rel commvar wrt ..got] ; &commvar
+	  mov rcx,[rax]			  ; commvar
+	  mov rax,[rel integer wrt ..got] ; &integer
+	  mov rsi,[rax]
+	  lea rdx,[rsi+1]
+	  mov rax,localint wrt ..gotoff	 ; &localint - r15
+	  mov [rax+r15],rdx	 ; localint = integer+1
+	  mov rax,localptr wrt ..gotoff ; &localptr - r15
+	  mov rax,[rax+r15]	 ; localptr
+	  mov rdx,[rax]		 ; *localptr = localint
+	  mov rdi,printfstr wrt ..gotoff ; &printfstr - r15
+	  add rdi,r15		; &printfstr 
+	  xor eax,eax		; No fp arguments
+	  pop r15
+	  jmp printf wrt ..plt	; [10]
+
+	  SECTION .data
+
+; a string
+asmstr	  db 'hello, world', 0	; [2]
+.end:
+
+; a string for Printf
+printfstr db "integer=%ld, localint=%ld, commvar=%ld", 10, 0
+
+; some pointers
+localptr  dq localint		; [5] [17]
+textptr	  dq greet_s wrt ..sym	; [15]
+selfptr	  dq selfptr wrt ..sym	; [16]
+
+	  SECTION .bss
+; a useless symbol
+useless	  resq 1
+	
+; an integer
+integer	  resq 1		; [3]
+
+; a local integer
+localint  resq 1		; [6]
diff --git a/test/elftest.c b/test/elftest64.c
similarity index 56%
copy from test/elftest.c
copy to test/elftest64.c
index 42b3f7e9..1f3dec1f 100644
--- a/test/elftest.c
+++ b/test/elftest64.c
@@ -1,36 +1,41 @@
 /*
- * test source file for assembling to ELF
- * build with:
- *    nasm -f elf elftest.asm
- *    gcc -o elftest elftest.c elftest.o
- * (assuming your gcc is ELF)
+ *  build with:
+ *	nasm -f elf64 elf64so.asm
+ *	ld -shared -o elf64so.so elf64so.o
+ * test with:
+ *	gcc -o elf64so elftest64.c ./elf64so.so
+ *	./elf64so
  */
 
 #include <stdio.h>
 #include <inttypes.h>
 
-extern int lrotate(int32_t, int);
-extern void greet(void);
+extern long lrotate(long, int);
+extern void greet_s(void);
+extern void greet_m(void);
 extern int8_t asmstr[];
 extern void *selfptr;
 extern void *textptr;
-extern int integer, commvar;
+extern long integer;
+long commvar;
 
 int main(void)
 {
 
     printf("Testing lrotate: should get 0x00400000, 0x00000001\n");
     printf("lrotate(0x00040000, 4) = 0x%08lx\n", lrotate(0x40000, 4));
-    printf("lrotate(0x00040000, 14) = 0x%08lx\n", lrotate(0x40000, 14));
+    printf("lrotate(0x00040000, 46) = 0x%08lx\n", lrotate(0x40000, 46));
 
     printf("This string should read `hello, world': `%s'\n", asmstr);
 
+    printf("&integer = %p, &commvar = %p\n", &integer, &commvar);
     printf("The integers here should be 1234, 1235 and 4321:\n");
     integer = 1234;
     commvar = 4321;
-    greet();
+    greet_s();
+    greet_m();
 
-    printf("These pointers should be equal: %p and %p\n", &greet, textptr);
+    printf("These pointers should be equal: %p and %p\n", &greet_s, textptr);
 
     printf("So should these: %p and %p\n", selfptr, &selfptr);
 
diff --git a/test/fwdopt.asm b/test/fwdopt.asm
new file mode 100644
index 00000000..48dbc3fc
--- /dev/null
+++ b/test/fwdopt.asm
@@ -0,0 +1,133 @@
+;Testname=test; Arguments=-fbin -ofwdopt.bin; Files=stdout stderr fwdopt.bin
+n0:	jmp n1
+n1:	jmp n2
+n2:	jmp n3
+n3:	jmp n4
+n4:	jmp n5
+n5:	jmp n6
+n6:	jmp n7
+n7:	jmp n8
+n8:	jmp n9
+n9:	jmp n10
+n10:	jmp n11
+n11:	jmp n12
+n12:	jmp n13
+n13:	jmp n14
+n14:	jmp n15
+n15:	jmp n16
+n16:	jmp n17
+n17:	jmp n18
+n18:	jmp n19
+n19:	jmp n20
+n20:	jmp n21
+n21:	jmp n22
+n22:	jmp n23
+n23:	jmp n24
+n24:	jmp n25
+n25:	jmp n26
+n26:	jmp n27
+n27:	jmp n28
+n28:	jmp n29
+n29:	jmp n30
+n30:	jmp n31
+n31:	jmp n32
+n32:	jmp n33
+n33:	jmp n34
+n34:	jmp n35
+n35:	jmp n36
+n36:	jmp n37
+n37:	jmp n38
+n38:	jmp n39
+n39:	jmp n40
+n40:	jmp n41
+n41:	jmp n42
+n42:	jmp n43
+n43:	jmp n44
+n44:	jmp n45
+n45:	jmp n46
+n46:	jmp n47
+n47:	jmp n48
+n48:	jmp n49
+n49:	jmp n50
+n50:	jmp n51
+n51:	jmp n52
+n52:	jmp n53
+n53:	jmp n54
+n54:	jmp n55
+n55:	jmp n56
+n56:	jmp n57
+n57:	jmp n58
+n58:	jmp n59
+n59:	jmp n60
+n60:	jmp n61
+n61:	jmp n62
+n62:	jmp n63
+n63:	jmp n64
+n64:	jmp n65
+n65:	jmp n66
+n66:	jmp n67
+n67:	jmp n68
+n68:	jmp n69
+n69:	jmp n70
+n70:	jmp n71
+n71:	jmp n72
+n72:	jmp n73
+n73:	jmp n74
+n74:	jmp n75
+n75:	jmp n76
+n76:	jmp n77
+n77:	jmp n78
+n78:	jmp n79
+n79:	jmp n80
+n80:	jmp n81
+n81:	jmp n82
+n82:	jmp n83
+n83:	jmp n84
+n84:	jmp n85
+n85:	jmp n86
+n86:	jmp n87
+n87:	jmp n88
+n88:	jmp n89
+n89:	jmp n90
+n90:	jmp n91
+n91:	jmp n92
+n92:	jmp n93
+n93:	jmp n94
+n94:	jmp n95
+n95:	jmp n96
+n96:	jmp n97
+n97:	jmp n98
+n98:	jmp n99
+n99:	jmp n100
+n100:	jmp n101
+n101:	jmp n102
+n102:	jmp n103
+n103:	jmp n104
+n104:	jmp n105
+n105:	jmp n106
+n106:	jmp n107
+n107:	jmp n108
+n108:	jmp n109
+n109:	jmp n110
+n110:	jmp n111
+n111:	jmp n112
+n112:	jmp n113
+n113:	jmp n114
+n114:	jmp n115
+n115:	jmp n116
+n116:	jmp n117
+n117:	jmp n118
+n118:	jmp n119
+n119:	jmp n120
+n120:	jmp n121
+n121:	jmp n122
+n122:	jmp n123
+n123:	jmp n124
+n124:	jmp n125
+n125:	jmp n126
+n126:	jmp n127
+n127:	jmp n0
+
+	;;  This should emit exactly 3 NOP bytes
+	times 260-($-$$) nop
+	hlt
diff --git a/test/fwdoptpp.asm b/test/fwdoptpp.asm
new file mode 100644
index 00000000..e1f5dd63
--- /dev/null
+++ b/test/fwdoptpp.asm
@@ -0,0 +1,150 @@
+;Testname=error; Arguments=-fbin -DERROR -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+;Testname=fatal; Arguments=-fbin -DFATAL -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+;Testname=warning; Arguments=-fbin -DWARNING -ofwdoptpp.bin; Files=stdout stderr fwdoptpp.bin
+
+%ifndef ERROR
+  %ifndef FATAL
+    %ifndef WARNING
+      %define ERROR 1
+    %endif
+  %endif
+%endif
+	
+n0:	jmp n1
+n1:	jmp n2
+n2:	jmp n3
+n3:	jmp n4
+n4:	jmp n5
+n5:	jmp n6
+n6:	jmp n7
+n7:	jmp n8
+n8:	jmp n9
+n9:	jmp n10
+n10:	jmp n11
+n11:	jmp n12
+n12:	jmp n13
+n13:	jmp n14
+n14:	jmp n15
+n15:	jmp n16
+n16:	jmp n17
+n17:	jmp n18
+n18:	jmp n19
+n19:	jmp n20
+n20:	jmp n21
+n21:	jmp n22
+n22:	jmp n23
+n23:	jmp n24
+n24:	jmp n25
+n25:	jmp n26
+n26:	jmp n27
+n27:	jmp n28
+n28:	jmp n29
+n29:	jmp n30
+n30:	jmp n31
+n31:	jmp n32
+n32:	jmp n33
+n33:	jmp n34
+n34:	jmp n35
+n35:	jmp n36
+n36:	jmp n37
+n37:	jmp n38
+n38:	jmp n39
+n39:	jmp n40
+n40:	jmp n41
+n41:	jmp n42
+n42:	jmp n43
+n43:	jmp n44
+n44:	jmp n45
+n45:	jmp n46
+n46:	jmp n47
+n47:	jmp n48
+n48:	jmp n49
+n49:	jmp n50
+n50:	jmp n51
+n51:	jmp n52
+n52:	jmp n53
+n53:	jmp n54
+n54:	jmp n55
+n55:	jmp n56
+n56:	jmp n57
+n57:	jmp n58
+n58:	jmp n59
+n59:	jmp n60
+n60:	jmp n61
+n61:	jmp n62
+n62:	jmp n63
+n63:	jmp n64
+n64:	jmp n65
+n65:	jmp n66
+n66:	jmp n67
+n67:	jmp n68
+n68:	jmp n69
+n69:	jmp n70
+n70:	jmp n71
+n71:	jmp n72
+n72:	jmp n73
+n73:	jmp n74
+n74:	jmp n75
+n75:	jmp n76
+n76:	jmp n77
+n77:	jmp n78
+n78:	jmp n79
+n79:	jmp n80
+n80:	jmp n81
+n81:	jmp n82
+n82:	jmp n83
+n83:	jmp n84
+n84:	jmp n85
+n85:	jmp n86
+n86:	jmp n87
+n87:	jmp n88
+n88:	jmp n89
+n89:	jmp n90
+n90:	jmp n91
+n91:	jmp n92
+n92:	jmp n93
+n93:	jmp n94
+n94:	jmp n95
+n95:	jmp n96
+n96:	jmp n97
+n97:	jmp n98
+n98:	jmp n99
+n99:	jmp n100
+n100:	jmp n101
+n101:	jmp n102
+n102:	jmp n103
+n103:	jmp n104
+n104:	jmp n105
+n105:	jmp n106
+n106:	jmp n107
+n107:	jmp n108
+n108:	jmp n109
+n109:	jmp n110
+n110:	jmp n111
+n111:	jmp n112
+n112:	jmp n113
+n113:	jmp n114
+n114:	jmp n115
+n115:	jmp n116
+n116:	jmp n117
+n117:	jmp n118
+n118:	jmp n119
+n119:	jmp n120
+n120:	jmp n121
+n121:	jmp n122
+n122:	jmp n123
+n123:	jmp n124
+n124:	jmp n125
+n125:	jmp n126
+n126:	jmp n127
+n127:	jmp n0
+	
+%if ($-$$) > 257
+  %ifdef FATAL
+    %fatal "Out of space!"
+  %elifdef ERROR
+    %error "Out of space!"
+  %elifdef WARNING
+    %warning "Out of space!"
+  %endif
+%endif
diff --git a/test/gotoff64.asm b/test/gotoff64.asm
new file mode 100644
index 00000000..05f5882b
--- /dev/null
+++ b/test/gotoff64.asm
@@ -0,0 +1,25 @@
+;Testname=noerr; Arguments=-felf64 -ogotoff64.o; Files=stdout stderr gotoff64.o
+;Testname=err; Arguments=-DERROR -felf64 -ogotoff64.o; Files=stdout stderr gotoff64.o
+
+	bits 64
+	default rel
+
+	extern foo
+
+	mov r15,[foo wrt ..got]
+	lea r12,[foo wrt ..got]
+%ifdef ERROR
+	lea rax,[foo wrt ..gotoff]
+	mov rax,[foo wrt ..gotoff]
+%endif
+
+	default abs
+
+	mov r15,[foo wrt ..got]
+	lea r12,[foo wrt ..got]
+	mov rax,[qword foo wrt ..got]
+%ifdef ERROR
+	lea rax,[foo wrt ..gotoff]
+	mov rax,[foo wrt ..gotoff]
+%endif
+	mov rax,[qword foo wrt ..gotoff]
diff --git a/test/ifelse.asm b/test/ifelse.asm
new file mode 100644
index 00000000..bbb0d796
--- /dev/null
+++ b/test/ifelse.asm
@@ -0,0 +1,46 @@
+;Testname=ifelse; Arguments=-fbin -oifelse.bin; Files=stdout stderr ifelse.bin
+
+;No problems -> db 3
+%if 0
+ db 0
+%elif 0 > 0
+ db 1
+%elif 1 < 1
+ db 2
+%else
+ db 3
+%endif
+
+;Garbage after else, elif after else -> db 5
+%if 0
+  db 4
+%else trailing garbage
+  db 5
+%elif 1
+  db 6
+%endif
+
+;Garbage after endif ->
+%if 0
+  db 7
+%endif trailing garbage
+
+;else after else -> db 9
+%if 0
+  db 8
+%else
+  db 9
+%else
+  db 10
+%endif
+
+;Problem preprocessed out, no warning ->
+%if 0
+  %if 1
+    db 11
+  %else
+    db 12
+  %else
+    db 13
+  %endif
+%endif
diff --git a/test/immwarn.asm b/test/immwarn.asm
new file mode 100644
index 00000000..8bffbfae
--- /dev/null
+++ b/test/immwarn.asm
@@ -0,0 +1,91 @@
+;Testname=onowarn; Arguments=-Ox -DOPT=1 -DWARN=0 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=owarn; Arguments=-Ox -DOPT=1 -DWARN=1 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=nowarn; Arguments=-O0 -DOPT=0 -DWARN=0 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+;Testname=warn; Arguments=-O0 -DOPT=1 -DWARN=1 -fbin -oimmwarn.bin; Files=stdout stderr immwarn.bin
+
+%ifndef WARN
+  %define WARN 1
+%endif
+
+	bits 16
+	push 1
+%if WARN
+	push 0ffffffffh
+%endif
+	push -1
+	push 0ffffh
+	push byte 0FFFFh
+
+	add ax,0FFFFh
+%if WARN
+	add ax,0FFFFFFFFh
+%endif
+	add ax,-1
+	add ax,byte 0FFFFh
+%if WARN
+	add ax,byte 0FFFFFFFFh
+%endif
+	add ax,-1
+
+	add cx,0FFFFh
+%if WARN
+	add cx,0FFFFFFFFh
+%endif
+	add cx,-1
+	add cx,byte 0FFFFh
+%if WARN
+	add cx,byte 0FFFFFFFFh
+%endif
+	add cx,-1
+
+	bits 32
+	push 1
+	push 0ffffffffh
+	push -1
+	push 0ffffh
+
+	push byte 1
+%if WARN
+	push byte 0ffffh
+%endif
+	push byte -1
+
+	push word 1
+	push word 0ffffh
+	push word -1
+
+	push dword 1
+	push dword 0ffffffffh
+	push dword -1
+
+	add eax,0FFFFh
+	add eax,0FFFFFFFFh
+	add eax,-1
+
+	add ecx,0FFFFh
+	add ecx,0FFFFFFFFh
+	add ecx,-1
+
+	bits 64
+	mov eax,7fffffffh
+	mov eax,80000000h
+	mov rax,7fffffffh
+	mov rax,80000000h
+%if WARN
+	mov rax,dword 80000000h
+%endif
+	add rcx,0FFFFh
+%if WARN
+	add rcx,0FFFFFFFFh
+%endif
+	add rcx,-1
+
+	add ecx,0FFFFh
+	add ecx,0FFFFFFFFh
+	add ecx,-1
+
+	push byte 1
+%if WARN
+	push byte 0ffffffffh
+%endif
+	push byte -1
diff --git a/test/imul.asm b/test/imul.asm
new file mode 100644
index 00000000..b1777120
--- /dev/null
+++ b/test/imul.asm
@@ -0,0 +1,90 @@
+;Testname=nowarn; Arguments=-fbin -oimul.bin; Files=stdout stderr imul.bin
+;Testname=warn; Arguments=-DWARN -fbin -oimul.bin; Files=stdout stderr imul.bin
+
+%macro test 1-2 5
+	bits %1
+
+%undef MEM
+%if %1 == 16
+  %define MEM [di]
+%elif %1 == 32
+  %define MEM [edi]
+%elif %1 == 64
+  %define MEM [rdi]
+%endif
+
+	imul al
+	imul byte MEM
+	imul ax
+	imul word MEM
+	imul eax
+	imul dword MEM
+%if %1 == 64
+	imul rdx
+	imul qword MEM
+%endif
+	
+	imul ax,cx
+	imul ax,MEM
+	imul ax,word MEM
+	imul eax,ecx
+	imul eax,MEM
+	imul eax,dword MEM
+%if %1 == 64
+	imul rax,rcx
+	imul rax,MEM
+	imul rax,qword MEM
+%endif
+
+	imul ax,cx,%2
+	imul ax,cx,byte %2
+	imul ax,MEM,%2
+	imul ax,word MEM,%2
+	imul eax,ecx,%2
+	imul eax,ecx,byte %2
+	imul eax,MEM,%2
+	imul eax,dword MEM,%2
+%if %1 == 64
+	imul rax,rcx,%2
+	imul rax,rcx,byte %2
+	imul rax,MEM,%2
+	imul rax,qword MEM,%2
+%endif
+
+	imul ax,%2
+	imul ax,byte %2
+	imul eax,%2
+	imul eax,byte %2
+%if %1 == 64
+	imul rax,%2
+	imul rax,byte %2
+%endif
+
+	imul ax,cx,0x1234
+	imul ax,MEM,0x1234
+	imul ax,word MEM,0x1234
+	imul eax,ecx,0x12345678
+	imul eax,MEM,0x12345678
+	imul eax,dword MEM,0x12345678
+%if %1 == 64
+	imul rax,rcx,0x12345678
+	imul rax,MEM,0x12345678
+	imul rax,qword MEM,0x12345678
+%endif
+
+	imul ax,0x1234
+	imul eax,0x12345678
+%if %1 == 64
+	imul rax,0x12345678
+%endif
+%endmacro
+
+	test 16
+	test 32
+	test 64
+
+%ifdef WARN
+	test 16,0x999
+	test 32,0x999999
+	test 64,0x999999999
+%endif
diff --git a/test/optimization.asm b/test/optimization.asm
new file mode 100644
index 00000000..d78209d9
--- /dev/null
+++ b/test/optimization.asm
@@ -0,0 +1,104 @@
+;Testname=O0; Arguments=-O0 -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+;Testname=O1; Arguments=-O1 -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+;Testname=Ox; Arguments=-Ox -fbin -ooptimization.bin; Files=stdout stderr optimization.bin
+
+BITS 32
+
+; Simple
+jmp foo
+times 124 nop
+foo:
+
+; Must start short to converge optimally
+jmp car
+times 127 nop
+car:
+
+; Always near
+jmp cdr
+times 128 nop
+cdr:
+
+
+; Simple
+add eax, quux2 - quux1
+quux1:
+times 127 nop
+quux2:
+
+; Must start short
+corge1:
+add eax, corge2 - corge1
+times 127 - 3 nop
+corge2:
+
+
+; Simple
+lea eax, [bolug2-bolug1]
+bolug1:
+times 127 nop
+bolug2:
+
+; Must start short
+calog1:
+lea eax, [calog2-calog1]
+times 127 - 3 nop
+calog2:
+
+
+; Simple
+lea eax, [eax+dolug2-dolug1]
+dolug1:
+times 127 nop
+dolug2:
+
+; Must start short
+ealog1:
+lea eax, [eax+ealog2-ealog1]
+times 127 - 3 nop
+ealog2:
+
+; Must stay long!
+lea eax, [eax+folug2-folug1]
+folug1:
+times 128 nop
+folug2:
+
+; Must stay long!
+galog1:
+lea eax, [eax+galog2-galog1]
+times 128 - 3 nop
+galog2:
+
+; Sbyte tests...
+onetwentysix	equ 126
+onetwentynine	equ 129
+	
+add eax,onetwentyseven		; sbyte (forward)
+add eax,onetwentyeight		; not sbyte (forward)
+add eax,onetwentyseven		; sbyte (forward)
+add eax,onetwentysix		; sbyte (backward)
+add eax,onetwentynine		; not sbyte (backward)
+add ecx,onetwentyseven		; sbyte (forward)
+add ecx,onetwentyeight		; not sbyte (forward)
+add ecx,onetwentyseven		; sbyte (forward)
+add ecx,onetwentysix		; sbyte (backward)
+add ecx,onetwentynine		; not sbyte (backward)
+	
+onetwentyseven	equ 127
+onetwentyeight	equ 128
+
+; Simple
+add eax, holug2-holug1
+holug1:
+times 127 nop
+holug2:
+
+; Must start short
+ialog1:
+add eax, ialog2-ialog1
+times 127 - 3 nop
+ialog2:
+	
+; Do not confuse forward references and segmentless addresses!
+jmp 12345
diff --git a/test/pinsr16.asm b/test/pinsr16.asm
new file mode 100644
index 00000000..f971598c
--- /dev/null
+++ b/test/pinsr16.asm
@@ -0,0 +1,52 @@
+	bits 16
+
+	pinsrw mm0,eax,0
+	pinsrw mm1,si,0
+	pinsrw mm2,[bx],0
+	pinsrw mm3,word [bx],0
+
+	pinsrb xmm0,eax,0
+	pinsrb xmm1,sil,0
+;	pinsrb xmm1,bh,0
+	pinsrb xmm2,[bx],0
+	pinsrb xmm3,byte [bx],0
+
+	pinsrw xmm0,eax,0
+	pinsrw xmm1,si,0
+	pinsrw xmm2,[bx],0
+	pinsrw xmm3,word [bx],0
+
+	pinsrd xmm0,eax,0
+	pinsrd xmm1,esi,0
+	pinsrd xmm2,[bx],0
+	pinsrd xmm3,dword [bx],0
+
+	vpinsrb xmm0,eax,0
+	vpinsrb xmm1,bl,0
+	vpinsrb xmm2,[bx],0
+	vpinsrb xmm3,byte [bx],0
+
+	vpinsrw xmm0,eax,0
+	vpinsrw xmm1,si,0
+	vpinsrw xmm2,[bx],0
+	vpinsrw xmm3,word [bx],0
+
+	vpinsrd xmm0,eax,0
+	vpinsrd xmm1,esi,0
+	vpinsrd xmm2,[bx],0
+	vpinsrd xmm3,dword [bx],0
+
+	vpinsrb xmm4,xmm0,eax,0
+	vpinsrb xmm5,xmm1,bl,0
+	vpinsrb xmm6,xmm2,[bx],0
+	vpinsrb xmm7,xmm3,byte [bx],0
+
+	vpinsrw xmm4,xmm0,eax,0
+	vpinsrw xmm5,xmm1,si,0
+	vpinsrw xmm6,xmm2,[bx],0
+	vpinsrw xmm7,xmm3,word [bx],0
+
+	vpinsrd xmm4,xmm0,eax,0
+	vpinsrd xmm5,xmm1,esi,0
+	vpinsrd xmm6,xmm2,[bx],0
+	vpinsrd xmm7,xmm3,dword [bx],0
diff --git a/test/pinsr32.asm b/test/pinsr32.asm
new file mode 100644
index 00000000..834d1866
--- /dev/null
+++ b/test/pinsr32.asm
@@ -0,0 +1,52 @@
+	bits 32
+
+	pinsrw mm0,eax,0
+	pinsrw mm1,si,0
+	pinsrw mm2,[ecx],0
+	pinsrw mm3,word [ecx],0
+
+	pinsrb xmm0,eax,0
+	pinsrb xmm1,sil,0
+;	pinsrb xmm1,bh,0
+	pinsrb xmm2,[ecx],0
+	pinsrb xmm3,byte [ecx],0
+
+	pinsrw xmm0,eax,0
+	pinsrw xmm1,si,0
+	pinsrw xmm2,[ecx],0
+	pinsrw xmm3,word [ecx],0
+
+	pinsrd xmm0,eax,0
+	pinsrd xmm1,esi,0
+	pinsrd xmm2,[ecx],0
+	pinsrd xmm3,dword [ecx],0
+
+	vpinsrb xmm0,eax,0
+	vpinsrb xmm1,bl,0
+	vpinsrb xmm2,[ecx],0
+	vpinsrb xmm3,byte [ecx],0
+
+	vpinsrw xmm0,eax,0
+	vpinsrw xmm1,si,0
+	vpinsrw xmm2,[ecx],0
+	vpinsrw xmm3,word [ecx],0
+
+	vpinsrd xmm0,eax,0
+	vpinsrd xmm1,esi,0
+	vpinsrd xmm2,[ecx],0
+	vpinsrd xmm3,dword [ecx],0
+
+	vpinsrb xmm4,xmm0,eax,0
+	vpinsrb xmm5,xmm1,bl,0
+	vpinsrb xmm6,xmm2,[ecx],0
+	vpinsrb xmm7,xmm3,byte [ecx],0
+
+	vpinsrw xmm4,xmm0,eax,0
+	vpinsrw xmm5,xmm1,si,0
+	vpinsrw xmm6,xmm2,[ecx],0
+	vpinsrw xmm7,xmm3,word [ecx],0
+
+	vpinsrd xmm4,xmm0,eax,0
+	vpinsrd xmm5,xmm1,esi,0
+	vpinsrd xmm6,xmm2,[ecx],0
+	vpinsrd xmm7,xmm3,dword [ecx],0
diff --git a/test/pinsr64.asm b/test/pinsr64.asm
new file mode 100644
index 00000000..bf837e9e
--- /dev/null
+++ b/test/pinsr64.asm
@@ -0,0 +1,68 @@
+	bits 64
+
+	pinsrw mm0,eax,0
+	pinsrw mm1,si,0
+	pinsrw mm2,[rcx],0
+	pinsrw mm3,word [rcx],0
+
+	pinsrb xmm0,eax,0
+	pinsrb xmm1,sil,0
+;	pinsrb xmm1,bh,0
+	pinsrb xmm2,[rcx],0
+	pinsrb xmm3,byte [rcx],0
+
+	pinsrw xmm0,eax,0
+	pinsrw xmm1,si,0
+	pinsrw xmm2,[rcx],0
+	pinsrw xmm3,word [rcx],0
+
+	pinsrd xmm0,eax,0
+	pinsrd xmm1,esi,0
+	pinsrd xmm2,[rcx],0
+	pinsrd xmm3,dword [rcx],0
+
+	pinsrq xmm0,rax,0
+	pinsrq xmm1,rsi,0
+	pinsrq xmm2,[rcx],0
+	pinsrq xmm3,qword [rcx],0
+
+	vpinsrb xmm0,eax,0
+	vpinsrb xmm1,sil,0
+	vpinsrb xmm2,[rcx],0
+	vpinsrb xmm3,byte [rcx],0
+
+	vpinsrw xmm0,eax,0
+	vpinsrw xmm1,si,0
+	vpinsrw xmm2,[rcx],0
+	vpinsrw xmm3,word [rcx],0
+
+	vpinsrd xmm0,eax,0
+	vpinsrd xmm1,esi,0
+	vpinsrd xmm2,[rcx],0
+	vpinsrd xmm3,dword [rcx],0
+
+	vpinsrq xmm0,rax,0
+	vpinsrq xmm1,rsi,0
+	vpinsrq xmm2,[rcx],0
+	vpinsrq xmm3,qword [rcx],0
+
+	vpinsrb xmm4,xmm0,eax,0
+	vpinsrb xmm5,xmm1,sil,0
+	vpinsrb xmm6,xmm2,[rcx],0
+	vpinsrb xmm7,xmm3,byte [rcx],0
+
+	vpinsrw xmm4,xmm0,eax,0
+	vpinsrw xmm5,xmm1,si,0
+	vpinsrw xmm6,xmm2,[rcx],0
+	vpinsrw xmm7,xmm3,word [rcx],0
+
+	vpinsrd xmm4,xmm0,eax,0
+	vpinsrd xmm5,xmm1,esi,0
+	vpinsrd xmm6,xmm2,[rcx],0
+	vpinsrd xmm7,xmm3,dword [rcx],0
+
+	vpinsrq xmm4,xmm0,rax,0
+	vpinsrq xmm5,xmm1,rsi,0
+	vpinsrq xmm6,xmm2,[rcx],0
+	vpinsrq xmm7,xmm3,qword [rdx],0
+	
\ No newline at end of file
diff --git a/test/popcnt.asm b/test/popcnt.asm
new file mode 100644
index 00000000..00096198
--- /dev/null
+++ b/test/popcnt.asm
@@ -0,0 +1,32 @@
+;Testname=test; Arguments=-fbin -opopcnt.bin; Files=stdout stderr popcnt.bin
+
+	bits 16
+
+	popcnt ax,cx
+	popcnt ax,[si]
+	popcnt ax,word [si]
+	popcnt eax,ecx
+	popcnt eax,[si]
+	popcnt eax,dword [si]
+
+	bits 32
+
+	popcnt ax,cx
+	popcnt ax,[esi]
+	popcnt ax,word [esi]
+	popcnt eax,ecx
+	popcnt eax,[esi]
+	popcnt eax,dword [esi]
+
+	bits 64
+
+	popcnt ax,cx
+	popcnt ax,[rsi]
+	popcnt ax,word [rsi]
+	popcnt eax,ecx
+	popcnt eax,[rsi]
+	popcnt eax,dword [rsi]
+	popcnt rax,rcx
+	popcnt rax,[rsi]
+	popcnt rax,qword [rsi]
+	
\ No newline at end of file
diff --git a/test/ppindirect.asm b/test/ppindirect.asm
new file mode 100644
index 00000000..0a30d075
--- /dev/null
+++ b/test/ppindirect.asm
@@ -0,0 +1,42 @@
+;Testname=test; Arguments=-E -o ppindirect.out; Files=ppindirect.out
+
+; Fun tests of the preprocessor indirection mode...
+
+%assign foo1		11
+%assign foo11		1111
+%assign foo2		22
+%assign foo22		2222
+%assign foo3		33
+%assign foo33		3333
+%assign n		2
+foo%[foo%[n]]*100
+foo%[n]*100
+%assign foo%[foo%[n]]	foo%[foo%[n]]*100
+;%assign foo%[n]		foo%[n]*100
+
+	foo1
+	foo2
+	foo3
+	foo11
+	foo22
+	foo33
+
+%define foo33bar	999999
+	%[foo%[foo3]bar]
+	
+%assign bctr 0
+%macro bluttan 0
+%assign bctr bctr+1
+%assign bluttan%[bctr]	bctr
+%defstr bstr bluttan%[bctr]
+	bluttan%[bctr]
+	bstr
+%endmacro
+
+%rep 20
+	bluttan
+%endrep
+%rep 20
+	bluttan%[bctr]
+%assign bctr bctr-1
+%endrep
diff --git a/test/pushseg.asm b/test/pushseg.asm
new file mode 100644
index 00000000..7bd7c955
--- /dev/null
+++ b/test/pushseg.asm
@@ -0,0 +1,17 @@
+;Testname=test; Arguments=-fbin -opushseg.bin; Files=stdout stderr pushseg.bin
+
+	bits 16
+
+	push cs
+	push ds
+	push es
+	push ss
+	push fs
+	push gs
+
+	pop gs
+	pop fs
+	pop ss
+	pop es
+	pop ds
+	pop cs		; 8086 only, does not disassemble
diff --git a/test/riprel2.asm b/test/riprel2.asm
new file mode 100644
index 00000000..2d13d3e4
--- /dev/null
+++ b/test/riprel2.asm
@@ -0,0 +1,11 @@
+;Testname=unoptimized; Arguments=-fbin -oriprel2.bin -O0; Files=stdout stderr riprel.bin
+;Testname=optimized;   Arguments=-fbin -oriprel2.bin -Ox; Files=stdout stderr riprel.bin
+
+	bits 64
+
+	default rel
+	mov dword [foo],12345678h
+	mov qword [foo],12345678h
+	mov [foo],rax
+	mov dword [foo],12345678h
+foo:
diff --git a/test/smartalign16.asm b/test/smartalign16.asm
new file mode 100644
index 00000000..42915de6
--- /dev/null
+++ b/test/smartalign16.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign16.bin; Files=stdout stderr smartalign16.bin
+
+%use smartalign
+
+	bits 16
+
+	alignmode nop, 32
+	add ax,ax
+	align 32
+
+	alignmode generic, 32
+	add ax,ax
+	align 32
+
+	alignmode k7, 32
+	add ax,ax
+	align 32
+
+	alignmode k8, 32
+	add ax,ax
+	align 32
+
+	alignmode p6, 32
+	add ax,ax
+	align 32
+
+	add ecx,ecx
+	align 32
+	add edx,edx
+	align 128
+	add ebx,ebx
+	align 256
+	add esi,esi
+	align 512
+
+	add edi,edi
diff --git a/test/smartalign32.asm b/test/smartalign32.asm
new file mode 100644
index 00000000..64d65b0b
--- /dev/null
+++ b/test/smartalign32.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign32.bin; Files=stdout stderr smartalign32.bin
+
+%use smartalign
+
+	bits 32
+
+	alignmode nop, 32
+	add ax,ax
+	align 32
+
+	alignmode generic, 32
+	add ax,ax
+	align 32
+
+	alignmode k7, 32
+	add ax,ax
+	align 32
+
+	alignmode k8, 32
+	add ax,ax
+	align 32
+
+	alignmode p6, 32
+	add ax,ax
+	align 32
+
+	add ecx,ecx
+	align 32
+	add edx,edx
+	align 128
+	add ebx,ebx
+	align 256
+	add esi,esi
+	align 512
+
+	add edi,edi
diff --git a/test/smartalign64.asm b/test/smartalign64.asm
new file mode 100644
index 00000000..74454ca8
--- /dev/null
+++ b/test/smartalign64.asm
@@ -0,0 +1,36 @@
+;Testname=test; Arguments=-fbin -osmartalign64.bin; Files=stdout stderr smartalign64.bin
+
+%use smartalign
+
+	bits 64
+
+	alignmode nop, 32
+	add ax,ax
+	align 32
+
+	alignmode generic, 32
+	add ax,ax
+	align 32
+
+	alignmode k7, 32
+	add ax,ax
+	align 32
+
+	alignmode k8, 32
+	add ax,ax
+	align 32
+
+	alignmode p6, 32
+	add ax,ax
+	align 32
+
+	add ecx,ecx
+	align 32
+	add edx,edx
+	align 128
+	add ebx,ebx
+	align 256
+	add esi,esi
+	align 512
+
+	add edi,edi
diff --git a/test/struc.asm b/test/struc.asm
new file mode 100644
index 00000000..3c8c1b47
--- /dev/null
+++ b/test/struc.asm
@@ -0,0 +1,33 @@
+;Testname=test; Arguments=-fbin -ostruc.bin; Files=stdout stderr struc.bin
+
+bits 32
+
+; Simple struc example
+struc teststruc1
+  .long: resd 1
+  .word: resw 1
+  .byte: resb 1
+  .str:  resb 32
+endstruc
+
+; Reference with offset
+mov [ebp - 40 + teststruc1.word], ax
+
+istruc teststruc1
+ at .word, db 5
+iend
+
+; Struc with base offset
+; should be the same as the previous stuc
+struc teststruc2, -40
+  .long: resd 1
+  .word: resw 1
+  .byte: resb 1
+  .str:  resb 32
+endstruc
+
+mov [ebp + teststruc2.word], ax
+
+istruc teststruc2
+ at .word, db 5
+iend
diff --git a/test/weirdpaste.asm b/test/weirdpaste.asm
new file mode 100644
index 00000000..46bfa90a
--- /dev/null
+++ b/test/weirdpaste.asm
@@ -0,0 +1,29 @@
+;Testname=preproc; Arguments=-E; Files=stdout stderr
+;Testname=bin; Arguments=-fbin -oweirdpaste.bin; Files=stdout stderr weirdpaste.bin
+
+	%define foo xyzzy
+%define bar 1e+10
+
+%define xyzzy1e 15
+
+%macro dx 2
+%assign	xx %1%2
+	dw xx
+%endmacro
+
+	dx foo, bar
+
+%macro df 2
+%assign xy __float32__(%1e+%2)
+	dd xy
+	dd %1e+%2
+%endmacro
+
+	df 1, 36
+	df 33, 20
+	df 0, 2
+	df 1.2, 5
+
+
+%define N 1e%++%+ 5
+	dd N, 1e+5
diff --git a/float.h b/ver.c
similarity index 81%
copy from float.h
copy to ver.c
index 6f94cc68..a7c4608e 100644
--- a/float.h
+++ b/ver.c
@@ -31,25 +31,21 @@
  *
  * ----------------------------------------------------------------------- */
 
-/* 
- * float.h   header file for the floating-point constant module of
- *	     the Netwide Assembler
- */
-
-#ifndef NASM_FLOAT_H
-#define NASM_FLOAT_H
-
 #include "nasm.h"
+#include "version.h"
 
-enum float_round {
-    FLOAT_RC_NEAR,
-    FLOAT_RC_ZERO,
-    FLOAT_RC_DOWN,
-    FLOAT_RC_UP,
-};
+/* This is printed when entering nasm -v */
+const char nasm_version[] = NASM_VER;
+const char nasm_date[] = __DATE__;
+const char nasm_compile_options[] = ""
+#ifdef DEBUG
+    " with -DDEBUG"
+#endif
+    ;
 
-int float_const(const char *string, int sign, uint8_t *result, int bytes,
-                efunc error);
-int float_option(const char *option);
+/* These are used by some backends. */
+const char nasm_comment[] =
+    "The Netwide Assembler " NASM_VER;
 
-#endif
+const char nasm_signature[] =
+    "NASM " NASM_VER;


More information about the Nasm-commits mailing list